Filtro solicitudes por Agencia Aduanal

This commit is contained in:
2025-06-30 12:01:39 -06:00
parent 55be3d85c9
commit b0291a6685
5 changed files with 193 additions and 35 deletions

View File

@@ -203,3 +203,42 @@ CREATE INDEX [IX_agencias_activo] ON [dbo].[agencias_aduanales] ([activo]);
CREATE INDEX [IX_agencias_administrador] ON [dbo].[agencias_aduanales] ([id_administrador]); CREATE INDEX [IX_agencias_administrador] ON [dbo].[agencias_aduanales] ([id_administrador]);
CREATE INDEX [IX_solicitudes_estado] ON [dbo].[solicitudes_vinculacion] ([estado], [id_agencia]); CREATE INDEX [IX_solicitudes_estado] ON [dbo].[solicitudes_vinculacion] ([estado], [id_agencia]);
== MODIFICACIONES MULLTI-AGENCIA ==
ALTER TABLE usuarios_sistema
ADD id_agencia_en_uso INT NULL;
ALTER TABLE usuarios_sistema
ADD CONSTRAINT FK_usuario_agencia_uso
FOREIGN KEY (id_agencia_en_uso) REFERENCES agencias_aduanales(id_agencia);
-- 1. Modificar la tabla de solicitudes para incluir la relación con agencia
ALTER TABLE [dbo].[solicitud_importacion_factura]
ADD [id_agencia] [int] NULL;
-- Agregar foreign key para la agencia
ALTER TABLE [dbo].[solicitud_importacion_factura]
ADD CONSTRAINT [FK_solicitud_agencia]
FOREIGN KEY ([id_agencia]) REFERENCES [dbo].[agencias_aduanales]([id_agencia]);
-- 2. Crear índices para mejorar el rendimiento
CREATE INDEX [IX_solicitud_importador_agencia]
ON [dbo].[solicitud_importacion_factura] ([id_importador], [id_agencia]);
CREATE INDEX [IX_solicitud_agencia_status]
ON [dbo].[solicitud_importacion_factura] ([id_agencia], [status]);
-- 3. Agregar campos adicionales a la tabla expediente_archivos existente para mejor control
ALTER TABLE [dbo].[expediente_archivos]
ADD [estado_archivo] [varchar](20) NULL DEFAULT 'ACTIVO', -- ACTIVO, INACTIVO, ELIMINADO
[subido_por] [int] NULL, -- ID del usuario que subió el archivo
[observaciones] [nvarchar](500) NULL,
[fecha_modificacion] [datetime] NULL;
-- Agregar foreign key para el usuario que subió el archivo
ALTER TABLE [dbo].[expediente_archivos]
ADD CONSTRAINT [FK_expediente_archivos_usuario]
FOREIGN KEY ([subido_por]) REFERENCES [dbo].[usuarios_sistema]([id_usuario]);

View File

@@ -204,3 +204,55 @@ function desvincularUsuario()
exit; exit;
} }
} }
/** Función para cambiar la agencia activa del usuario **/
function cambiarAgenciaActiva()
{
if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'importador') {
header('Location: /IMPORTADORES/login');
exit;
}
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
header("Location: /IMPORTADORES/vinculaciones/vinculacionesusuario?error=invalid_id");
exit;
}
$id_agencia = intval($_GET['id']);
$id_usuario = $_SESSION['usuario_id'];
$conn = getConnection();
// Validar que el importador está vinculado a esta agencia
$sqlVerificacion = "
SELECT 1
FROM importador_agencia
WHERE id_importador = ? AND id_agencia = ? AND activo = 1
";
$stmtVerificacion = sqlsrv_query($conn, $sqlVerificacion, [$id_usuario, $id_agencia]);
if ($stmtVerificacion === false || !sqlsrv_fetch($stmtVerificacion)) {
header("Location: /IMPORTADORES/vinculaciones/vinculacionesusuario?error=invalid_agency");
exit;
}
// Actualizar campo id_agencia_en_uso
$sqlUpdate = "
UPDATE usuarios_sistema
SET id_agencia_en_uso = ?
WHERE id_usuario = ?
";
$stmtUpdate = sqlsrv_query($conn, $sqlUpdate, [$id_agencia, $id_usuario]);
if ($stmtUpdate === false) {
header("Location: /IMPORTADORES/vinculaciones/vinculacionesusuario?error=agency_changed_failed");
exit;
}
// Opcional: actualizar también la sesión si lo usas en tu lógica
$_SESSION['id_agencia_en_uso'] = $id_agencia;
// Redirigir con éxito
header("Location: /IMPORTADORES/vinculaciones/vinculacionesusuario?success=agency_changed");
exit;
}

