Files
MVE/views/transportistas/alta.php
2025-07-03 11:58:49 -06:00

273 lines
12 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php include __DIR__ . '/../partials/sidebar_importador.php'; ?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title> Alta de Transportista</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<!-- SweetAlert2 -->
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<style>
body { font-family: 'Segoe UI', sans-serif; background-color: #f4f6f9; }
.sidebar { width: 220px; height: 100vh; background-color: #343a40; position: fixed; top: 0; left: 0; padding-top: 56px; z-index: 1040; }
.sidebar .nav-link { font-weight: bold; color: white; transition: all 0.3s ease; }
.sidebar .nav-link:hover,
.sidebar .nav-link.active { background-color: #495057; color: #fff; }
.content { margin-top: 56px; padding: 40px 20px; position: relative; z-index: 1; background-color: #f4f6f9; transition: margin-left 0.3s ease; }
.navbar { position: fixed; top: 0; width: 100%; z-index: 1050; }
@media (min-width: 768px) { .content { margin-left: 250px; } }
@media (max-width: 767.98px) { .content { margin-left: 0; } }
.card { border-radius: 12px; }
</style>
</head>
<body>
<div class="content">
<h4 class="mb-4"> Alta de Transportista</h4>
<form action="/IMPORTADORES/transportistas/guardar" method="POST" class="card p-4 shadow-sm" id="formAltaTransportista">
<!-- Hidden para persona moral -->
<input type="hidden" name="es_persona_moral" id="es_persona_moral" value="0">
<!-- Switch Persona Moral -->
<div class="row mb-3">
<div class="col-md-4 d-flex align-items-end">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="personaMoralSwitch">
<label class="form-check-label" for="personaMoralSwitch">Es Persona Moral</label>
</div>
</div>
</div>
<div class="row g-3">
<div class="col-md-4">
<label for="clave" class="form-label">Clave *</label>
<input name="clave" id="clave" class="form-control" maxlength="8" required>
</div>
<div class="col-md-4">
<label for="nombre" class="form-label" id="labelNombre">Nombre *</label>
<input name="nombre" id="nombre" class="form-control" required>
</div>
<div class="col-md-4">
<label for="rfc" class="form-label">RFC *</label>
<input name="rfc" id="rfc" class="form-control" maxlength="13" required>
</div>
<div class="col-md-4">
<label for="curp" class="form-label">CURP *</label>
<input name="curp" id="curp" class="form-control" maxlength="18">
</div>
<div class="col-md-4">
<label for="telefono" class="form-label">Teléfono *</label>
<input name="telefono" id="telefono" class="form-control" maxlength="11" required>
</div>
<div class="col-md-4">
<label for="caat" class="form-label">Código caat *</label>
<input name="caat" id="caat" class="form-control" maxlength="20" required>
</div>
<div class="col-md-4">
<label for="pais" class="form-label">País *</label>
<select id="pais" name="pais" class="form-select" required>
<option value="">Selecciona país</option>
<?php foreach($paises as $p): ?>
<option value="<?= $p['id_pais'] ?>"><?= htmlspecialchars($p['nombre']) ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-4">
<label for="entidad" class="form-label">Entidad *</label>
<select id="entidad" name="entidad" class="form-select" required disabled>
<option value="">Primero país…</option>
</select>
</div>
<div class="col-md-4">
<label for="ciudad" class="form-label">Ciudad *</label>
<select id="ciudad" name="ciudad" class="form-select" required disabled>
<option value="">Primero estado…</option>
</select>
</div>
<div class="col-md-8">
<label for="domicilio" class="form-label">Domicilio *</label>
<input name="domicilio" id="domicilio" class="form-control" maxlength="100" required>
</div>
</div>
<div class="text-end mt-4">
<button class="btn btn-success px-4">Guardar Transportista</button>
<a href="/IMPORTADORES/transportistas/lista" class="btn btn-secondary ms-2">Cancelar</a>
</div>
</form>
</div>
<script>
document.getElementById('formAltaTransportista').addEventListener('submit', function(e) {
e.preventDefault();
const rfcInput = document.getElementById('rfc');
const curpInput = document.getElementById('curp');
const telefonoInput = document.getElementById('telefono');
const rfc = rfcInput.value.trim().toUpperCase();
const curp = curpInput.value.trim();
const telefono = telefonoInput.value.trim();
const clave = document.getElementById('clave').value.trim();
const nombre = document.getElementById('nombre').value.trim();
const caat = document.getElementById('caat').value.trim();
const pais = document.getElementById('pais').value;
const entidad = document.getElementById('entidad').value;
const ciudad = document.getElementById('ciudad').value;
const domicilio = document.getElementById('domicilio').value.trim();
const curpRegex = /^[A-Z]{4}[0-9]{6}[HM](AS|BC|BS|CC|CL|CM|CS|CH|DF|DG|GT|GR|HG|JC|MC|MN|MS|NT|NL|OC|PL|QT|QR|SP|SL|SR|TC|TS|TL|VZ|YN|ZS)[A-Z]{3}[A-Z0-9]{2}$/;
const rfcRegex = /^[A-ZÑ&]{3,4}\d{6}[A-Z0-9]{3}$/;
const telefonoRegex = /^\d{3}\s\d{7}$/;
if (!clave) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'La clave es obligatoria.', confirmButtonColor: '#dc3545'});
document.getElementById('clave').focus();
return;
}
if (clave.length>8) {
Swal.fire({ icon: 'error', title: 'Clave inválida', text: 'La clave no puede tener más de 8 caracteres.', confirmButtonColor: '#dc3545'});
document.getElementById('clave').focus();
return;
}
if (!nombre) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El nombre es obligatorio.', confirmButtonColor: '#dc3545'});
document.getElementById('nombre').focus();
return;
}
if (!rfc) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El RFC es obligatorio.', confirmButtonColor: '#dc3545'});
document.getElementById('rfc').focus();
return;
}
if (!rfcRegex.test(rfc)) {
Swal.fire({ icon: 'error', title: 'RFC inválido', text: 'El RFC debe tener 12 o 13 caracteres con el formato correcto (ej. ABC123456XYZ).', confirmButtonColor: '#dc3545'});
document.getElementById('rfc').focus();
return;
}
if (curp && !curpRegex.test(curp)) {
Swal.fire({ icon: 'error', title: 'CURP inválido', text: 'El CURP no tiene el formato correcto.', confirmButtonColor: '#dc3545'});
document.getElementById('curp').focus();
return;
}
if (!telefono) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El teléfono es obligatorio.', confirmButtonColor: '#dc3545'});
document.getElementById('telefono').focus();
return;
}
if (!telefonoRegex.test(telefono)) {
Swal.fire({ icon: 'error', title: 'Teléfono inválido', text: 'Debe tener 10 dígitos en el formato: 3 dígitos (LADA), espacio, y 7 dígitos (ej. 123 4567890).', onfirmButtonColor:'#dc3545'});
document.getElementById('telefono').focus();
return;
}
if (telefono.length>11) {
Swal.fire({ icon: 'error', title: 'Teléfono inválido', text: 'El teléfono no puede tener más de 11 caracteres.', confirmButtonColor: '#dc3545'});
document.getElementById('telefono').focus();
return;
}
if (!caat) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El código caat es obligatorio.', confirmButtonColor: '#dc3545'});
document.getElementById('caat').focus();
return;
}
if (!pais) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'Debe seleccionar un país.', confirmButtonColor: '#dc3545'});
document.getElementById('pais').focus();
return;
}
if (!entidad) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'Debe seleccionar un estado.', confirmButtonColor: '#dc3545'});
document.getElementById('entidad').focus();
return;
}
if (!ciudad) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'Debe seleccionar una ciudad.', confirmButtonColor: '#dc3545'});
document.getElementById('ciudad').focus();
return;
}
if (!domicilio) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El domicilio es obligatorio.', confirmButtonColor: '#dc3545'});
document.getElementById('domicilio').focus();
return;
}
document.getElementById('rfc').value = rfc;
document.getElementById('curp').value = curp;
this.submit();
});
document.getElementById('pais').addEventListener('change', e => {
const pid = e.target.value;
const estadoSelect = document.getElementById('entidad');
const ciudadSelect = document.getElementById('ciudad');
estadoSelect.innerHTML = '<option value="">Cargando…</option>';
estadoSelect.disabled = true;
ciudadSelect.innerHTML = '<option value="">Primero estado…</option>';
ciudadSelect.disabled = true;
if (!pid) { estadoSelect.innerHTML = '<option value="">Primero país…</option>'; return; }
fetch(`/IMPORTADORES/transportistas/estados?pais=${pid}`)
.then(r => { if (!r.ok) throw new Error('Error al cargar estados'); return r.json(); })
.then(list => {
estadoSelect.innerHTML = '<option value="">Selecciona estado</option>';
list.forEach(st => estadoSelect.add(new Option(st.nombre, st.id_estado)));
estadoSelect.disabled = false;
})
.catch(() => {
estadoSelect.innerHTML = '<option value="">Error al cargar</option>';
Swal.fire({ icon:'error',title:'Error',text:'No se pudieron cargar los estados',confirmButtonColor:'#dc3545'});
});
});
document.getElementById('entidad').addEventListener('change', e => {
const eid = e.target.value;
const ciudadSelect = document.getElementById('ciudad');
ciudadSelect.innerHTML = '<option value="">Cargando…</option>';
ciudadSelect.disabled = true;
if (!eid) { ciudadSelect.innerHTML = '<option value="">Primero estado…</option>'; return; }
fetch(`/IMPORTADORES/transportistas/ciudades?estado=${eid}`)
.then(r => { if (!r.ok) throw new Error('Error al cargar ciudades'); return r.json(); })
.then(list => {
ciudadSelect.innerHTML = '<option value="">Selecciona ciudad</option>';
list.forEach(ct => ciudadSelect.add(new Option(ct.nombre, ct.id_ciudad)));
ciudadSelect.disabled = false;
})
.catch(() => {
ciudadSelect.innerHTML = '<option value="">Error al cargar</option>';
Swal.fire({ icon:'error',title:'Error',text:'No se pudieron cargar las ciudades',confirmButtonColor:'#dc3545'});
});
});
// Switch Persona Moral
document.getElementById('personaMoralSwitch').addEventListener('change', function() {
const checked = this.checked;
const label = document.getElementById('labelNombre');
const curp = document.getElementById('curp');
const hidden = document.getElementById('es_persona_moral');
if (checked) {
label.textContent = 'Razón Social *';
curp.value = '';
curp.disabled = true;
curp.removeAttribute('required');
hidden.value = '1';
} else {
label.textContent = 'Nombre *';
curp.disabled = false;
curp.setAttribute('required', 'required');
hidden.value = '0';
}
});
</script>
</body>
</html>