Vinculaciones multi-agencia

This commit is contained in:
2025-06-25 12:38:50 -06:00
parent a830e3a84a
commit c5c698dbe4
62 changed files with 5107 additions and 1454 deletions

View File

@@ -42,6 +42,12 @@ $color2 = explode(',', $config['colores_primarios'] ?? '#003366,#0055A5')
footer { background-color: #e9ecef; padding: 20px; text-align: center; font-size: 14px; color: #666; }
.recaptcha { margin-top: 20px; }
.logo-siih { height: 90px; margin-right: 10px; }
.form-toggle { margin-bottom: 2rem; text-align: center; }
.form-toggle .btn { margin: 0 0.5rem; min-width: 150px; }
.form-container { display: none; }
.form-container.active { display: block; }
.form-title { text-align: center; margin-bottom: 2rem; color: #333; }
.transition-fade { transition: opacity 0.3s ease-in-out; }
</style>
</head>
<body>
@@ -72,44 +78,109 @@ $color2 = explode(',', $config['colores_primarios'] ?? '#003366,#0055A5')
</div>
</nav>
<!-- Contenedor del formulario -->
<div class="container card-form">
<form action="/IMPORTADORES/registro/enviar" method="POST" enctype="multipart/form-data" id="formRegistro">
<div class="row g-3">
<div class="col-md-6">
<label for="company_name" class="form-label">Nombre de la empresa *</label>
<input type="text" class="form-control" name="company_name" required>
</div>
<div class="col-md-6">
<label for="rfc" class="form-label">RFC *</label>
<input type="text" class="form-control" name="rfc" maxlength="13" required>
</div>
<div class="col-md-6">
<label for="email" class="form-label">Correo electrónico *</label>
<input type="email" class="form-control" name="email" required>
</div>
<div class="col-md-6">
<label for="phone" class="form-label">Teléfono *</label>
<input type="text" class="form-control" name="phone" required>
</div>
<div class="col-md-12">
<label for="opinion_file" class="form-label">Padrón de importadores o encargo conferido (PDF) *</label>
<input type="file" class="form-control" name="opinion_file" id="opinion_file" accept=".pdf" required>
</div>
<div class="col-md-12 text-center recaptcha">
<div class="g-recaptcha" data-sitekey="6LfkMB8rAAAAAH-BEC1cMYij1HEhw4sTaEOl-UCA"></div>
</div>
<div class="col-md-12 text-end mt-4">
<button type="submit" class="btn btn-primary px-4 py-2">Enviar solicitud</button>
</div>
<!-- Contenedor de formularios -->
<div class="container">
<div class="card-form">
<!-- Botón para alternar entre formularios -->
<div class="form-toggle">
<button type="button" class="btn btn-white" id="btnToggle" onclick="alternarFormulario()">🔄 Registro de Agencia Aduanal</button>
</div>
</form>
<!-- Formulario de Importador -->
<div id="formImportadorContainer" class="form-container active transition-fade">
<h3 class="form-title">Registro de Importador</h3>
<form action="/IMPORTADORES/registro/enviarSoliImportador" method="POST" enctype="multipart/form-data" id="formRegistro">
<div class="row g-3">
<div class="col-md-6">
<label for="company_name" class="form-label">Nombre de la empresa *</label>
<input type="text" class="form-control" name="company_name" id="company_name" required>
</div>
<div class="col-md-6">
<label for="rfc" class="form-label">RFC *</label>
<input type="text" class="form-control" name="rfc" maxlength="13" id="rfc" required>
</div>
<div class="col-md-6">
<label for="email" class="form-label">Correo electrónico *</label>
<input type="email" class="form-control" name="email" id="email" required>
</div>
<div class="col-md-6">
<label for="phone" class="form-label">Teléfono *</label>
<input type="text" class="form-control" name="phone" id="phone" required>
</div>
<div class="col-md-12">
<label for="opinion_file" class="form-label">Padrón de importadores o encargo conferido (PDF) *</label>
<input type="file" class="form-control" name="opinion_file" id="opinion_file" accept=".pdf" required>
</div>
<div class="col-md-12 text-center recaptcha">
<div class="g-recaptcha" data-sitekey="6LfkMB8rAAAAAH-BEC1cMYij1HEhw4sTaEOl-UCA"></div>
</div>
<div class="col-md-12 text-end mt-4">
<button type="submit" class="btn btn-primary px-4 py-2">Enviar solicitud</button>
</div>
</div>
</form>
</div>
<!-- Formulario de Agencia Aduanal -->
<div id="formAgenciaContainer" class="form-container transition-fade">
<h3 class="form-title">Registro de Agencia Aduanal</h3>
<form action="/IMPORTADORES/registro/enviarSoliAgencia" method="POST" enctype="multipart/form-data" id="formRegistroAgencia">
<div class="row g-3">
<div class="col-md-6">
<label for="nombre_agencia" class="form-label">Nombre de la agencia *</label>
<input type="text" class="form-control" name="nombre_agencia" id="nombre_agencia" required>
</div>
<div class="col-md-6">
<label for="rfc_agencia" class="form-label">RFC *</label>
<input type="text" class="form-control" name="rfc_agencia" maxlength="13" id="rfc_agencia" required>
</div>
<div class="col-md-6">
<label for="correo" class="form-label">Correo electrónico *</label>
<input type="email" class="form-control" name="correo" id="correo" required>
</div>
<div class="col-md-6">
<label for="telefono" class="form-label">Teléfono *</label>
<input type="text" class="form-control" name="telefono" maxlength="11" id="telefono" required>
</div>
<div class="col-md-12">
<label for="direccion" class="form-label">Dirección *</label>
<input type="text" class="form-control" name="direccion" id="direccion"
placeholder="Ej: Calle, num.externo, num.interno, colonia, municipio, código postal, estado" required>
</div>
<div class="col-md-12">
<label for="opinion_file" class="form-label">Padrón de importadores o encargo conferido (PDF) *</label>
<input type="file" class="form-control" name="opinion_file" id="opinion_file" accept=".pdf" required>
</div><hr>
<p><strong>Administrador de la Agencia</strong></p>
<div class="col-md-6">
<label for="nombre_admin" class="form-label">Nombre *</label>
<input type="text" class="form-control" name="nombre_admin" id="nombre_admin" required>
</div>
<div class="col-md-6">
<label for="correo_admin" class="form-label">Correo Administrador *</label>
<input type="email" class="form-control" name="correo_admin" id="correo_admin" required>
</div>
<div class="col-md-12 text-center recaptcha">
<div class="g-recaptcha" data-sitekey="6LfkMB8rAAAAAH-BEC1cMYij1HEhw4sTaEOl-UCA"></div>
</div>
<div class="col-md-12 text-end mt-4">
<button type="submit" class="btn btn-primary px-4 py-2">Enviar solicitud</button>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="container ">
@@ -126,59 +197,214 @@ $color2 = explode(',', $config['colores_primarios'] ?? '#003366,#0055A5')
<!-- Validación JS -->
<script>
let formularioActual = 'importador';
function alternarFormulario() {
const formImportador = document.getElementById('formImportadorContainer');
const formAgencia = document.getElementById('formAgenciaContainer');
const btnToggle = document.getElementById('btnToggle');
if (formularioActual === 'importador') {
// Cambiar a formulario de agencia
formImportador.classList.remove('active');
formAgencia.classList.add('active');
btnToggle.textContent = '🔄 Registro de Importador';
btnToggle.classList.remove('btn-white');
btnToggle.classList.add('btn-white');
formularioActual = 'agencia';
} else {
// Cambiar a formulario de importador
formAgencia.classList.remove('active');
formImportador.classList.add('active');
btnToggle.textContent = '🔄 Registro de Agencia Aduanal';
btnToggle.classList.remove('btn-white');
btnToggle.classList.add('btn-white');
formularioActual = 'importador';
}
// Resetear reCAPTCHA si está disponible
if (typeof grecaptcha !== 'undefined') {
grecaptcha.reset();
}
}
// Inicializar al cargar la página
document.addEventListener('DOMContentLoaded', function() {
// Por defecto mostrar el formulario de importador
const formImportador = document.getElementById('formImportadorContainer');
formImportador.classList.add('active');
});
// Registro de Importador
document.getElementById('formRegistro').addEventListener('submit', function(e) {
const rfcInput = document.querySelector('input[name="rfc"]');
const emailInput = document.querySelector('input[name="email"]');
const phoneInput = document.querySelector('input[name="phone"]');
const archivo = document.getElementById('opinion_file').files[0];
e.preventDefault();
const nombre = document.getElementById('company_name').value.trim();
const rfc = document.getElementById('rfc').value.trim().toUpperCase();
const email = document.getElementById('email').value.trim();
const phone = document.getElementById('phone').value.trim();
const archivo = document.getElementById('opinion_file').files[0];
const recaptcha = grecaptcha.getResponse();
const rfc = rfcInput.value.trim().toUpperCase();
const email = emailInput.value.trim();
const phone = phoneInput.value.trim();
// Expresiones regulares
const emailRegex = /^[a-zA-Z0-9._+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
const rfcRegex = /^[A-ZÑ&]{3,4}\d{6}[A-Z0-9]{3}$/;
const phoneRegex = /^\d{3}\s\d{7}$/;
// Validación de nombre
if (!nombre) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El nombre es obligatorio.', confirmButtonColor: '#dc3545' });
document.getElementById('company_name').focus();
return;
}
// Validación de correo
if (!email) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El correo es obligatorio.', confirmButtonColor: '#dc3545' });
document.getElementById('email').focus();
return;
}
if (!emailRegex.test(email)) {
Swal.fire({ icon: 'error', title: 'Correo inválido', text: 'No es una dirección de correo válida.', confirmButtonColor: '#dc3545' });
document.getElementById('email').focus();
return;
}
// Validación de RFC
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;
}
// Validación de teléfono
if (!phone) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El teléfono es obligatorio.', confirmButtonColor: '#dc3545' });
document.getElementById('phone').focus();
return;
}
if (!phoneRegex.test(phone)) {
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. Ejemplo: 123 4567890', confirmButtonColor: '#dc3545' });
document.getElementById('phone').focus();
return;
}
// Validación de archivo PDF
if (!archivo) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El padrón de importadores es obligatorio.', confirmButtonColor: '#dc3545' });
document.getElementById('direccion').focus();
return;
}
if (!archivo || archivo.type !== 'application/pdf') {
Swal.fire({ icon: 'error', title: 'Formato de documento inválido', text: 'Solo se permite subir archivos PDF.', confirmButtonColor: '#dc3545' });
return; }
// Validación de reCAPTCHA
if (recaptcha.length === 0) {
Swal.fire({ icon: 'warning', title: 'Verificación requerida', text: 'Por favor completa el reCAPTCHA.', confirmButtonColor: '#dc3545' });
return;
}
// Si todas las validaciones pasan, el formulario se envía.
this.submit();
});
// Registro de Agencia
document.getElementById('formRegistroAgencia').addEventListener('submit', function(e) {
e.preventDefault();
const nombre = document.getElementById('nombre_agencia').value.trim();
const rfc_agencia = document.getElementById('rfc_agencia').value.trim().toUpperCase();
const correo = document.getElementById('correo').value.trim();
const telefono = document.getElementById('telefono').value.trim();
const direccion = document.getElementById('direccion').value.trim();
const archivo = document.getElementById('opinion_file').files[0];
const nombre_admin = document.getElementById('nombre_admin').value.trim();
const correo_admin = document.getElementById('correo_admin').value.trim();
const recaptcha = grecaptcha.getResponse();
// Expresiones regulares
const correoRegex = /^[a-z0-9._+-]+@[a-z0-9.-]+\.[a-z]{2,}$/;
const rfcRegex = /^[A-ZÑ&]{3,4}\d{6}[A-Z0-9]{3}$/;
const correoRegex = /^[a-zA-Z0-9._+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
const rfcRegex = /^[A-ZÑ&]{3,4}\d{6}[A-Z0-9]{3}$/;
const telefonoRegex = /^\d{3}\s\d{7}$/;
// Validación de nombre
if (!nombre) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El nombre es obligatorio.', confirmButtonColor: '#dc3545' });
document.getElementById('nombre_agencia').focus();
return;
}
// Validación de correo
if (!correoRegex.test(email)) {
e.preventDefault();
Swal.fire("Correo inválido", "No es una dirección de correo válida. Solo se permiten minúsculas.", "error");
emailInput.focus();
if (!correo) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El correo es obligatorio.', confirmButtonColor: '#dc3545' });
document.getElementById('correo').focus();
return;
}
if (!correoRegex.test(correo)) {
Swal.fire({ icon: 'error', title: 'Correo inválido', text: 'No es una dirección de correo válida.', confirmButtonColor: '#dc3545' });
document.getElementById('correo').focus();
return;
}
// Validación de RFC
if (!rfcRegex.test(rfc)) {
e.preventDefault();
Swal.fire("RFC inválido", "El RFC debe tener 12 o 13 caracteres con el formato correcto (ej. ABC123456XYZ).", "error");
rfcInput.focus();
if (!rfc_agencia) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El RFC es obligatorio.', confirmButtonColor: '#dc3545' });
document.getElementById('rfc_agencia').focus();
return;
}
if (!rfcRegex.test(rfc_agencia)) {
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_agencia').focus();
return;
}
// Validación de teléfono
if (!telefonoRegex.test(phone)) {
e.preventDefault();
Swal.fire("Teléfono inválido", "Debe tener 10 dígitos en el formato: 3 dígitos (LADA), espacio, y 7 dígitos. Ejemplo: 123 4567890", "error");
phoneInput.focus();
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).', confirmButtonColor: '#dc3545' });
document.getElementById('telefono').focus();
return;
}
// Validación de dirección
if (!direccion) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'La dirección es obligatoria.', confirmButtonColor: '#dc3545' });
document.getElementById('direccion').focus();
return;
}
// Validación de archivo PDF
if (!archivo || archivo.type !== 'application/pdf') {
e.preventDefault();
Swal.fire("Error", "Solo se permite subir archivos PDF.", "error");
if (!archivo) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El padrón de importadores es obligatorio.', confirmButtonColor: '#dc3545' });
document.getElementById('direccion').focus();
return;
}
if (!archivo || archivo.type !== 'application/pdf') {
Swal.fire({ icon: 'error', title: 'Formato de documento inválido', text: 'Solo se permite subir archivos PDF.', confirmButtonColor: '#dc3545' });
return; }
// Validación de administrador
if (!nombre_admin) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El nombre del administrador es obligatorio.', confirmButtonColor: '#dc3545' });
document.getElementById('nombre_admin').focus();
return;
}
// Validación de correo de administrador
if (!correo_admin) {
Swal.fire({ icon: 'warning', title: 'Campo requerido', text: 'El correo de administrador es obligatorio.', confirmButtonColor: '#dc3545' });
document.getElementById('correo_admin').focus();
return;
}
if (!correoRegex.test(correo_admin)) {
Swal.fire({ icon: 'error', title: 'Correo inválido', text: 'No es una dirección de correo válida.', confirmButtonColor: '#dc3545' });
document.getElementById('correo_admin').focus();
return;
}
// Validación de reCAPTCHA
if (recaptcha.length === 0) {
e.preventDefault();
Swal.fire("Verificación requerida", "Por favor completa el reCAPTCHA.", "warning");
return;
if (recaptcha.length === 0) {
Swal.fire({ icon: 'warning', title: 'Verificación requerida', text: 'Por favor completa el reCAPTCHA.', confirmButtonColor: '#dc3545' });
return;
}
// Si todas las validaciones pasan, el formulario se envía.
this.submit();
});
</script>