View File

@@ -71,6 +71,13 @@ function lista() {
$id_importador = $_SESSION['usuario_id']; $id_importador = $_SESSION['usuario_id'];
$conn = getConnection(); $conn = getConnection();
// ✅ NUEVO: Obtener la agencia actual del usuario
$stmt = sqlsrv_query($conn, "SELECT id_agencia_en_uso FROM dbo.usuarios_sistema WHERE id_usuario = ?", [$id_importador]);
$id_agencia = null;
if ($stmt && $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$id_agencia = $row['id_agencia_en_uso'];
}
$sql = " $sql = "
SELECT SELECT
f.*, f.*,
@@ -86,10 +93,11 @@ function lista() {
LEFT JOIN dbo.paises p LEFT JOIN dbo.paises p
ON f.pais_proveedor = p.id_pais ON f.pais_proveedor = p.id_pais
WHERE f.id_importador = ? WHERE f.id_importador = ?
AND f.id_agencia = ?
AND f.status >= 1 AND f.status >= 1
ORDER BY f.created_at DESC ORDER BY f.created_at DESC
"; ";
$stmt = sqlsrv_query($conn, $sql, [$id_importador]); $stmt = sqlsrv_query($conn, $sql, [$id_importador, $id_agencia]);
if ($stmt === false) { if ($stmt === false) {
die("Error en lista(): " . print_r(sqlsrv_errors(), true)); die("Error en lista(): " . print_r(sqlsrv_errors(), true));
} }
@@ -115,6 +123,13 @@ function crear()
$id_importador = $_SESSION['usuario_id']; $id_importador = $_SESSION['usuario_id'];
$conn = getConnection(); $conn = getConnection();
// ✅ NUEVO: Obtener la agencia actual del usuario
$stmt = sqlsrv_query($conn, "SELECT id_agencia_en_uso FROM dbo.usuarios_sistema WHERE id_usuario = ?", [$id_importador]);
$id_agencia = null;
if ($stmt && $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$id_agencia = $row['id_agencia_en_uso'];
}
// Carga de datos para selects // Carga de datos para selects
$transportistas = []; $transportistas = [];
$stmtT = sqlsrv_query($conn, "SELECT id_transportista, clave_identificador, nombre FROM dbo.transportistas WHERE id_usuario=? AND activo=1 ORDER BY nombre",[$id_importador]); $stmtT = sqlsrv_query($conn, "SELECT id_transportista, clave_identificador, nombre FROM dbo.transportistas WHERE id_usuario=? AND activo=1 ORDER BY nombre",[$id_importador]);
@@ -151,7 +166,22 @@ function guardar()
if (!($_SESSION['usuario_id'] ?? false)) { if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado."); die("⚠️ No autorizado.");
} }
$id_importador = $_SESSION['usuario_id']; $id_importador = $_SESSION['usuario_id'];
$conn = getConnection();
// ✅ Obtener id_agencia_en_uso del usuario
$stmtAgencia = sqlsrv_query($conn, "SELECT id_agencia_en_uso FROM dbo.usuarios_sistema WHERE id_usuario = ?", [$id_importador]);
$id_agencia = null;
if ($stmtAgencia && $row = sqlsrv_fetch_array($stmtAgencia, SQLSRV_FETCH_ASSOC)) {
$id_agencia = $row['id_agencia_en_uso'];
}
if (!$id_agencia) {
die("❌ No se pudo determinar la agencia en uso para guardar la solicitud.");
}
// Obtener y validar campos del formulario
$aduana_seccion = $_POST['anexo22_apendice'] ?? null; $aduana_seccion = $_POST['anexo22_apendice'] ?? null;
$num_factura = trim($_POST['numero_factura'] ?? ''); $num_factura = trim($_POST['numero_factura'] ?? '');
$fecha = $_POST['fecha_factura'] ?? null; $fecha = $_POST['fecha_factura'] ?? null;
@@ -180,10 +210,9 @@ function guardar()
} }
} }
$conn = getConnection();
$params = [ $params = [
$id_importador, $id_importador,
$id_agencia,
$aduana_seccion, $aduana_seccion,
$aduana_seccion, $aduana_seccion,
$num_factura, $num_factura,
@@ -201,12 +230,12 @@ function guardar()
]; ];
$sql = "INSERT INTO dbo.solicitud_importacion_factura $sql = "INSERT INTO dbo.solicitud_importacion_factura
(id_importador, aduana, anexo22_apendice, numero_factura, fecha_factura, (id_importador, id_agencia, aduana, anexo22_apendice, numero_factura, fecha_factura,
numero_pedimento, incoterm, pais_proveedor, tipo_moneda, numero_pedimento, incoterm, pais_proveedor, tipo_moneda,
valor_factura, vinculacion, transportista_id, chofer_id, valor_factura, vinculacion, transportista_id, chofer_id,
foto_solicitud_url, status, proveedor_clave) foto_solicitud_url, status, proveedor_clave)
OUTPUT INSERTED.id_solicitud OUTPUT INSERTED.id_solicitud
VALUES(?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; VALUES(?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = sqlsrv_query($conn, $sql, $params, ['Scrollable' => SQLSRV_CURSOR_KEYSET]); $stmt = sqlsrv_query($conn, $sql, $params, ['Scrollable' => SQLSRV_CURSOR_KEYSET]);
if ($stmt === false) { if ($stmt === false) {
@@ -435,19 +464,29 @@ function enviarNotificacionNuevaSolicitud($email, $nombreUsuario, $datosSolicitu
} }
/** Formulario de edición de factura **/ /** Formulario de edición de factura **/
function editar() { function editar()
{
if (!($_SESSION['usuario_id'] ?? false)) { if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login'); exit; header('Location: /IMPORTADORES/login');
exit;
} }
$id_solicitud = $_GET['id']??null; $id_solicitud = $_GET['id']??null;
if(!$id_solicitud || !is_numeric($id_solicitud)) { if(!$id_solicitud || !is_numeric($id_solicitud)) {
die("❌ ID inválido."); die("❌ ID inválido.");
} }
$id_importador = $_SESSION['usuario_id']; $id_importador = $_SESSION['usuario_id'];
$conn = getConnection(); $conn = getConnection();
$stmt = sqlsrv_query($conn,"SELECT * FROM dbo.solicitud_importacion_factura WHERE id_solicitud=? AND id_importador=?",[(int)$id_solicitud,$id_importador]); // ✅ Obtener id_agencia_en_uso del usuario
$stmtAgencia = sqlsrv_query($conn, "SELECT id_agencia_en_uso FROM dbo.usuarios_sistema WHERE id_usuario = ?", [$id_importador]);
$id_agencia = null;
if ($stmtAgencia && $row = sqlsrv_fetch_array($stmtAgencia, SQLSRV_FETCH_ASSOC)) {
$id_agencia = $row['id_agencia_en_uso'];
}
$stmt = sqlsrv_query($conn,"SELECT * FROM dbo.solicitud_importacion_factura WHERE id_solicitud=? AND id_importador=? AND id_agencia=?", [(int)$id_solicitud, $id_importador, $id_agencia]);
if($stmt === false) { if($stmt === false) {
die(print_r(sqlsrv_errors(),true)); die(print_r(sqlsrv_errors(),true));
} }
@@ -508,8 +547,8 @@ function editar() {
} }
/** Procesa la actualización de una factura y sus partidas **/ /** Procesa la actualización de una factura y sus partidas **/
function actualizar() { function actualizar()
session_start(); {
if (!($_SESSION['usuario_id'] ?? false)) { if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado."); die("⚠️ No autorizado.");
} }
@@ -522,14 +561,21 @@ function actualizar() {
// 1) Conexión // 1) Conexión
$conn = getConnection(); $conn = getConnection();
// ✅ NUEVO: Obtener la agencia actual del usuario
$stmt = sqlsrv_query($conn, "SELECT id_agencia_en_uso FROM dbo.usuarios_sistema WHERE id_usuario = ?", [$id_importador]);
$id_agencia = null;
if ($stmt && $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$id_agencia = $row['id_agencia_en_uso'];
}
// 2) Obtener URL de foto actual desde BD para conservar si no suben nueva // 2) Obtener URL de foto actual desde BD para conservar si no suben nueva
$fotoUrl = null; $fotoUrl = null;
$stmtFoto = sqlsrv_query( $stmtFoto = sqlsrv_query(
$conn, $conn,
"SELECT foto_solicitud_url "SELECT foto_solicitud_url
FROM dbo.solicitud_importacion_factura FROM dbo.solicitud_importacion_factura
WHERE id_solicitud = ? AND id_importador = ?", WHERE id_solicitud = ? AND id_importador = ? AND id_agencia = ?",
[ $id_solicitud, $_SESSION['usuario_id'] ] [ $id_solicitud, $_SESSION['usuario_id'], $id_agencia ]
); );
if ($stmtFoto !== false && ($row = sqlsrv_fetch_array($stmtFoto, SQLSRV_FETCH_ASSOC))) { if ($stmtFoto !== false && ($row = sqlsrv_fetch_array($stmtFoto, SQLSRV_FETCH_ASSOC))) {
$fotoUrl = $row['foto_solicitud_url']; $fotoUrl = $row['foto_solicitud_url'];
@@ -585,6 +631,7 @@ function actualizar() {
updated_at = GETDATE() updated_at = GETDATE()
WHERE id_solicitud = ? WHERE id_solicitud = ?
AND id_importador = ? AND id_importador = ?
AND id_agencia = ?
"; ";
$paramsU = [ $paramsU = [
$aduana_seccion, $aduana_seccion,
@@ -601,7 +648,8 @@ function actualizar() {
$fotoUrl, $fotoUrl,
$status, $status,
$id_solicitud, $id_solicitud,
$_SESSION['usuario_id'] $_SESSION['usuario_id'],
$id_agencia
]; ];
$stmtU = sqlsrv_query($conn, $sqlU, $paramsU); $stmtU = sqlsrv_query($conn, $sqlU, $paramsU);
if ($stmtU === false) { if ($stmtU === false) {
@@ -1553,6 +1601,9 @@ function pdf() {
$options = new Options(); $options = new Options();
$options->set('defaultFont', 'Arial'); $options->set('defaultFont', 'Arial');
$options->set('isRemoteEnabled', true); // Permite cargar imágenes remotas si es necesario $options->set('isRemoteEnabled', true); // Permite cargar imágenes remotas si es necesario
$options->set('isHtml5ParserEnabled', true); // Habilita el parser HTML5
$options->set('isPhpEnabled', true); // Habilita PHP dentro del HTML si es necesario
$options->set('chroot', $_SERVER['DOCUMENT_ROOT']); // Asegura que las rutas relativas funcionen correctamente
$dompdf = new Dompdf($options); $dompdf = new Dompdf($options);
$dompdf->loadHtml($html); $dompdf->loadHtml($html);
@@ -1772,8 +1823,7 @@ function generarHTMLPDF($solicitud, $partidas, $configuracion, $proveedor_info =
/** Encabezado **/ /** Encabezado **/
.header { padding-bottom: 50px; } .header { padding-bottom: 50px; }
.logo-section { width: 20%; text-align: left; } .logo-section { width: 20%; text-align: left; }
.logo { max-width: 100px; height: auto; vertical-align: center; } .logo { max-width: 125px; height: auto; vertical-align: top; }
.siglas { font-size: 15px; }
.company-info { width: 60%; text-align: center; vertical-align: top; font-size: 12px; } .company-info { width: 60%; text-align: center; vertical-align: top; font-size: 12px; }
.company-name { font-weight: bold; font-size: 25px; margin-bottom: 3px; } .company-name { font-weight: bold; font-size: 25px; margin-bottom: 3px; }
.invoice-info { width: 20%; text-align: right; vertical-align: top; font-size: 12px; } .invoice-info { width: 20%; text-align: right; vertical-align: top; font-size: 12px; }
@@ -1811,7 +1861,6 @@ function generarHTMLPDF($solicitud, $partidas, $configuracion, $proveedor_info =
<tr> <tr>
<td class="logo-section"> <td class="logo-section">
<img src="' . htmlspecialchars($configuracion['logo_url'] ?? 'assets/img/logo_siih.png') . '" alt="Logo" class="logo"><br> <img src="' . htmlspecialchars($configuracion['logo_url'] ?? 'assets/img/logo_siih.png') . '" alt="Logo" class="logo"><br>
<div class="siglas"><strong>' . htmlspecialchars($configuracion['siglas'] ?? 'SIIH') . '</strong></div>
</td> </td>
<td class="company-info"> <td class="company-info">
<div class="company-name">' . htmlspecialchars($solicitud['importador_nombre']) . '</div> <div class="company-name">' . htmlspecialchars($solicitud['importador_nombre']) . '</div>

View File

@@ -21,8 +21,10 @@ function vinculacionesUsuario()
$sql = " $sql = "
SELECT * SELECT *
FROM importador_agencia ia FROM importador_agencia ia
INNER JOIN agencias_aduanales aa ON ia.id_agencia = aa.id_agencia INNER JOIN agencias_aduanales aa
WHERE ia.id_importador = ? AND ia.activo = 1 ON ia.id_agencia = aa.id_agencia
WHERE ia.id_importador = ?
AND ia.activo = 1
ORDER BY ia.fecha_vinculacion DESC ORDER BY ia.fecha_vinculacion DESC
"; ";
$stmt = sqlsrv_query($conn, $sql, [$_SESSION['usuario_id']]); $stmt = sqlsrv_query($conn, $sql, [$_SESSION['usuario_id']]);
@@ -37,7 +39,6 @@ function vinculacionesUsuario()
include __DIR__ . '/../../views/vinculaciones/vinculaciones_importador.php'; include __DIR__ . '/../../views/vinculaciones/vinculaciones_importador.php';
} }
function nuevaVinculacion() function nuevaVinculacion()
{ {
if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'importador') { if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'importador') {

View File

@@ -46,6 +46,7 @@
<thead> <thead>
<tr> <tr>
<th>#</th> <th>#</th>
<th>Agencia</th>
<th>Nombre</th> <th>Nombre</th>
<th>RFC</th> <th>RFC</th>
<th>Teléfono</th> <th>Teléfono</th>
@@ -59,12 +60,18 @@
<?php foreach ($vinculaciones as $v): ?> <?php foreach ($vinculaciones as $v): ?>
<tr> <tr>
<td><?= htmlspecialchars($v['id_relacion'] ?? '') ?></td> <td><?= htmlspecialchars($v['id_relacion'] ?? '') ?></td>
<td><?= htmlspecialchars($v['id_agencia'] ?? '') ?></td>
<td><?= htmlspecialchars(decrypt($v['nombre_agencia'] ?? '')) ?></td> <td><?= htmlspecialchars(decrypt($v['nombre_agencia'] ?? '')) ?></td>
<td><?= htmlspecialchars($v['rfc_agencia'] ?? '') ?></td> <td><?= htmlspecialchars($v['rfc_agencia'] ?? '') ?></td>
<td><?= htmlspecialchars($v['telefono'] ?? '') ?></td> <td><?= htmlspecialchars($v['telefono'] ?? '') ?></td>
<td><?= htmlspecialchars($v['direccion'] ?? '') ?></td> <td><?= htmlspecialchars($v['direccion'] ?? '') ?></td>
<td><?= !empty($v['fecha_vinculacion']) ? $v['fecha_vinculacion']->format('Y-m-d H:i') : '' ?></td> <td><?= !empty($v['fecha_vinculacion']) ? $v['fecha_vinculacion']->format('Y-m-d H:i') : '' ?></td>
<td> <td>
<?php if ($v['id_agencia'] == ($_SESSION['id_agencia_en_uso'] ?? null)): ?>
<span class="badge bg-secondary">En uso</span>
<?php else: ?>
<a href="/IMPORTADORES/importadores/cambiarAgenciaActiva?id=<?= $v['id_agencia'] ?>" class="btn btn-sm btn-success">Usar Agencia</a>
<?php endif; ?>
<a href="/IMPORTADORES/importadores/desvincularUsuario?id=<?= $v['id_relacion'] ?>" class="btn btn-sm btn-danger">Desvincular</a> <a href="/IMPORTADORES/importadores/desvincularUsuario?id=<?= $v['id_relacion'] ?>" class="btn btn-sm btn-danger">Desvincular</a>
</td> </td>
</tr> </tr>
@@ -93,6 +100,10 @@
Swal.fire({ icon: 'success', title: 'Usuario desvinculado', Swal.fire({ icon: 'success', title: 'Usuario desvinculado',
text: 'El usuario se ha desvinculado correctamente.', text: 'El usuario se ha desvinculado correctamente.',
confirmButtonColor: '#198754' }); confirmButtonColor: '#198754' });
<?php elseif ($_GET['success'] === 'agency_changed'): ?>
Swal.fire({ icon: 'success', title: 'Agencia cambiada',
text: 'La agencia activa se ha cambiado correctamente.',
confirmButtonColor: '#198754' });
<?php endif; ?> <?php endif; ?>
</script> </script>
<?php endif; ?> <?php endif; ?>
@@ -103,6 +114,12 @@
Swal.fire({ icon: 'error', title: 'Desvinculación fallida', text: 'No se ha podido desvincular el usuario.', confirmButtonColor: '#dc3545' }); Swal.fire({ icon: 'error', title: 'Desvinculación fallida', text: 'No se ha podido desvincular el usuario.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'invalid_id'): ?> <?php elseif ($_GET['error'] === 'invalid_id'): ?>
Swal.fire({ icon: 'error', title: 'ID inválido', text: 'El identificador de la relación no es válido.', confirmButtonColor: '#dc3545' }); Swal.fire({ icon: 'error', title: 'ID inválido', text: 'El identificador de la relación no es válido.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'invalid_agency'): ?>
Swal.fire({ icon: 'error', title: 'Agencia inválida', text: 'El ID de agencia proporcionado no es válido.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'fetch_failed'): ?>
Swal.fire({ icon: 'error', title: 'Error al cargar agencias', text: 'No se han podido cargar las agencias.', confirmButtonColor: '#dc3545' });
<?php elseif ($_GET['error'] === 'agency_change_failed'): ?>
Swal.fire({ icon: 'error', title: 'Error al cambiar agencia', text: 'No se ha podido cambiar la agencia activa.', confirmButtonColor: '#dc3545' });
<?php endif; ?> <?php endif; ?>
</script> </script>
<?php endif; ?> <?php endif; ?>