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_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;
}
}
/** 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'];
$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 = "
SELECT
f.*,
@@ -86,10 +93,11 @@ function lista() {
LEFT JOIN dbo.paises p
ON f.pais_proveedor = p.id_pais
WHERE f.id_importador = ?
AND f.id_agencia = ?
AND f.status >= 1
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) {
die("Error en lista(): " . print_r(sqlsrv_errors(), true));
}
@@ -115,6 +123,13 @@ function crear()
$id_importador = $_SESSION['usuario_id'];
$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
$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]);
@@ -151,7 +166,22 @@ function guardar()
if (!($_SESSION['usuario_id'] ?? false)) {
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;
$num_factura = trim($_POST['numero_factura'] ?? '');
$fecha = $_POST['fecha_factura'] ?? null;
@@ -180,10 +210,9 @@ function guardar()
}
}
$conn = getConnection();
$params = [
$id_importador,
$id_agencia,
$aduana_seccion,
$aduana_seccion,
$num_factura,
@@ -201,12 +230,12 @@ function guardar()
];
$sql = "INSERT INTO dbo.solicitud_importacion_factura
(id_importador, aduana, anexo22_apendice, numero_factura, fecha_factura,
numero_pedimento, incoterm, pais_proveedor, tipo_moneda,
valor_factura, vinculacion, transportista_id, chofer_id,
foto_solicitud_url, status, proveedor_clave)
OUTPUT INSERTED.id_solicitud
VALUES(?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
(id_importador, id_agencia, aduana, anexo22_apendice, numero_factura, fecha_factura,
numero_pedimento, incoterm, pais_proveedor, tipo_moneda,
valor_factura, vinculacion, transportista_id, chofer_id,
foto_solicitud_url, status, proveedor_clave)
OUTPUT INSERTED.id_solicitud
VALUES(?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = sqlsrv_query($conn, $sql, $params, ['Scrollable' => SQLSRV_CURSOR_KEYSET]);
if ($stmt === false) {
@@ -435,19 +464,29 @@ function enviarNotificacionNuevaSolicitud($email, $nombreUsuario, $datosSolicitu
}
/** Formulario de edición de factura **/
function editar() {
function editar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login'); exit;
header('Location: /IMPORTADORES/login');
exit;
}
$id_solicitud = $_GET['id']??null;
if(!$id_solicitud || !is_numeric($id_solicitud)) {
die("❌ ID inválido.");
}
$id_importador = $_SESSION['usuario_id'];
$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) {
die(print_r(sqlsrv_errors(),true));
}
@@ -508,8 +547,8 @@ function editar() {
}
/** Procesa la actualización de una factura y sus partidas **/
function actualizar() {
session_start();
function actualizar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado.");
}
@@ -522,14 +561,21 @@ function actualizar() {
// 1) Conexión
$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
$fotoUrl = null;
$stmtFoto = sqlsrv_query(
$conn,
"SELECT foto_solicitud_url
FROM dbo.solicitud_importacion_factura
WHERE id_solicitud = ? AND id_importador = ?",
[ $id_solicitud, $_SESSION['usuario_id'] ]
WHERE id_solicitud = ? AND id_importador = ? AND id_agencia = ?",
[ $id_solicitud, $_SESSION['usuario_id'], $id_agencia ]
);
if ($stmtFoto !== false && ($row = sqlsrv_fetch_array($stmtFoto, SQLSRV_FETCH_ASSOC))) {
$fotoUrl = $row['foto_solicitud_url'];
@@ -549,17 +595,17 @@ function actualizar() {
}
// 4) Extraer campos del formulario
$aduana_seccion = $_POST['anexo22_apendice'] ?? null;
$num_factura = trim($_POST['numero_factura'] ?? '');
$fecha = $_POST['fecha_factura'] ?? null;
$incoterm = $_POST['incoterm'] ?? null;
$pais_proveedor = $_POST['pais_proveedor'] ?? null;
$tipo_moneda = $_POST['tipo_moneda'] ?? null;
$valor_factura = $_POST['valor_factura'] ?? null;
$vinculacion = $_POST['vinculacion'] ?? 0;
$aduana_seccion = $_POST['anexo22_apendice'] ?? null;
$num_factura = trim($_POST['numero_factura'] ?? '');
$fecha = $_POST['fecha_factura'] ?? null;
$incoterm = $_POST['incoterm'] ?? null;
$pais_proveedor = $_POST['pais_proveedor'] ?? null;
$tipo_moneda = $_POST['tipo_moneda'] ?? null;
$valor_factura = $_POST['valor_factura'] ?? null;
$vinculacion = $_POST['vinculacion'] ?? 0;
$transportista_id = (int)($_POST['transportista_id'] ?? 0);
$chofer_id = (int)($_POST['chofer_id'] ?? 0);
$status = isset($_POST['status']) ?? 1;
$chofer_id = (int)($_POST['chofer_id'] ?? 0);
$status = isset($_POST['status']) ?? 1;
// 5) Validar obligatorios
if (empty($num_factura) || empty($fecha) || $transportista_id <= 0 || $chofer_id <= 0) {
@@ -585,6 +631,7 @@ function actualizar() {
updated_at = GETDATE()
WHERE id_solicitud = ?
AND id_importador = ?
AND id_agencia = ?
";
$paramsU = [
$aduana_seccion,
@@ -601,7 +648,8 @@ function actualizar() {
$fotoUrl,
$status,
$id_solicitud,
$_SESSION['usuario_id']
$_SESSION['usuario_id'],
$id_agencia
];
$stmtU = sqlsrv_query($conn, $sqlU, $paramsU);
if ($stmtU === false) {
@@ -1553,6 +1601,9 @@ function pdf() {
$options = new Options();
$options->set('defaultFont', 'Arial');
$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->loadHtml($html);
@@ -1772,8 +1823,7 @@ function generarHTMLPDF($solicitud, $partidas, $configuracion, $proveedor_info =
/** Encabezado **/
.header { padding-bottom: 50px; }
.logo-section { width: 20%; text-align: left; }
.logo { max-width: 100px; height: auto; vertical-align: center; }
.siglas { font-size: 15px; }
.logo { max-width: 125px; height: auto; vertical-align: top; }
.company-info { width: 60%; text-align: center; vertical-align: top; font-size: 12px; }
.company-name { font-weight: bold; font-size: 25px; margin-bottom: 3px; }
.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>
<td class="logo-section">
<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 class="company-info">
<div class="company-name">' . htmlspecialchars($solicitud['importador_nombre']) . '</div>

View File

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

View File

@@ -46,6 +46,7 @@
<thead>
<tr>
<th>#</th>
<th>Agencia</th>
<th>Nombre</th>
<th>RFC</th>
<th>Teléfono</th>
@@ -59,12 +60,18 @@
<?php foreach ($vinculaciones as $v): ?>
<tr>
<td><?= htmlspecialchars($v['id_relacion'] ?? '') ?></td>
<td><?= htmlspecialchars($v['id_agencia'] ?? '') ?></td>
<td><?= htmlspecialchars(decrypt($v['nombre_agencia'] ?? '')) ?></td>
<td><?= htmlspecialchars($v['rfc_agencia'] ?? '') ?></td>
<td><?= htmlspecialchars($v['telefono'] ?? '') ?></td>
<td><?= htmlspecialchars($v['direccion'] ?? '') ?></td>
<td><?= !empty($v['fecha_vinculacion']) ? $v['fecha_vinculacion']->format('Y-m-d H:i') : '' ?></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>
</td>
</tr>
@@ -93,6 +100,10 @@
Swal.fire({ icon: 'success', title: 'Usuario desvinculado',
text: 'El usuario se ha desvinculado correctamente.',
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; ?>
</script>
<?php endif; ?>
@@ -103,6 +114,12 @@
Swal.fire({ icon: 'error', title: 'Desvinculación fallida', text: 'No se ha podido desvincular el usuario.', confirmButtonColor: '#dc3545' });
<?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' });
<?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; ?>
</script>
<?php endif; ?>