diff --git a/app/controllers/administrador.php b/app/controllers/administrador.php index 7514e22..c3cc461 100644 --- a/app/controllers/administrador.php +++ b/app/controllers/administrador.php @@ -525,7 +525,7 @@ function aprobar_agencia() $sqlGetAgenciaId = "SELECT SCOPE_IDENTITY() AS id_agencia"; $stmtGetAgenciaId = sqlsrv_query($conn, $sqlGetAgenciaId); $agenciaIdRow = sqlsrv_fetch_array($stmtGetAgenciaId, SQLSRV_FETCH_ASSOC); - $id_agencia = $idUsuarioRow['id_agencia'] ?? null; + $id_agencia = $agenciaIdRow['id_agencia'] ?? null; if (!$id_agencia) { die("❌ No se pudo obtener el ID de la agencia recién creada."); @@ -535,9 +535,7 @@ function aprobar_agencia() $sqlInsert2 = "INSERT INTO usuarios_sistema (nombre, email, password_hash, tipo_usuario, activo, creado_en, dos_factores, creado_por) VALUES (?, ?, ?, ?, 1, GETDATE(), 0, ?) "; - $stmtInsert2 = sqlsrv_query($conn, $sqlInsert, [ - $admin_name_encrypt, $admin_email_encrypt, $password_hash, $tipo, $usuario_id - ]); + $stmtInsert2 = sqlsrv_query($conn, $sqlInsert, [$admin_name_encrypt, $admin_email_encrypt, $password_hash, $tipo, $usuario_id]); if (!$stmtInsert2) { die("❌ Error al crear usuario administrador: " . print_r(sqlsrv_errors(), true)); @@ -576,7 +574,8 @@ function aprobar_agencia() SET request_status = 'approved', approval_date = GETDATE(), approved_by = ? - WHERE request_id = ?"; + WHERE request_id = ? + "; $stmtUpdate = sqlsrv_query($conn, $sqlUpdate, [$usuario_id, $id]); if (!$stmtUpdate) { diff --git a/app/controllers/agencias.php b/app/controllers/agencias.php index 6c3729a..e22b456 100644 --- a/app/controllers/agencias.php +++ b/app/controllers/agencias.php @@ -1,6 +1,5 @@ false, 'message' => 'No autorizado']); exit; } - $gafete = trim($_GET['numero_gafete'] ?? ''); + $gafete = trim($_GET['numero_gafete'] ?? ''); $id_chofer = $_GET['id_chofer'] ?? null; if ($gafete === '') { @@ -235,11 +257,11 @@ function validarNumeroGafete() { if ($id_chofer) { // Edición: excluir el chofer actual - $sql = "SELECT id_chofer FROM dbo.choferes WHERE numero_gafete = ? AND id_chofer <> ? AND status = 1"; + $sql = "SELECT id_chofer FROM dbo.choferes WHERE numero_gafete = ? AND id_chofer <> ? AND status = 1"; $stmt = sqlsrv_query($conn, $sql, [$gafete, $id_chofer]); } else { // Alta nueva - $sql = "SELECT id_chofer FROM dbo.choferes WHERE numero_gafete = ? AND status = 1"; + $sql = "SELECT id_chofer FROM dbo.choferes WHERE numero_gafete = ? AND status = 1"; $stmt = sqlsrv_query($conn, $sql, [$gafete]); } @@ -252,21 +274,22 @@ function validarNumeroGafete() { } /** Procesa la actualización de un chofer **/ -function actualizar() { +function actualizar() +{ if (!($_SESSION['usuario_id'] ?? false)) { die("⚠️ No autorizado."); } - $id = $_POST['id_chofer'] ?? null; - $transportista_id = $_POST['transportista_id'] ?? null; - $nombre = trim($_POST['nombre'] ?? ''); - $apellido = trim($_POST['apellido'] ?? ''); - $licencia = trim($_POST['numero_licencia']?? ''); - $gafete = trim($_POST['numero_gafete']?? ''); - $telefono = trim($_POST['telefono'] ?? ''); - $email = trim($_POST['email'] ?? ''); - $fecha_ingreso = $_POST['fecha_ingreso'] ?: null; - $status = isset($_POST['status']) ? 1 : 0; + $id = $_POST['id_chofer'] ?? null; + $transportista_id = $_POST['transportista_id'] ?? null; + $nombre = trim($_POST['nombre'] ?? ''); + $apellido = trim($_POST['apellido'] ?? ''); + $licencia = trim($_POST['numero_licencia'] ?? ''); + $gafete = trim($_POST['numero_gafete'] ?? ''); + $telefono = trim($_POST['telefono'] ?? ''); + $email = trim($_POST['email'] ?? ''); + $fecha_ingreso = $_POST['fecha_ingreso'] ?: null; + $status = isset($_POST['status']) ? 1 : 0; // Validación básica if ( @@ -281,7 +304,8 @@ function actualizar() { // ✅ CRÍTICO: Verificar que el número de gafete no existe (excluyendo el chofer actual) $sqlCheckGafete = "SELECT id_chofer FROM dbo.choferes WHERE numero_gafete = ? AND id_chofer <> ? AND status = 1"; - $stmtCheck = sqlsrv_query($conn, $sqlCheckGafete, [$gafete, $id_chofer]); + $stmtCheck = sqlsrv_query($conn, $sqlCheckGafete, [$gafete, $id_chofer]); + if ($stmtCheck && sqlsrv_fetch($stmtCheck)) { die("❌ El número de gafete '{$gafete}' ya está en uso. Por favor, use otro número."); } @@ -290,7 +314,7 @@ function actualizar() { $fotoUrl = null; if (!empty($_FILES['foto']['tmp_name']) && $_FILES['foto']['error'] === UPLOAD_ERR_OK) { $allowedTypes = ['jpg', 'jpeg', 'png', 'gif']; - $ext = strtolower(pathinfo($_FILES['foto']['name'], PATHINFO_EXTENSION)); + $ext = strtolower(pathinfo($_FILES['foto']['name'], PATHINFO_EXTENSION)); if (!in_array($ext, $allowedTypes)) { die("❌ Tipo de archivo no permitido. Solo JPG, PNG, GIF."); @@ -314,64 +338,62 @@ function actualizar() { } if ($fotoUrl) { - $sql = " - UPDATE dbo.choferes SET - transportista_id = ?, - nombre = ?, - apellido = ?, - numero_licencia = ?, - numero_gafete = ?, - telefono = ?, - email = ?, - fecha_ingreso = ?, - foto_url = ?, - status = ?, - updated_at = GETDATE() - WHERE id_chofer = ? - "; + $sql = "UPDATE dbo.choferes SET + transportista_id = ?, + nombre = ?, + apellido = ?, + numero_licencia = ?, + numero_gafete = ?, + telefono = ?, + email = ?, + fecha_ingreso = ?, + foto_url = ?, + status = ?, + updated_at = GETDATE() + WHERE id_chofer = ? + "; $params = [ - (int)$transportista_id, - $nombre, - $apellido, - $licencia, - $gafete, - $telefono, - $email, - $fecha_ingreso, - $fotoUrl, - $status, - (int)$id - ]; + (int)$transportista_id, + $nombre, + $apellido, + $licencia, + $gafete, + $telefono, + $email, + $fecha_ingreso, + $fotoUrl, + $status, + (int)$id + ]; } else { - $sql = " - UPDATE dbo.choferes SET - transportista_id = ?, - nombre = ?, - apellido = ?, - numero_licencia = ?, - numero_gafete = ?, - telefono = ?, - email = ?, - fecha_ingreso = ?, - status = ?, - updated_at = GETDATE() - WHERE id_chofer = ? - "; + $sql = "UPDATE dbo.choferes SET + transportista_id = ?, + nombre = ?, + apellido = ?, + numero_licencia = ?, + numero_gafete = ?, + telefono = ?, + email = ?, + fecha_ingreso = ?, + status = ?, + updated_at = GETDATE() + WHERE id_chofer = ? + "; $params = [ - (int)$transportista_id, - $nombre, - $apellido, - $licencia, - $gafete, - $telefono, - $email, - $fecha_ingreso, - $status, - (int)$id - ]; + (int)$transportista_id, + $nombre, + $apellido, + $licencia, + $gafete, + $telefono, + $email, + $fecha_ingreso, + $status, + (int)$id + ]; } - $stmt = sqlsrv_query($conn, $sql, $params); + if ($stmt === false) { $errors = sqlsrv_errors(); // ✅ Manejo específico de error de duplicado @@ -388,25 +410,28 @@ function actualizar() { } /** “Soft-delete” (status = 0) de un chofer **/ -function eliminar() { +function eliminar() +{ if (!($_SESSION['usuario_id'] ?? false)) { header('Location: /IMPORTADORES/login'); exit; } $id = $_GET['id'] ?? null; + if (!$id || !is_numeric($id)) { die("❌ ID inválido."); } $conn = getConnection(); - $sql = " - UPDATE dbo.choferes - SET status = 0, - updated_at = GETDATE() - WHERE id_chofer = ? - "; + + $sql = "UPDATE dbo.choferes + SET status = 0, + updated_at = GETDATE() + WHERE id_chofer = ? + "; $stmt = sqlsrv_query($conn, $sql, [(int)$id]); + if ($stmt === false) { die("❌ Error en eliminar(): " . print_r(sqlsrv_errors(), true)); } diff --git a/app/controllers/configuracion.php b/app/controllers/configuracion.php index e79022c..ae7c96f 100644 --- a/app/controllers/configuracion.php +++ b/app/controllers/configuracion.php @@ -6,6 +6,7 @@ require_once __DIR__ . '/../helpers/crypto.php'; function index() { $conn = getConnection(); + $id_usuario = $_SESSION['usuario_id'] ?? null; if (!$id_usuario) { @@ -35,7 +36,7 @@ function index() // Dependiendo del tipo de usuario, obtenemos información adicional switch (trim($usuario['tipo_usuario'])) { // Agregué trim() por si hay espacios case 'importador': - $sql_importador = "SELECT * FROM informacion_general WHERE id_usuario = ?"; + $sql_importador = "SELECT * FROM informacion_general WHERE id_usuario = ?"; $stmt_importador = sqlsrv_query($conn, $sql_importador, [$id_usuario]); if ($stmt_importador !== false) { @@ -48,15 +49,17 @@ function index() case 'admin_agencia': case 'agente_aduanal': - $sql_agencia = " - SELECT aa.id_agencia, aa.nombre_agencia, aa.rfc_agencia, - aa.direccion AS direccion_agencia, aa.telefono AS telefono_agencia, - aa.email AS email_agencia, aga.fecha_asignacion - FROM agente_agencia aga - INNER JOIN agencias_aduanales aa ON aga.id_agencia = aa.id_agencia - WHERE aga.id_agente = ? AND aga.activo = 1 AND aa.activo = 1 - "; - + $sql_agencia = "SELECT + aa.id_agencia, aa.nombre_agencia, aa.rfc_agencia, + aa.direccion AS direccion_agencia, aa.telefono AS telefono_agencia, + aa.email AS email_agencia, aga.fecha_asignacion + FROM agente_agencia aga + INNER JOIN agencias_aduanales aa + ON aga.id_agencia = aa.id_agencia + WHERE aga.id_agente = ? + AND aga.activo = 1 + AND aa.activo = 1 + "; $stmt_agencia = sqlsrv_query($conn, $sql_agencia, [$id_usuario]); if ($stmt_agencia !== false) { @@ -88,7 +91,8 @@ function index() function editar() { - $conn = getConnection(); + $conn = getConnection(); + $id_usuario = $_SESSION['usuario_id'] ?? null; if (!$id_usuario) { @@ -96,9 +100,9 @@ function editar() } // Traer los datos existentes del usuario - $sql = "SELECT * FROM informacion_general WHERE id_usuario = ?"; + $sql = "SELECT * FROM informacion_general WHERE id_usuario = ?"; $params = [$id_usuario]; - $stmt = sqlsrv_query($conn, $sql, $params); + $stmt = sqlsrv_query($conn, $sql, $params); if ($stmt === false) { die(print_r(sqlsrv_errors(), true)); @@ -112,6 +116,7 @@ function editar() function guardar() { $conn = getConnection(); + $id_usuario = $_SESSION['usuario_id'] ?? null; if (!$id_usuario) { @@ -125,7 +130,7 @@ function guardar() ]; $sql_parts = []; - $params = []; + $params = []; foreach ($campos as $campo) { if (isset($_POST[$campo]) && $_POST[$campo] !== '') { @@ -144,10 +149,10 @@ function guardar() try { // 1. Actualiza la tabla informacion_general - $sql = "UPDATE informacion_general SET " . implode(", ", $sql_parts) . " WHERE id_usuario = ?"; + $sql = "UPDATE informacion_general SET " . implode(", ", $sql_parts) . " WHERE id_usuario = ?"; $params[] = $id_usuario; + $stmt = sqlsrv_query($conn, $sql, $params); - $stmt = sqlsrv_query($conn, $sql, $params); if ($stmt === false) { throw new Exception(print_r(sqlsrv_errors(), true)); } @@ -157,9 +162,9 @@ function guardar() $telefono = $_POST['telefono']; // Primero obtenemos el nombre de la empresa de informacion_general - $sql_get_name = "SELECT nombre FROM informacion_general WHERE id_usuario = ?"; + $sql_get_name = "SELECT nombre FROM informacion_general WHERE id_usuario = ?"; $params_get_name = [$id_usuario]; - $stmt_get_name = sqlsrv_query($conn, $sql_get_name, $params_get_name); + $stmt_get_name = sqlsrv_query($conn, $sql_get_name, $params_get_name); if ($stmt_get_name === false) { throw new Exception("Error al obtener nombre de empresa: " . print_r(sqlsrv_errors(), true)); @@ -174,10 +179,9 @@ function guardar() $nombre_encriptado = encrypt($nombre_empresa); // Actualizar solicitudes_importadores usando el company_name encriptado - $sql_solicitud = "UPDATE solicitudes_importadores SET phone = ? WHERE company_name = ?"; + $sql_solicitud = "UPDATE solicitudes_importadores SET phone = ? WHERE company_name = ?"; $params_solicitud = [$telefono, $nombre_encriptado]; - - $stmt_solicitud = sqlsrv_query($conn, $sql_solicitud, $params_solicitud); + $stmt_solicitud = sqlsrv_query($conn, $sql_solicitud, $params_solicitud); if ($stmt_solicitud === false) { throw new Exception("Error al actualizar teléfono en solicitudes: " . print_r(sqlsrv_errors(), true)); @@ -190,16 +194,15 @@ function guardar() error_log("No se encontró registro en solicitudes_importadores para actualizar teléfono. Empresa: " . $nombre_empresa); // Opcional: Buscar por RFC como fallback - $sql_rfc = "SELECT rfc FROM informacion_general WHERE id_usuario = ?"; + $sql_rfc = "SELECT rfc FROM informacion_general WHERE id_usuario = ?"; $stmt_rfc = sqlsrv_query($conn, $sql_rfc, [$id_usuario]); if ($stmt_rfc) { $rfc_data = sqlsrv_fetch_array($stmt_rfc, SQLSRV_FETCH_ASSOC); if ($rfc_data && !empty($rfc_data['rfc'])) { - $sql_solicitud_rfc = "UPDATE solicitudes_importadores SET phone = ? WHERE rfc = ?"; + $sql_solicitud_rfc = "UPDATE solicitudes_importadores SET phone = ? WHERE rfc = ?"; $params_solicitud_rfc = [$telefono, $rfc_data['rfc']]; - - $stmt_solicitud_rfc = sqlsrv_query($conn, $sql_solicitud_rfc, $params_solicitud_rfc); + $stmt_solicitud_rfc = sqlsrv_query($conn, $sql_solicitud_rfc, $params_solicitud_rfc); if ($stmt_solicitud_rfc === false) { error_log("Error al actualizar por RFC: " . print_r(sqlsrv_errors(), true)); diff --git a/app/controllers/expediente.php b/app/controllers/expediente.php index 4ec0398..ae1ab0d 100644 --- a/app/controllers/expediente.php +++ b/app/controllers/expediente.php @@ -4,33 +4,33 @@ require_once __DIR__ . '/../../config/database.php'; require_once __DIR__ . '/../helpers/env.php'; // Mostrar tabla de expedientes -function index() { +function index() +{ if (!isset($_SESSION['usuario_id'])) { header('Location: /IMPORTADORES/login'); exit; } + $conn = getConnection(); + $id_importador = $_SESSION['usuario_id']; - $sql = " - SELECT - sif.id_solicitud, - sif.numero_pedimento, - sif.fecha_factura, - sif.aduana, - sif.proveedor_clave, - COUNT(ea.id) AS total_archivos, - ISNULL(SUM(ea.tamano_archivo), 0) AS total_tamano - FROM solicitud_importacion_factura sif - LEFT JOIN expediente_archivos ea ON ea.id_solicitud = sif.id_solicitud - WHERE sif.numero_pedimento IS NOT NULL AND sif.id_importador = ? and sif.status > 0 - GROUP BY sif.id_solicitud, sif.numero_pedimento, sif.fecha_factura, sif.aduana, sif.proveedor_clave - ORDER BY sif.fecha_factura DESC - "; - + $sql = "SELECT + sif.id_solicitud, sif.numero_pedimento, sif.fecha_factura, sif.aduana, sif.proveedor_clave, + COUNT(ea.id) AS total_archivos, + ISNULL(SUM(ea.tamano_archivo), 0) AS total_tamano + FROM solicitud_importacion_factura sif + LEFT JOIN expediente_archivos ea + ON ea.id_solicitud = sif.id_solicitud + WHERE sif.numero_pedimento IS NOT NULL + AND sif.id_importador = ? + AND sif.status > 0 + GROUP BY sif.id_solicitud, sif.numero_pedimento, sif.fecha_factura, sif.aduana, sif.proveedor_clave + ORDER BY sif.fecha_factura DESC + "; $stmt = sqlsrv_query($conn, $sql, [$id_importador]); - $expedientes = []; + $expedientes = []; if ($stmt) { while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { $expedientes[] = $row; @@ -40,17 +40,20 @@ function index() { include __DIR__ . '/../../views/expediente/index.php'; } -function subir($id_solicitud) { +function subir($id_solicitud) +{ include __DIR__ . '/../../views/expediente/subir.php'; } -function subir_handler() { +function subir_handler() +{ if (!isset($_POST['id_solicitud']) || !isset($_FILES['archivos']) || !isset($_SESSION['usuario_id'])) { die("❌ Solicitud inválida."); } $conn = getConnection(); - $id_solicitud = (int) $_POST['id_solicitud']; + + $id_solicitud = (int) $_POST['id_solicitud']; $id_importador = $_SESSION['usuario_id']; // Validar propiedad de la solicitud @@ -60,7 +63,7 @@ function subir_handler() { } $archivos = $_FILES['archivos']; - $usuario = $_SESSION['usuario_nombre'] ?? 'sistema'; + $usuario = $_SESSION['usuario_nombre'] ?? 'sistema'; $uploadDir = __DIR__ . '/../../uploads/expedientes/' . $id_solicitud; if (!is_dir($uploadDir)) { @@ -71,18 +74,19 @@ function subir_handler() { if ($archivos['error'][$i] !== 0) continue; $nombreOriginal = basename($archivos['name'][$i]); - $nombreSeguro = uniqid() . '_' . preg_replace('/[^A-Za-z0-9._-]/', '_', $nombreOriginal); - $rutaFinal = $uploadDir . '/' . $nombreSeguro; + $nombreSeguro = uniqid() . '_' . preg_replace('/[^A-Za-z0-9._-]/', '_', $nombreOriginal); + $rutaFinal = $uploadDir . '/' . $nombreSeguro; move_uploaded_file($archivos['tmp_name'][$i], $rutaFinal); - $rutaDb = "uploads/expedientes/$id_solicitud/$nombreSeguro"; - $tamanoKb = round(filesize($rutaFinal) / 1024, 2); + $rutaDb = "uploads/expedientes/$id_solicitud/$nombreSeguro"; + $tamanoKb = round(filesize($rutaFinal) / 1024, 2); $tipoArchivo = mime_content_type($rutaFinal); - $sql = "INSERT INTO expediente_archivos (id_solicitud, nombre_archivo, ruta_archivo, tipo_archivo, tamano_archivo, creado_por) - VALUES (?, ?, ?, ?, ?, ?)"; - + $sql = "INSERT INTO expediente_archivos + (id_solicitud, nombre_archivo, ruta_archivo, tipo_archivo, tamano_archivo, creado_por) + VALUES (?, ?, ?, ?, ?, ?) + "; $params = [$id_solicitud, $nombreOriginal, $rutaDb, $tipoArchivo, $tamanoKb, $usuario]; sqlsrv_query($conn, $sql, $params); } @@ -99,12 +103,13 @@ function ver($id_solicitud) } $conn = getConnection(); - $id_importador = $_SESSION['usuario_id']; - $archivos = []; - $sql = "SELECT * FROM expediente_archivos WHERE id_solicitud = ? AND id_solicitud IN (SELECT id_solicitud FROM solicitud_importacion_factura WHERE id_importador = ?) ORDER BY creado_en DESC"; + $id_importador = $_SESSION['usuario_id']; + + $sql = "SELECT * FROM expediente_archivos WHERE id_solicitud = ? AND id_solicitud IN (SELECT id_solicitud FROM solicitud_importacion_factura WHERE id_importador = ?) ORDER BY creado_en DESC"; $stmt = sqlsrv_query($conn, $sql, [$id_solicitud, $id_importador]); + $archivos = []; if ($stmt) { while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { if (is_string($row['creado_en'])) { @@ -117,15 +122,17 @@ function ver($id_solicitud) include __DIR__ . '/../../views/expediente/ver.php'; } -function ver_archivo($id_archivo) { +function ver_archivo($id_archivo) +{ if (!isset($_SESSION['usuario_id'])) { header('Location: /IMPORTADORES/login'); exit; } $conn = getConnection(); - $sql = "SELECT ea.*, sif.id_importador FROM expediente_archivos ea JOIN solicitud_importacion_factura sif ON sif.id_solicitud = ea.id_solicitud WHERE ea.id = ?"; - $stmt = sqlsrv_query($conn, $sql, [$id_archivo]); + + $sql = "SELECT ea.*, sif.id_importador FROM expediente_archivos ea JOIN solicitud_importacion_factura sif ON sif.id_solicitud = ea.id_solicitud WHERE ea.id = ?"; + $stmt = sqlsrv_query($conn, $sql, [$id_archivo]); $archivo = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); if (!$archivo || $archivo['id_importador'] != $_SESSION['usuario_id']) { @@ -141,7 +148,7 @@ function ver_archivo($id_archivo) { exit; } - $tipo = $archivo['tipo_archivo'] ?? mime_content_type($ruta); + $tipo = $archivo['tipo_archivo'] ?? mime_content_type($ruta); $nombre = $archivo['nombre_archivo']; header('Content-Type: ' . $tipo); @@ -160,16 +167,19 @@ function descargar_zip($id_solicitud) } $conn = getConnection(); + $id_importador = $_SESSION['usuario_id']; - $sql = " - SELECT ea.nombre_archivo, ea.ruta_archivo - FROM expediente_archivos ea - JOIN solicitud_importacion_factura sif ON sif.id_solicitud = ea.id_solicitud - WHERE ea.id_solicitud = ? AND sif.id_importador = ? - "; - + $sql = "SELECT + ea.nombre_archivo, ea.ruta_archivo + FROM expediente_archivos ea + JOIN solicitud_importacion_factura sif + ON sif.id_solicitud = ea.id_solicitud + WHERE ea.id_solicitud = ? + AND sif.id_importador = ? + "; $stmt = sqlsrv_query($conn, $sql, [$id_solicitud, $id_importador]); + if (!$stmt) { http_response_code(500); echo "Error al consultar archivos."; @@ -181,7 +191,7 @@ function descargar_zip($id_solicitud) $ruta_absoluta = __DIR__ . '/../../' . $row['ruta_archivo']; if (file_exists($ruta_absoluta)) { $archivos[] = [ - 'ruta' => $ruta_absoluta, + 'ruta' => $ruta_absoluta, 'nombre' => $row['nombre_archivo'] ]; } @@ -194,7 +204,7 @@ function descargar_zip($id_solicitud) } $zip_file = tempnam(sys_get_temp_dir(), 'expediente_') . '.zip'; - $zip = new ZipArchive(); + $zip = new ZipArchive(); if ($zip->open($zip_file, ZipArchive::CREATE) !== true) { http_response_code(500); diff --git a/app/controllers/importadores.php b/app/controllers/importadores.php index f920f32..eaf0aa3 100644 --- a/app/controllers/importadores.php +++ b/app/controllers/importadores.php @@ -4,7 +4,8 @@ require_once __DIR__ . '/../../config/database.php'; require_once __DIR__ . '/../helpers/crypto.php'; // Función para obtener catálogos visibles del usuario -function obtenerCatalogosVisibles($idUsuario) { +function obtenerCatalogosVisibles($idUsuario) +{ $conn = getConnection(); // Obtener configuración general y tipo de usuario @@ -132,7 +133,8 @@ function obtenerCatalogosVisibles($idUsuario) { } // Función para obtener icono según el nombre del catálogo -function obtenerIconoCatalogo($nombre) { +function obtenerIconoCatalogo($nombre) +{ $iconos = [ 'Locaciones' => '📍', 'Vinculación' => '🔗', @@ -169,28 +171,30 @@ function dashboard() function lista() { $conn = getConnection(); - $locaciones = []; // Consulta conjunta para evitar múltiples queries anidadas - $sql = " - SELECT - p.id_pais, p.nombre AS nombre_pais, p.iso2, p.iso3, - e.id_estado, e.nombre AS nombre_estado, e.abreviatura, - c.id_ciudad, c.nombre AS nombre_ciudad - FROM paises p - LEFT JOIN estados e ON p.id_pais = e.pais_id - LEFT JOIN ciudades c ON e.id_estado = c.estado_id - ORDER BY p.id_pais, e.id_estado, c.id_ciudad - "; - + $sql = "SELECT + p.id_pais, p.nombre AS nombre_pais, p.iso2, p.iso3, + e.id_estado, e.nombre AS nombre_estado, e.abreviatura, + c.id_ciudad, c.nombre AS nombre_ciudad + FROM paises p + LEFT JOIN estados e + ON p.id_pais = e.pais_id + LEFT JOIN ciudades c + ON e.id_estado = c.estado_id + ORDER BY p.id_pais, e.id_estado, c.id_ciudad + "; $stmt = sqlsrv_query($conn, $sql); + + $locaciones = []; while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { $locaciones[] = $row; } // Obtener países para los selects del modal - $sql_paises_select = "SELECT id_pais, nombre FROM paises ORDER BY nombre"; + $sql_paises_select = "SELECT id_pais, nombre FROM paises ORDER BY nombre"; $stmt_paises_select = sqlsrv_query($conn, $sql_paises_select); + $paises = []; while ($row = sqlsrv_fetch_array($stmt_paises_select, SQLSRV_FETCH_ASSOC)) { $paises[] = $row; @@ -225,7 +229,10 @@ function vincular() } // Insertar la nueva solicitud - $sql = "INSERT INTO solicitudes_vinculacion (id_importador, id_agencia, mensaje, estado, fecha_solicitud) VALUES (?, ?, 'Solicitud de vinculación', 'PENDIENTE', GETDATE())"; + $sql = "INSERT INTO solicitudes_vinculacion + (id_importador, id_agencia, mensaje, estado, fecha_solicitud) + VALUES (?, ?, 'Solicitud de vinculación', 'PENDIENTE', GETDATE()) + "; $params = [$id_importador, $id_agencia]; $stmt = sqlsrv_prepare($conn, $sql, $params); @@ -250,12 +257,14 @@ function cancelarVinculacion() $id_importador = $_SESSION['usuario_id']; $id_agencia = (int) $_GET['id']; - $sql = "UPDATE solicitudes_vinculacion - SET estado = 'CANCELADA', fecha_respuesta = GETDATE() - WHERE id_importador = ? AND id_agencia = ? AND estado = 'PENDIENTE'"; - + $sql = "UPDATE solicitudes_vinculacion + SET estado = 'CANCELADA', fecha_respuesta = GETDATE() + WHERE id_importador = ? + AND id_agencia = ? + AND estado = 'PENDIENTE' + "; $params = [$id_importador, $id_agencia]; - $stmt = sqlsrv_prepare($conn, $sql, $params); + $stmt = sqlsrv_prepare($conn, $sql, $params); if ($stmt && sqlsrv_execute($stmt)) { header('Location: /IMPORTADORES/vinculaciones/nuevaVinculacion?success=cancelled'); @@ -284,15 +293,16 @@ function desvincularUsuario() sqlsrv_begin_transaction($conn); // 1. Verificar que la relación existe y pertenece a la agencia del admin - $sqlVerificar = " - SELECT - ia.*, - u.id_usuario, u.nombre as importador_nombre, aa.nombre_agencia - FROM importador_agencia ia - INNER JOIN usuarios_sistema u ON ia.id_importador = u.id_usuario - INNER JOIN agencias_aduanales aa ON ia.id_agencia = aa.id_agencia - WHERE ia.id_relacion = ? AND ia.id_importador = ? - "; + $sqlVerificar = "SELECT + ia.*, u.id_usuario, u.nombre as importador_nombre, aa.nombre_agencia + FROM importador_agencia ia + INNER JOIN usuarios_sistema u + ON ia.id_importador = u.id_usuario + INNER JOIN agencias_aduanales aa + ON ia.id_agencia = aa.id_agencia + WHERE ia.id_relacion = ? + AND ia.id_importador = ? + "; $stmtVerificar = sqlsrv_query($conn, $sqlVerificar, [$id_relacion, $_SESSION['usuario_id']]); // Verificar si la consulta fue exitosa @@ -313,14 +323,13 @@ function desvincularUsuario() } // 2. Desactivar la relación (no eliminar, mantener historial) - $sqlDesactivar = " - UPDATE importador_agencia - SET activo = 0, - fecha_desvinculacion = GETDATE(), - estado = 'DESVINCULADO' - WHERE id_relacion = ? AND id_importador = ? - "; - + $sqlDesactivar = "UPDATE importador_agencia + SET activo = 0, + fecha_desvinculacion = GETDATE(), + estado = 'DESVINCULADO' + WHERE id_relacion = ? + AND id_importador = ? + "; $stmtDesactivar = sqlsrv_query($conn, $sqlDesactivar, [$id_relacion, $_SESSION['usuario_id']]); if ($stmtDesactivar === false) { @@ -337,11 +346,7 @@ function desvincularUsuario() // 3. Actualizar el campo id_agencia_en_uso del usuario si es necesario if ($_SESSION['id_agencia_en_uso'] == $relacion['id_agencia']) { - $sqlActualizarAgencia = " - UPDATE usuarios_sistema - SET id_agencia_en_uso = NULL - WHERE id_usuario = ? - "; + $sqlActualizarAgencia = "UPDATE usuarios_sistema SET id_agencia_en_uso = NULL WHERE id_usuario = ?"; $stmtActualizarAgencia = sqlsrv_query($conn, $sqlActualizarAgencia, [$_SESSION['usuario_id']]); if ($stmtActualizarAgencia === false) { @@ -392,11 +397,7 @@ function cambiarAgenciaActiva() $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 - "; + $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)) { @@ -405,11 +406,7 @@ function cambiarAgenciaActiva() } // Actualizar campo id_agencia_en_uso - $sqlUpdate = " - UPDATE usuarios_sistema - SET id_agencia_en_uso = ? - WHERE id_usuario = ? - "; + $sqlUpdate = "UPDATE usuarios_sistema SET id_agencia_en_uso = ? WHERE id_usuario = ?"; $stmtUpdate = sqlsrv_query($conn, $sqlUpdate, [$id_agencia, $id_usuario]); if ($stmtUpdate === false) { diff --git a/app/controllers/locaciones.php b/app/controllers/locaciones.php index bb228b5..1de0189 100644 --- a/app/controllers/locaciones.php +++ b/app/controllers/locaciones.php @@ -1,6 +1,5 @@ false, 'message' => 'Debe seleccionar un país']); @@ -106,8 +106,8 @@ function guardarEstado() $conn = getConnection(); // Verificar que el país existe - $sql_pais = "SELECT COUNT(*) as count FROM paises WHERE id_pais = ?"; - $stmt_pais = sqlsrv_query($conn, $sql_pais, [$pais_id]); + $sql_pais = "SELECT COUNT(*) as count FROM paises WHERE id_pais = ?"; + $stmt_pais = sqlsrv_query($conn, $sql_pais, [$pais_id]); $pais_exists = sqlsrv_fetch_array($stmt_pais, SQLSRV_FETCH_ASSOC); if ($pais_exists['count'] == 0) { @@ -116,9 +116,9 @@ function guardarEstado() } // Verificar si ya existe el estado en ese país - $sql_check = "SELECT COUNT(*) as count FROM estados WHERE pais_id = ? AND nombre = ?"; + $sql_check = "SELECT COUNT(*) as count FROM estados WHERE pais_id = ? AND nombre = ?"; $stmt_check = sqlsrv_query($conn, $sql_check, [$pais_id, $entidad]); - $exists = sqlsrv_fetch_array($stmt_check, SQLSRV_FETCH_ASSOC); + $exists = sqlsrv_fetch_array($stmt_check, SQLSRV_FETCH_ASSOC); if ($exists['count'] > 0) { echo json_encode(['success' => false, 'message' => 'Este estado ya existe en el país seleccionado']); @@ -127,12 +127,12 @@ function guardarEstado() // Insertar nuevo estado // Primero obtenemos el siguiente ID disponible - $sql_max = "SELECT ISNULL(MAX(id_estado), 0) + 1 as next_id FROM estados"; - $stmt_max = sqlsrv_query($conn, $sql_max); + $sql_max = "SELECT ISNULL(MAX(id_estado), 0) + 1 as next_id FROM estados"; + $stmt_max = sqlsrv_query($conn, $sql_max); $next_id_row = sqlsrv_fetch_array($stmt_max, SQLSRV_FETCH_ASSOC); - $next_id = $next_id_row['next_id']; + $next_id = $next_id_row['next_id']; - $sql = "INSERT INTO estados (id_estado, pais_id, nombre) VALUES (?, ?, ?)"; + $sql = "INSERT INTO estados (id_estado, pais_id, nombre) VALUES (?, ?, ?)"; $stmt = sqlsrv_query($conn, $sql, [$next_id, $pais_id, $entidad]); if ($stmt) { @@ -160,8 +160,8 @@ function guardarCiudad() header('Content-Type: application/json; charset=utf-8'); try { - $estado_id = $_POST['entidad'] ?? ''; - $ciudad = trim($_POST['ciudad'] ?? ''); + $estado_id = $_POST['entidad'] ?? ''; + $ciudad = trim($_POST['ciudad'] ?? ''); // Validaciones if (empty($estado_id) || empty($ciudad)) { @@ -172,9 +172,9 @@ function guardarCiudad() $conn = getConnection(); // Verificar si ya existe la ciudad en ese estado - $sql_check = "SELECT COUNT(*) as count FROM ciudades WHERE estado_id = ? AND nombre = ?"; + $sql_check = "SELECT COUNT(*) as count FROM ciudades WHERE estado_id = ? AND nombre = ?"; $stmt_check = sqlsrv_query($conn, $sql_check, [$estado_id, $ciudad]); - $exists = sqlsrv_fetch_array($stmt_check, SQLSRV_FETCH_ASSOC); + $exists = sqlsrv_fetch_array($stmt_check, SQLSRV_FETCH_ASSOC); if ($exists['count'] > 0) { echo json_encode(['success' => false, 'message' => 'Esta ciudad ya existe en el estado seleccionado']); @@ -182,11 +182,11 @@ function guardarCiudad() } // Insertar nueva ciudad - $sql = "INSERT INTO ciudades (estado_id, nombre) VALUES (?, ?)"; + $sql = "INSERT INTO ciudades (estado_id, nombre) VALUES (?, ?)"; $stmt = sqlsrv_query($conn, $sql, [$estado_id, $ciudad]); if ($stmt) { - echo json_encode(['success' => true, 'message' => 'Ciudad registrada exitosamente']); + echo json_encode(['success' => true, 'message' => 'Ciudad registrada exitosamente']); } else { echo json_encode(['success' => false, 'message' => 'Error al registrar la ciudad']); } @@ -211,11 +211,12 @@ function obtenerPaisPorEstado() } $conn = getConnection(); - $sql = "SELECT pais_id FROM estados WHERE id_estado = ?"; + + $sql = "SELECT pais_id FROM estados WHERE id_estado = ?"; $stmt = sqlsrv_query($conn, $sql, [$estado_id]); if ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { - echo json_encode(['success' => true, 'pais_id' => $row['pais_id']]); + echo json_encode(['success' => true, 'pais_id' => $row['pais_id']]); } else { echo json_encode(['success' => false, 'message' => 'Estado no encontrado']); } @@ -258,10 +259,10 @@ function actualizarPais() header('Content-Type: application/json; charset=utf-8'); try { - $id = $_POST['id'] ?? ''; + $id = $_POST['id'] ?? ''; $nombre = trim($_POST['nombre'] ?? ''); - $iso2 = trim($_POST['iso2'] ?? ''); - $iso3 = trim($_POST['iso3'] ?? ''); + $iso2 = trim($_POST['iso2'] ?? ''); + $iso3 = trim($_POST['iso3'] ?? ''); // Validaciones if (empty($id) || empty($nombre)) { @@ -270,13 +271,14 @@ function actualizarPais() } $conn = getConnection(); + if (!$conn) { echo json_encode(['success' => false, 'message' => 'Error de conexión a la base de datos']); exit; } // Verificar duplicados - $sql_check = "SELECT COUNT(*) as count FROM paises WHERE nombre = ? AND id_pais != ?"; + $sql_check = "SELECT COUNT(*) as count FROM paises WHERE nombre = ? AND id_pais != ?"; $stmt_check = sqlsrv_query($conn, $sql_check, [$nombre, $id]); if (!$stmt_check) { @@ -294,10 +296,9 @@ function actualizarPais() $iso2_val = empty($iso2) ? null : $iso2; $iso3_val = empty($iso3) ? null : $iso3; - $sql = "UPDATE paises SET nombre = ?, iso2 = ?, iso3 = ? WHERE id_pais = ?"; + $sql = "UPDATE paises SET nombre = ?, iso2 = ?, iso3 = ? WHERE id_pais = ?"; $params = [$nombre, $iso2_val, $iso3_val, $id]; - - $stmt = sqlsrv_query($conn, $sql, $params); + $stmt = sqlsrv_query($conn, $sql, $params); if ($stmt && sqlsrv_rows_affected($stmt) > 0) { echo json_encode(['success' => true, 'message' => 'País actualizado exitosamente']); @@ -317,10 +318,10 @@ function actualizarEstado() header('Content-Type: application/json; charset=utf-8'); try { - $id = $_POST['id'] ?? ''; - $nombre = trim($_POST['nombre'] ?? ''); + $id = $_POST['id'] ?? ''; + $nombre = trim($_POST['nombre'] ?? ''); $abreviatura = trim($_POST['abreviatura'] ?? ''); - $pais_id = $_POST['pais_id'] ?? ''; + $pais_id = $_POST['pais_id'] ?? ''; // Validaciones if (empty($id) || empty($nombre) || empty($pais_id)) { @@ -329,13 +330,14 @@ function actualizarEstado() } $conn = getConnection(); + if (!$conn) { echo json_encode(['success' => false, 'message' => 'Error de conexión a la base de datos']); exit; } // Verificar duplicados - $sql_check = "SELECT COUNT(*) as count FROM estados WHERE nombre = ? AND pais_id = ? AND id_estado != ?"; + $sql_check = "SELECT COUNT(*) as count FROM estados WHERE nombre = ? AND pais_id = ? AND id_estado != ?"; $stmt_check = sqlsrv_query($conn, $sql_check, [$nombre, $pais_id, $id]); if (!$stmt_check) { @@ -352,10 +354,9 @@ function actualizarEstado() // Actualizar $abreviatura_val = empty($abreviatura) ? null : $abreviatura; - $sql = "UPDATE estados SET nombre = ?, abreviatura = ?, pais_id = ? WHERE id_estado = ?"; + $sql = "UPDATE estados SET nombre = ?, abreviatura = ?, pais_id = ? WHERE id_estado = ?"; $params = [$nombre, $abreviatura_val, $pais_id, $id]; - - $stmt = sqlsrv_query($conn, $sql, $params); + $stmt = sqlsrv_query($conn, $sql, $params); if ($stmt && sqlsrv_rows_affected($stmt) > 0) { echo json_encode(['success' => true, 'message' => 'Estado actualizado exitosamente']); @@ -375,9 +376,9 @@ function actualizarCiudad() header('Content-Type: application/json; charset=utf-8'); try { - $id = $_POST['id'] ?? ''; - $nombre = trim($_POST['nombre'] ?? ''); - $estado_id = $_POST['estado_id'] ?? ''; + $id = $_POST['id'] ?? ''; + $nombre = trim($_POST['nombre'] ?? ''); + $estado_id = $_POST['estado_id'] ?? ''; // Validaciones if (empty($id) || empty($nombre) || empty($estado_id)) { @@ -386,13 +387,14 @@ function actualizarCiudad() } $conn = getConnection(); + if (!$conn) { echo json_encode(['success' => false, 'message' => 'Error de conexión a la base de datos']); exit; } // Verificar duplicados - $sql_check = "SELECT COUNT(*) as count FROM ciudades WHERE nombre = ? AND estado_id = ? AND id_ciudad != ?"; + $sql_check = "SELECT COUNT(*) as count FROM ciudades WHERE nombre = ? AND estado_id = ? AND id_ciudad != ?"; $stmt_check = sqlsrv_query($conn, $sql_check, [$nombre, $estado_id, $id]); if (!$stmt_check) { @@ -407,10 +409,9 @@ function actualizarCiudad() } // Actualizar - $sql = "UPDATE ciudades SET nombre = ?, estado_id = ? WHERE id_ciudad = ?"; + $sql = "UPDATE ciudades SET nombre = ?, estado_id = ? WHERE id_ciudad = ?"; $params = [$nombre, $estado_id, $id]; - - $stmt = sqlsrv_query($conn, $sql, $params); + $stmt = sqlsrv_query($conn, $sql, $params); if ($stmt && sqlsrv_rows_affected($stmt) > 0) { echo json_encode(['success' => true, 'message' => 'Ciudad actualizada exitosamente']); @@ -432,8 +433,8 @@ function eliminar() try { // Obtener datos del JSON enviado $input = json_decode(file_get_contents('php://input'), true); - $tipo = $input['tipo'] ?? ''; - $id = $input['id'] ?? ''; + $tipo = $input['tipo'] ?? ''; + $id = $input['id'] ?? ''; if (empty($tipo) || empty($id)) { echo json_encode(['success' => false, 'message' => 'Datos incompletos']); @@ -445,8 +446,8 @@ function eliminar() switch ($tipo) { case 'pais': // Verificar si el país tiene estados asociados - $sql_check = "SELECT COUNT(*) as count FROM estados WHERE pais_id = ?"; - $stmt_check = sqlsrv_query($conn, $sql_check, [$id]); + $sql_check = "SELECT COUNT(*) as count FROM estados WHERE pais_id = ?"; + $stmt_check = sqlsrv_query($conn, $sql_check, [$id]); $has_estados = sqlsrv_fetch_array($stmt_check, SQLSRV_FETCH_ASSOC); if ($has_estados['count'] > 0) { @@ -455,7 +456,7 @@ function eliminar() } // Eliminar país - $sql = "DELETE FROM paises WHERE id_pais = ?"; + $sql = "DELETE FROM paises WHERE id_pais = ?"; $stmt = sqlsrv_query($conn, $sql, [$id]); if ($stmt) { @@ -472,8 +473,8 @@ function eliminar() case 'estado': // Verificar si el estado tiene ciudades asociadas - $sql_check = "SELECT COUNT(*) as count FROM ciudades WHERE estado_id = ?"; - $stmt_check = sqlsrv_query($conn, $sql_check, [$id]); + $sql_check = "SELECT COUNT(*) as count FROM ciudades WHERE estado_id = ?"; + $stmt_check = sqlsrv_query($conn, $sql_check, [$id]); $has_ciudades = sqlsrv_fetch_array($stmt_check, SQLSRV_FETCH_ASSOC); if ($has_ciudades['count'] > 0) { @@ -482,7 +483,7 @@ function eliminar() } // Eliminar estado - $sql = "DELETE FROM estados WHERE id_estado = ?"; + $sql = "DELETE FROM estados WHERE id_estado = ?"; $stmt = sqlsrv_query($conn, $sql, [$id]); if ($stmt) { @@ -502,7 +503,7 @@ function eliminar() // (aquí puedes agregar más verificaciones según tu modelo de datos) // Eliminar ciudad - $sql = "DELETE FROM ciudades WHERE id_ciudad = ?"; + $sql = "DELETE FROM ciudades WHERE id_ciudad = ?"; $stmt = sqlsrv_query($conn, $sql, [$id]); if ($stmt) { diff --git a/app/controllers/login.php b/app/controllers/login.php index 26960ba..f1423a1 100644 --- a/app/controllers/login.php +++ b/app/controllers/login.php @@ -4,8 +4,8 @@ require_once __DIR__ . '/../../config/database.php'; require_once __DIR__ . '/../helpers/crypto.php'; require_once __DIR__ . '/../helpers/bitacoras.php'; require_once __DIR__ . '/../helpers/env.php'; - require_once __DIR__ . '/../../vendor/autoload.php'; + use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception; @@ -33,9 +33,7 @@ function validar() $emailEncrypted = encrypt($email); // Obtenemos el usuario incluyendo el campo dos_factores - $sql = "SELECT id_usuario, nombre, email, password_hash, tipo_usuario, activo, dos_factores - FROM usuarios_sistema WHERE email = ?"; - + $sql = "SELECT id_usuario, nombre, email, password_hash, tipo_usuario, activo, dos_factores FROM usuarios_sistema WHERE email = ?"; $stmt = sqlsrv_query($conn, $sql, [$emailEncrypted]); if ($stmt && $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { @@ -225,9 +223,7 @@ function confirmarAcceso() exit; } - $sql = "SELECT codigo, expiracion FROM verificaciones - WHERE id_usuario = ? AND codigo = ? - ORDER BY id DESC"; + $sql = "SELECT codigo, expiracion FROM verificaciones WHERE id_usuario = ? AND codigo = ? ORDER BY id DESC"; $stmt = sqlsrv_query($conn, $sql, [$usuarioId, $codigoIngresado]); if (!$stmt || !($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC))) { @@ -282,7 +278,9 @@ function recuperar() function enviarCodigo() { header('Content-Type: application/json'); + $conn = getConnection(); + if (!$conn) { echo json_encode(['success' => false, 'message' => '❌ Error de conexión con la base de datos.']); exit; @@ -314,8 +312,7 @@ function enviarCodigo() } $now = (new DateTime())->format('Y-m-d H:i:s'); - $sqlCheck = "SELECT COUNT(*) AS total FROM recuperacion_password - WHERE email = ? AND estatus = 0 AND expiracion > ?"; + $sqlCheck = "SELECT COUNT(*) AS total FROM recuperacion_password WHERE email = ? AND estatus = 0 AND expiracion > ?"; $checkStmt = sqlsrv_query($conn, $sqlCheck, [$emailEncrypted, $now]); $checkRow = sqlsrv_fetch_array($checkStmt, SQLSRV_FETCH_ASSOC); @@ -339,7 +336,7 @@ function enviarCodigo() // ✅ AGREGAR ESTAS LÍNEAS PARA ESTABLECER LA SESIÓN $_SESSION['email_recuperacion'] = $email; - $_SESSION['id_usuario'] = $id_usuario; + $_SESSION['id_usuario'] = $id_usuario; try { $mail = new PHPMailer(true); @@ -458,6 +455,7 @@ function reenviarCodigo() } $conn = getConnection(); + if (!$conn) { echo json_encode(['success' => false, 'message' => '❌ Error de conexión con la base de datos.']); exit; @@ -467,10 +465,8 @@ function reenviarCodigo() $emailEncrypted = encrypt($_SESSION['email_recuperacion']); // Obtener el último código activo de recuperación - $now = (new DateTime())->format('Y-m-d H:i:s'); - $sql = "SELECT TOP 1 codigo FROM recuperacion_password - WHERE email = ? AND estatus = 0 AND expiracion > ? - ORDER BY expiracion DESC"; + $now = (new DateTime())->format('Y-m-d H:i:s'); + $sql = "SELECT TOP 1 codigo FROM recuperacion_password WHERE email = ? AND estatus = 0 AND expiracion > ? ORDER BY expiracion DESC"; $stmt = sqlsrv_query($conn, $sql, [$emailEncrypted, $now]); if (!$stmt || !($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC))) { @@ -530,8 +526,7 @@ function verificarCodigo() $emailEncrypted = encrypt($email); // Consulta el último código válido para ese email - $sql = "SELECT TOP 1 id, codigo, expiracion FROM recuperacion_password - WHERE email = ? AND estatus = 0 ORDER BY id DESC"; + $sql = "SELECT TOP 1 id, codigo, expiracion FROM recuperacion_password WHERE email = ? AND estatus = 0 ORDER BY id DESC"; $stmt = sqlsrv_query($conn, $sql, [$emailEncrypted]); if ($stmt === false) { @@ -567,13 +562,13 @@ function verificarCodigo() // Verificar si se han excedido los intentos if ($_SESSION['intentos_codigo'] >= 5) { // Bloquear el código - $sqlUpdate = "UPDATE recuperacion_password SET estatus = 1 WHERE id = ?"; + $sqlUpdate = "UPDATE recuperacion_password SET estatus = 1 WHERE id = ?"; $stmtUpdate = sqlsrv_query($conn, $sqlUpdate, [$row['id']]); if ($stmtUpdate) sqlsrv_free_stmt($stmtUpdate); // Bloquear la cuenta del usuario $sqlBloquearUsuario = "UPDATE usuarios_sistema SET activo = 0 WHERE email = ?"; - $stmtBloqueo = sqlsrv_query($conn, $sqlBloquearUsuario, [$emailEncrypted]); + $stmtBloqueo = sqlsrv_query($conn, $sqlBloquearUsuario, [$emailEncrypted]); if ($stmtBloqueo) sqlsrv_free_stmt($stmtBloqueo); // Enviar notificación @@ -639,25 +634,25 @@ function verificarCodigo() function enviarNotificacionIntentosExcedidos($email) { $conn = getConnection(); + if (!$conn) { throw new Exception("No se pudo conectar a la base de datos"); } // Buscar información del usuario por email $emailEncrypted = encrypt($email); - $sqlNotif = " - SELECT - u.nombre, - u.email, - u.notificaciones, - u.notificaciones_extra, - COALESCE(p.intentos_fallidos, 0) as intentos_fallidos, - ce.correo as correo_extra - FROM usuarios_sistema u - LEFT JOIN preferencias_notificaciones_usuario p ON u.id_usuario = p.id_usuario - LEFT JOIN correo_extra ce ON u.id_usuario = ce.id_usuario - WHERE u.email = ?"; + $sqlNotif = "SELECT + u.nombre, u.email, u.notificaciones, u.notificaciones_extra, + COALESCE(p.intentos_fallidos, 0) as intentos_fallidos, + ce.correo as correo_extra + FROM usuarios_sistema u + LEFT JOIN preferencias_notificaciones_usuario p + ON u.id_usuario = p.id_usuario + LEFT JOIN correo_extra ce + ON u.id_usuario = ce.id_usuario + WHERE u.email = ? + "; $stmtUsuario = sqlsrv_query($conn, $sqlNotif, [$emailEncrypted]); if ($stmtUsuario === false) { @@ -687,7 +682,7 @@ function enviarNotificacionIntentosExcedidos($email) 'email' => $usuario['email'], 'nombre' => $usuario['nombre'], 'fecha_hora' => date('Y-m-d H:i:s'), - 'ip' => $_SERVER['REMOTE_ADDR'] ?? 'Desconocida', + 'ip' => $_SERVER['REMOTE_ADDR'] ?? 'Desconocida', 'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'Desconocido' ]; @@ -822,23 +817,21 @@ function enviarNotificacionSeguridadIntentos($emailDestino, $nombreUsuario, $dat function enviarNotificacionCuentaBloqueada($email) { $conn = getConnection(); + if (!$conn) { throw new Exception("No se pudo conectar a la base de datos"); } // Buscar información del usuario por email (incluyendo correo extra) $emailEncrypted = encrypt($email); - $sqlNotif = " - SELECT - u.nombre, - u.email, - u.notificaciones, - u.notificaciones_extra, - ce.correo as correo_extra - FROM usuarios_sistema u - LEFT JOIN correo_extra ce ON u.id_usuario = ce.id_usuario - WHERE u.email = ?"; - + $sqlNotif = "SELECT + u.nombre, u.email, u.notificaciones, u.notificaciones_extra, + ce.correo as correo_extra + FROM usuarios_sistema u + LEFT JOIN correo_extra ce + ON u.id_usuario = ce.id_usuario + WHERE u.email = ? + "; $stmtUsuario = sqlsrv_query($conn, $sqlNotif, [$emailEncrypted]); if ($stmtUsuario === false) { @@ -854,7 +847,7 @@ function enviarNotificacionCuentaBloqueada($email) } // 🔐 Desencriptar datos sensibles - $usuario['email'] = decrypt($usuario['email']); + $usuario['email'] = decrypt($usuario['email']); $usuario['nombre'] = decrypt($usuario['nombre']); // Preparar datos para la notificación @@ -862,7 +855,7 @@ function enviarNotificacionCuentaBloqueada($email) 'email' => $usuario['email'], 'nombre' => $usuario['nombre'], 'fecha_hora' => date('Y-m-d H:i:s'), - 'ip' => $_SERVER['REMOTE_ADDR'] ?? 'Desconocida', + 'ip' => $_SERVER['REMOTE_ADDR'] ?? 'Desconocida', 'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'Desconocido' ]; @@ -1019,8 +1012,9 @@ function cambiarPassword() return; } - $conn = getConnection(); - $password = $_POST['password'] ?? ''; + $conn = getConnection(); + + $password = $_POST['password'] ?? ''; $confirmar = $_POST['confirmar'] ?? ''; // Validaciones diff --git a/app/controllers/patente.php b/app/controllers/patente.php index ff728f7..0d677bb 100644 --- a/app/controllers/patente.php +++ b/app/controllers/patente.php @@ -1,6 +1,5 @@ 10) die("❌ El campo {$campo} no puede exceder 10 caracteres."); // Opcional: Si quieres mantener solo números, descomenta la siguiente línea - // if (!is_numeric($valor)) die("❌ El campo {$campo} debe ser numérico."); + if (!is_numeric($valor)) die("❌ El campo {$campo} debe ser numérico."); } } // Validar todos los campos de folios - validarFolio($vp_inicio, 'VP Inicio'); - validarFolio($vp_final, 'VP Final'); - validarFolio($vp_siguiente, 'VP Siguiente'); - validarFolio($vpe_inicio, 'VPE Inicio'); - validarFolio($vpe_final, 'VPE Final'); - validarFolio($vpe_siguiente, 'VPE Siguiente'); - validarFolio($vat_pb_inicio, 'VAT PB Inicio'); - validarFolio($vat_pb_final, 'VAT PB Final'); + validarFolio($vp_inicio, 'VP Inicio'); + validarFolio($vp_final, 'VP Final'); + validarFolio($vp_siguiente, 'VP Siguiente'); + validarFolio($vpe_inicio, 'VPE Inicio'); + validarFolio($vpe_final, 'VPE Final'); + validarFolio($vpe_siguiente, 'VPE Siguiente'); + validarFolio($vat_pb_inicio, 'VAT PB Inicio'); + validarFolio($vat_pb_final, 'VAT PB Final'); validarFolio($vat_pb_siguiente, 'VAT PB Siguiente'); - validarFolio($vcc_inicio, 'VCC Inicio'); - validarFolio($vcc_final, 'VCC Final'); - validarFolio($vcc_siguiente, 'VCC Siguiente'); - validarFolio($vae_inicio, 'VAE Inicio'); - validarFolio($vae_final, 'VAE Final'); - validarFolio($vae_siguiente, 'VAE Siguiente'); + validarFolio($vcc_inicio, 'VCC Inicio'); + validarFolio($vcc_final, 'VCC Final'); + validarFolio($vcc_siguiente, 'VCC Siguiente'); + validarFolio($vae_inicio, 'VAE Inicio'); + validarFolio($vae_final, 'VAE Final'); + validarFolio($vae_siguiente, 'VAE Siguiente'); // Validar duplicado para este usuario - $sqlCheck = "SELECT COUNT(*) as count FROM dbo.agentes_aduanales WHERE aduana = ? AND patente = ? AND id_usuario = ?"; + $sqlCheck = "SELECT COUNT(*) as count FROM dbo.agentes_aduanales WHERE aduana = ? AND patente = ? AND id_usuario = ?"; $stmtCheck = sqlsrv_query($conn, $sqlCheck, [$aduana, $patente, $id_usuario]); if ($stmtCheck === false) die("❌ Error al verificar duplicados: " . print_r(sqlsrv_errors(), true)); @@ -209,27 +215,27 @@ function guardar() $vae_siguiente = empty($vae_siguiente) ? null : $vae_siguiente; // Insertar registro - $sql = "INSERT INTO dbo.agentes_aduanales - (id_agencia, aduana, patente, agente_aduanal, rfc, curp, razon_social, id_usuario, activo, - mf_nombre, mf_paterno, mf_materno, - vp_inicio, vp_final, vp_siguiente, - vpe_inicio, vpe_final, vpe_siguiente, - vat_pb_inicio, vat_pb_final, vat_pb_siguiente, - vcc_inicio, vcc_final, vcc_siguiente, - vae_inicio, vae_final, vae_siguiente) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; - + $sql = "INSERT INTO dbo.agentes_aduanales + (id_agencia, aduana, patente, agente_aduanal, rfc, curp, razon_social, id_usuario, activo, + mf_nombre, mf_paterno, mf_materno, + vp_inicio, vp_final, vp_siguiente, + vpe_inicio, vpe_final, vpe_siguiente, + vat_pb_inicio, vat_pb_final, vat_pb_siguiente, + vcc_inicio, vcc_final, vcc_siguiente, + vae_inicio, vae_final, vae_siguiente) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + "; $params = [ - $id_agencia, $aduana, $patente, $agente_aduanal, $rfc, $curp, $razon_social, $id_usuario, - $mf_nombre, $mf_paterno, $mf_materno, - $vp_inicio, $vp_final, $vp_siguiente, - $vpe_inicio, $vpe_final, $vpe_siguiente, - $vat_pb_inicio, $vat_pb_final, $vat_pb_siguiente, - $vcc_inicio, $vcc_final, $vcc_siguiente, - $vae_inicio, $vae_final, $vae_siguiente - ]; + $id_agencia, $aduana, $patente, $agente_aduanal, $rfc, $curp, $razon_social, $id_usuario, + $mf_nombre, $mf_paterno, $mf_materno, + $vp_inicio, $vp_final, $vp_siguiente, + $vpe_inicio, $vpe_final, $vpe_siguiente, + $vat_pb_inicio, $vat_pb_final, $vat_pb_siguiente, + $vcc_inicio, $vcc_final, $vcc_siguiente, + $vae_inicio, $vae_final, $vae_siguiente + ]; + $stmt = sqlsrv_query($conn, $sql, $params); - $stmt = sqlsrv_query($conn, $sql, $params); if ($stmt === false) die("❌ Error al guardar agente aduanal."); sqlsrv_free_stmt($stmt); @@ -246,9 +252,9 @@ function editar() exit; } - $id_usuario = $_SESSION['usuario_id']; + $id_usuario = $_SESSION['usuario_id']; $tipo_usuario = $_SESSION['tipo_usuario']; - $id = $_GET['id'] ?? null; + $id = $_GET['id'] ?? null; if (!$id || !is_numeric($id)) { die("❌ ID inválido."); @@ -262,13 +268,13 @@ function editar() if ($tipo_usuario === 'agente_aduanal') { // Obtener la agencia vinculada al agente $stmtAgencia = sqlsrv_query($conn, "SELECT id_agencia FROM dbo.agente_agencia WHERE id_agente = ?", [$id_usuario]); - $rowAgencia = sqlsrv_fetch_array($stmtAgencia, SQLSRV_FETCH_ASSOC); - $id_agencia = $rowAgencia['id_agencia'] ?? null; + $rowAgencia = sqlsrv_fetch_array($stmtAgencia, SQLSRV_FETCH_ASSOC); + $id_agencia = $rowAgencia['id_agencia'] ?? null; } elseif ($tipo_usuario === 'admin_agencia') { // Obtener la agencia del admin $stmtAgencia = sqlsrv_query($conn, "SELECT id_agencia FROM dbo.agente_agencia WHERE id_agente = ?", [$id_usuario]); - $rowAgencia = sqlsrv_fetch_array($stmtAgencia, SQLSRV_FETCH_ASSOC); - $id_agencia = $rowAgencia['id_agencia'] ?? null; + $rowAgencia = sqlsrv_fetch_array($stmtAgencia, SQLSRV_FETCH_ASSOC); + $id_agencia = $rowAgencia['id_agencia'] ?? null; } else { die("❌ Tipo de usuario no autorizado."); } @@ -278,7 +284,7 @@ function editar() } // Consultar la patente que tenga ese id_agente y que pertenezca a la agencia del usuario - $sql = "SELECT * FROM dbo.agentes_aduanales WHERE id_agente = ? AND id_agencia = ?"; + $sql = "SELECT * FROM dbo.agentes_aduanales WHERE id_agente = ? AND id_agencia = ?"; $stmt = sqlsrv_query($conn, $sql, [$id, $id_agencia]); if ($stmt === false) { @@ -314,6 +320,7 @@ function actualizar() // ✅ NUEVO: Obtener la agencia actual del usuario $stmt = sqlsrv_query($conn, "SELECT id_agencia FROM dbo.agente_agencia WHERE id_agente = ?", [$id_usuario]); + $id_agencia = null; if ($stmt && $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { $id_agencia = $row['id_agencia']; @@ -354,13 +361,13 @@ function actualizar() if (strlen($curp) > 18) die("❌ El CURP no puede exceder 18 caracteres."); // Validar duplicado (excepto el propio id) - $sqlCheck = "SELECT COUNT(*) as count FROM dbo.agentes_aduanales - WHERE aduana = ? AND patente = ? AND id_usuario = ? AND id_agente != ?"; + $sqlCheck = "SELECT COUNT(*) as count FROM dbo.agentes_aduanales WHERE aduana = ? AND patente = ? AND id_usuario = ? AND id_agente != ?"; $stmtCheck = sqlsrv_query($conn, $sqlCheck, [$aduana, $patente, $id_usuario, $id_agente]); if ($stmtCheck === false) die("❌ Error al verificar duplicados."); $row = sqlsrv_fetch_array($stmtCheck, SQLSRV_FETCH_ASSOC); + if ($row['count'] > 0) die("❌ Ya existe un agente aduanal con esta combinación de aduana y patente."); sqlsrv_free_stmt($stmtCheck); @@ -383,28 +390,29 @@ function actualizar() $vae_siguiente = empty($vae_siguiente) ? null : $vae_siguiente; // UPDATE - $sql = "UPDATE dbo.agentes_aduanales SET - aduana = ?, patente = ?, agente_aduanal = ?, rfc = ?, curp = ?, razon_social = ?, - mf_nombre = ?, mf_paterno = ?, mf_materno = ?, - vp_inicio = ?, vp_final = ?, vp_siguiente = ?, - vpe_inicio = ?, vpe_final = ?, vpe_siguiente = ?, - vat_pb_inicio = ?, vat_pb_final = ?, vat_pb_siguiente = ?, - vcc_inicio = ?, vcc_final = ?, vcc_siguiente = ?, - vae_inicio = ?, vae_final = ?, vae_siguiente = ?, id_agencia = ? - WHERE id_agente = ? AND id_usuario = ?"; - + $sql = "UPDATE dbo.agentes_aduanales SET + aduana = ?, patente = ?, agente_aduanal = ?, rfc = ?, curp = ?, razon_social = ?, + mf_nombre = ?, mf_paterno = ?, mf_materno = ?, + vp_inicio = ?, vp_final = ?, vp_siguiente = ?, + vpe_inicio = ?, vpe_final = ?, vpe_siguiente = ?, + vat_pb_inicio = ?, vat_pb_final = ?, vat_pb_siguiente = ?, + vcc_inicio = ?, vcc_final = ?, vcc_siguiente = ?, + vae_inicio = ?, vae_final = ?, vae_siguiente = ?, id_agencia = ? + WHERE id_agente = ? + AND id_usuario = ? + "; $params = [ - $aduana, $patente, $agente_aduanal, $rfc, $curp, $razon_social, - $mf_nombre, $mf_paterno, $mf_materno, - $vp_inicio, $vp_final, $vp_siguiente, - $vpe_inicio, $vpe_final, $vpe_siguiente, - $vat_pb_inicio, $vat_pb_final, $vat_pb_siguiente, - $vcc_inicio, $vcc_final, $vcc_siguiente, - $vae_inicio, $vae_final, $vae_siguiente, $id_agencia, - $id_agente, $id_usuario - ]; + $aduana, $patente, $agente_aduanal, $rfc, $curp, $razon_social, + $mf_nombre, $mf_paterno, $mf_materno, + $vp_inicio, $vp_final, $vp_siguiente, + $vpe_inicio, $vpe_final, $vpe_siguiente, + $vat_pb_inicio, $vat_pb_final, $vat_pb_siguiente, + $vcc_inicio, $vcc_final, $vcc_siguiente, + $vae_inicio, $vae_final, $vae_siguiente, $id_agencia, + $id_agente, $id_usuario + ]; + $stmt = sqlsrv_query($conn, $sql, $params); - $stmt = sqlsrv_query($conn, $sql, $params); if ($stmt === false) die("❌ Error al actualizar agente aduanal."); sqlsrv_free_stmt($stmt); @@ -424,6 +432,7 @@ function eliminar() $usr = $_SESSION['usuario_id']; $id = $_GET['id'] ?? null; + if (!$id || !is_numeric($id)) { die("❌ ID inválido."); } @@ -431,17 +440,17 @@ function eliminar() $conn = getConnection(); // Verificar que el transportista exista y pertenezca al usuario - $sqlChk = "SELECT COUNT(*) AS cnt - FROM dbo.agentes_aduanales - WHERE id_agente = ? AND id_usuario = ?"; + $sqlChk = "SELECT COUNT(*) AS cnt FROM dbo.agentes_aduanales WHERE id_agente = ? AND id_usuario = ?"; $stmtChk = sqlsrv_query($conn, $sqlChk, [$id, $usr]); $rowChk = sqlsrv_fetch_array($stmtChk, SQLSRV_FETCH_ASSOC); + if ($rowChk['cnt'] == 0) { die("❌ Agente no encontrado o no autorizado."); } $sql = "UPDATE dbo.agentes_aduanales SET activo = 0 WHERE id_agente = ?"; $stmt = sqlsrv_query($conn, $sql, [(int)$id]); + if ($stmt === false) { die("❌ Error en eliminar(): " . print_r(sqlsrv_errors(), true)); } diff --git a/app/controllers/preferencias.php b/app/controllers/preferencias.php index fed85a0..31ae09b 100644 --- a/app/controllers/preferencias.php +++ b/app/controllers/preferencias.php @@ -10,7 +10,8 @@ function index() function notificaciones() { - $conn = getConnection(); + $conn = getConnection(); + $idUsuario = $_SESSION['usuario_id'] ?? null; if (!$idUsuario) { @@ -353,7 +354,7 @@ function guardarPreferenciasAjax() try { // Obtener tipo de usuario $query = "SELECT tipo_usuario FROM usuarios_sistema WHERE id_usuario = ?"; - $stmt = sqlsrv_prepare($conn, $query, [$id_usuario]); + $stmt = sqlsrv_prepare($conn, $query, [$id_usuario]); if (!$stmt || !sqlsrv_execute($stmt)) { throw new Exception("Error al obtener tipo de usuario"); } @@ -385,7 +386,7 @@ function guardarPreferenciasAjax() $notificaciones_extra = $notificaciones ? ($input['notificaciones_extra'] ?? 0) : 0; $query = "UPDATE usuarios_sistema SET notificaciones = ?, notificaciones_extra = ? WHERE id_usuario = ?"; - $stmt = sqlsrv_prepare($conn, $query, [$notificaciones, $notificaciones_extra, $id_usuario]); + $stmt = sqlsrv_prepare($conn, $query, [$notificaciones, $notificaciones_extra, $id_usuario]); if (!$stmt || !sqlsrv_execute($stmt)) { throw new Exception("Error al actualizar configuración general"); @@ -397,7 +398,7 @@ function guardarPreferenciasAjax() $tabla_preferencias = getTablaPreferencias($tipo_usuario); if ($tabla_preferencias) { $query_delete = "DELETE FROM $tabla_preferencias WHERE id_usuario = ?"; - $stmt_delete = sqlsrv_prepare($conn, $query_delete, [$id_usuario]); + $stmt_delete = sqlsrv_prepare($conn, $query_delete, [$id_usuario]); if ($stmt_delete) { sqlsrv_execute($stmt_delete); sqlsrv_free_stmt($stmt_delete); @@ -406,7 +407,7 @@ function guardarPreferenciasAjax() } $response_data = [ - 'notificaciones' => $notificaciones, + 'notificaciones' => $notificaciones, 'notificaciones_extra' => $notificaciones_extra ]; break; @@ -417,7 +418,7 @@ function guardarPreferenciasAjax() // Validar que existe correo extra si se quiere activar if ($notificaciones_extra) { $query_check = "SELECT correo FROM correo_extra WHERE id_usuario = ?"; - $stmt_check = sqlsrv_prepare($conn, $query_check, [$id_usuario]); + $stmt_check = sqlsrv_prepare($conn, $query_check, [$id_usuario]); if ($stmt_check && sqlsrv_execute($stmt_check)) { $row = sqlsrv_fetch_array($stmt_check, SQLSRV_FETCH_ASSOC); sqlsrv_free_stmt($stmt_check); @@ -431,7 +432,7 @@ function guardarPreferenciasAjax() } $query = "UPDATE usuarios_sistema SET notificaciones_extra = ? WHERE id_usuario = ?"; - $stmt = sqlsrv_prepare($conn, $query, [$notificaciones_extra, $id_usuario]); + $stmt = sqlsrv_prepare($conn, $query, [$notificaciones_extra, $id_usuario]); if (!$stmt || !sqlsrv_execute($stmt)) { throw new Exception("Error al actualizar configuración de correo extra"); @@ -445,16 +446,16 @@ function guardarPreferenciasAjax() case 'tipo_notificacion': $tipo_nombre = $input['nombre'] ?? ''; - $valor = $input['valor'] ? 1 : 0; + $valor = $input['valor'] ? 1 : 0; if (empty($tipo_nombre)) { throw new Exception("Tipo de notificación no especificado"); } // Obtener configuración específica según tipo de usuario - $config = getConfiguracionTipoUsuario($tipo_usuario); + $config = getConfiguracionTipoUsuario($tipo_usuario); $tabla_preferencias = $config['tabla']; - $tipos_validos = $config['tipos_validos']; + $tipos_validos = $config['tipos_validos']; // Validar que el tipo de notificación es válido para este tipo de usuario if (!in_array($tipo_nombre, $tipos_validos)) { @@ -463,7 +464,7 @@ function guardarPreferenciasAjax() // Verificar que las notificaciones generales estén activadas $query_check = "SELECT notificaciones FROM usuarios_sistema WHERE id_usuario = ?"; - $stmt_check = sqlsrv_prepare($conn, $query_check, [$id_usuario]); + $stmt_check = sqlsrv_prepare($conn, $query_check, [$id_usuario]); if ($stmt_check && sqlsrv_execute($stmt_check)) { $row = sqlsrv_fetch_array($stmt_check, SQLSRV_FETCH_ASSOC); sqlsrv_free_stmt($stmt_check); @@ -477,10 +478,11 @@ function guardarPreferenciasAjax() // Verificar si existe el registro $query_exists = "SELECT COUNT(*) as count FROM $tabla_preferencias WHERE id_usuario = ?"; - $stmt_exists = sqlsrv_prepare($conn, $query_exists, [$id_usuario]); + $stmt_exists = sqlsrv_prepare($conn, $query_exists, [$id_usuario]); + $exists = false; if ($stmt_exists && sqlsrv_execute($stmt_exists)) { - $row = sqlsrv_fetch_array($stmt_exists, SQLSRV_FETCH_ASSOC); + $row = sqlsrv_fetch_array($stmt_exists, SQLSRV_FETCH_ASSOC); $exists = $row['count'] > 0; sqlsrv_free_stmt($stmt_exists); } @@ -488,7 +490,7 @@ function guardarPreferenciasAjax() if ($exists) { // Actualizar el campo específico $query = "UPDATE $tabla_preferencias SET [$tipo_nombre] = ? WHERE id_usuario = ?"; - $stmt = sqlsrv_prepare($conn, $query, [$valor, $id_usuario]); + $stmt = sqlsrv_prepare($conn, $query, [$valor, $id_usuario]); } else { // Crear registro con valores por defecto específicos del tipo de usuario $tipos_default = $config['valores_default']; @@ -496,12 +498,12 @@ function guardarPreferenciasAjax() // Establecer el valor específico $tipos_default[$tipo_nombre] = $valor; - $campos = '[' . implode('], [', array_keys($tipos_default)) . ']'; + $campos = '[' . implode('], [', array_keys($tipos_default)) . ']'; $placeholders = rtrim(str_repeat('?, ', count($tipos_default)), ', '); - $query = "INSERT INTO $tabla_preferencias (id_usuario, $campos) VALUES (?, $placeholders)"; + $query = "INSERT INTO $tabla_preferencias (id_usuario, $campos) VALUES (?, $placeholders)"; $params = array_merge([$id_usuario], array_values($tipos_default)); - $stmt = sqlsrv_prepare($conn, $query, $params); + $stmt = sqlsrv_prepare($conn, $query, $params); } if (!$stmt || !sqlsrv_execute($stmt)) { @@ -577,7 +579,7 @@ function guardarPreferenciasAjax() $stmt = sqlsrv_prepare($conn, $query, [$hora, $dias, $id_usuario]); } else { // Crear registro con valores por defecto específicos del tipo de usuario - $config = getConfiguracionTipoUsuario($tipo_usuario); + $config = getConfiguracionTipoUsuario($tipo_usuario); $tipos_default = $config['valores_default']; // Activar resumen diario y configurar hora/días @@ -755,20 +757,24 @@ function getConfiguracionTipoUsuario($tipo_usuario) { // Función auxiliar para obtener el correo extra de un usuario (útil para el sistema de notificaciones) function obtenerCorreoExtra($id_usuario) { - $conn = getConnection(); - $query = " - SELECT ce.correo - FROM correo_extra ce - INNER JOIN usuarios_sistema us ON ce.id_usuario = us.id_usuario - WHERE ce.id_usuario = ? AND us.notificaciones_extra = 1 - "; + $conn = getConnection(); + + $query = "SELECT ce.correo + FROM correo_extra ce + INNER JOIN usuarios_sistema us + ON ce.id_usuario = us.id_usuario + WHERE ce.id_usuario = ? + AND us.notificaciones_extra = 1 + "; $stmt = sqlsrv_prepare($conn, $query, [$id_usuario]); + $correo = null; if ($stmt && sqlsrv_execute($stmt)) { $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); $correo = $row ? $row['correo'] : null; sqlsrv_free_stmt($stmt); } + sqlsrv_close($conn); return $correo; } @@ -781,10 +787,12 @@ function obtenerPreferenciasNotificacion($id_usuario) // Obtener configuración general $query = "SELECT notificaciones, notificaciones_extra FROM usuarios_sistema WHERE id_usuario = ?"; $stmt = sqlsrv_prepare($conn, $query, [$id_usuario]); + if (!$stmt || !sqlsrv_execute($stmt)) { sqlsrv_close($conn); return null; } + $config = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); sqlsrv_free_stmt($stmt); @@ -796,6 +804,7 @@ function obtenerPreferenciasNotificacion($id_usuario) // Obtener preferencias específicas $query = "SELECT * FROM preferencias_notificaciones_usuario WHERE id_usuario = ?"; $stmt = sqlsrv_prepare($conn, $query, [$id_usuario]); + $preferencias = null; if ($stmt && sqlsrv_execute($stmt)) { $preferencias = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); @@ -843,18 +852,20 @@ function debeRecibirNotificacion($id_usuario, $tipo_notificacion) // Función auxiliar para obtener la configuración del resumen diario de un usuario function obtenerConfigResumenDiario($id_usuario) { - $conn = getConnection(); - - $query = " - SELECT pnu.resumen_diario, pnu.resumen_diario_hora, pnu.resumen_diario_dias - FROM preferencias_notificaciones_usuario pnu - INNER JOIN usuarios_sistema us ON pnu.id_usuario = us.id_usuario - WHERE pnu.id_usuario = ? AND us.notificaciones = 1 AND pnu.resumen_diario = 1 - "; + $conn = getConnection(); + $query = "SELECT + pnu.resumen_diario, pnu.resumen_diario_hora, pnu.resumen_diario_dias + FROM preferencias_notificaciones_usuario pnu + INNER JOIN usuarios_sistema us + ON pnu.id_usuario = us.id_usuario + WHERE pnu.id_usuario = ? + AND us.notificaciones = 1 + AND pnu.resumen_diario = 1 + "; $stmt = sqlsrv_prepare($conn, $query, [$id_usuario]); + $config = null; - if ($stmt && sqlsrv_execute($stmt)) { $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); if ($row) { @@ -890,7 +901,8 @@ function esDiaResumen($config_dias) function catalogos() { - $conn = getConnection(); + $conn = getConnection(); + $idUsuario = $_SESSION['usuario_id'] ?? null; if (!$idUsuario) { @@ -901,16 +913,18 @@ function catalogos() // Obtener configuración general de catalogos y tipo de usuario $query = "SELECT preferencias_catalogos, tipo_usuario FROM usuarios_sistema WHERE id_usuario = ?"; $stmt = sqlsrv_prepare($conn, $query, [$idUsuario]); + if (!$stmt || !sqlsrv_execute($stmt)) { die("Error al obtener configuración: " . print_r(sqlsrv_errors(), true)); } + $usuario = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); if (!$usuario) { die("Usuario no encontrado"); } $catalogos = $usuario['preferencias_catalogos'] ?? 0; - $tipoUsuario = $usuario['tipo_usuario'] ?? 'importador'; + $tipoUsuario = $usuario['tipo_usuario'] ?? 'importador'; sqlsrv_free_stmt($stmt); // Obtener preferencias específicas según el tipo de usuario @@ -949,22 +963,22 @@ function catalogos() // $query = "SELECT * FROM preferencias_catalogos_agente WHERE id_usuario = ?"; // $stmt = sqlsrv_prepare($conn, $query, [$idUsuario]); // if ($stmt && sqlsrv_execute($stmt)) { - // $preferenciasRow = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); - // sqlsrv_free_stmt($stmt); + // $preferenciasRow = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); + // sqlsrv_free_stmt($stmt); // } else { - // $preferenciasRow = false; + // $preferenciasRow = false; // } // Si no existe registro, crear valores por defecto para agente aduanal // if (!$preferenciasRow) { - // $preferencias = [ - // Aquí se definirán los campos específicos para agente aduanal - // cuando se creen las tablas correspondientes - // 'configuracion' => 0, - // 'cerrar_sesion' => 0 - // ]; + // $preferencias = [ + // // Aquí se definirán los campos específicos para agente aduanal + // // cuando se creen las tablas correspondientes + // 'configuracion' => 0, + // 'cerrar_sesion' => 0 + // ]; // } else { - // $preferencias = $preferenciasRow; + // $preferencias = $preferenciasRow; // } // break; @@ -972,22 +986,22 @@ function catalogos() // $query = "SELECT * FROM preferencias_catalogos_agencia WHERE id_usuario = ?"; // $stmt = sqlsrv_prepare($conn, $query, [$idUsuario]); // if ($stmt && sqlsrv_execute($stmt)) { - // $preferenciasRow = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); - // sqlsrv_free_stmt($stmt); + // $preferenciasRow = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); + // sqlsrv_free_stmt($stmt); // } else { - // $preferenciasRow = false; + // $preferenciasRow = false; // } // Si no existe registro, crear valores por defecto para admin agencia // if (!$preferenciasRow) { - // $preferencias = [ - // Aquí se definirán los campos específicos para admin agencia - // cuando se creen las tablas correspondientes - // 'configuracion' => 0, - // 'cerrar_sesion' => 0 - // ]; + // $preferencias = [ + // // Aquí se definirán los campos específicos para admin agencia + // // cuando se creen las tablas correspondientes + // 'configuracion' => 0, + // 'cerrar_sesion' => 0 + // ]; // } else { - // $preferencias = $preferenciasRow; + // $preferencias = $preferenciasRow; // } // break; @@ -995,22 +1009,22 @@ function catalogos() // $query = "SELECT * FROM preferencias_catalogos_admin WHERE id_usuario = ?"; // $stmt = sqlsrv_prepare($conn, $query, [$idUsuario]); // if ($stmt && sqlsrv_execute($stmt)) { - // $preferenciasRow = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); - // sqlsrv_free_stmt($stmt); + // $preferenciasRow = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); + // sqlsrv_free_stmt($stmt); // } else { - // $preferenciasRow = false; + // $preferenciasRow = false; // } // Si no existe registro, crear valores por defecto para super admin // if (!$preferenciasRow) { - // $preferencias = [ - // Aquí se definirán los campos específicos para super admin - // cuando se creen las tablas correspondientes - // 'configuracion' => 0, - // 'cerrar_sesion' => 0 - // ]; + // $preferencias = [ + // // Aquí se definirán los campos específicos para super admin + // // cuando se creen las tablas correspondientes + // 'configuracion' => 0, + // 'cerrar_sesion' => 0 + // ]; // } else { - // $preferencias = $preferenciasRow; + // $preferencias = $preferenciasRow; // } // break; @@ -1026,6 +1040,7 @@ function catalogos() // Obtener tipos de catalogos disponibles según el tipo de usuario $query = "SELECT nombre, descripcion, color FROM tipos_catalogos WHERE tipo_usuario = ? ORDER BY id"; $stmt = sqlsrv_prepare($conn, $query, [$tipoUsuario]); + if (!$stmt || !sqlsrv_execute($stmt)) { die("Error al obtener tipos: " . print_r(sqlsrv_errors(), true)); } @@ -1063,7 +1078,8 @@ function guardarCatalogosAjax() exit; } - $conn = getConnection(); + $conn = getConnection(); + $idUsuario = $_SESSION['usuario_id'] ?? null; if (!$idUsuario) { @@ -1075,11 +1091,13 @@ function guardarCatalogosAjax() // Obtener tipo de usuario $query = "SELECT tipo_usuario FROM usuarios_sistema WHERE id_usuario = ?"; $stmt = sqlsrv_prepare($conn, $query, [$idUsuario]); + if (!$stmt || !sqlsrv_execute($stmt)) { http_response_code(500); echo json_encode(['success' => false, 'message' => 'Error al obtener información del usuario']); exit; } + $usuario = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); $tipoUsuario = $usuario['tipo_usuario'] ?? 'importador'; sqlsrv_free_stmt($stmt); @@ -1091,13 +1109,13 @@ function guardarCatalogosAjax() case 'catalogos_general': // Actualizar preferencias generales de catálogos $valor = isset($input['valor']) && $input['valor'] ? 1 : 0; - $query = "UPDATE usuarios_sistema SET preferencias_catalogos = ? WHERE id_usuario = ?"; $stmt = sqlsrv_prepare($conn, $query, [$valor, $idUsuario]); if (!$stmt || !sqlsrv_execute($stmt)) { throw new Exception('Error al actualizar preferencias generales'); } + sqlsrv_free_stmt($stmt); break; @@ -1132,6 +1150,7 @@ function guardarCatalogosAjax() // Verificar si existe un registro para este usuario $query = "SELECT id_preferencia FROM $tabla WHERE id_usuario = ?"; $stmt = sqlsrv_prepare($conn, $query, [$idUsuario]); + if (!$stmt || !sqlsrv_execute($stmt)) { throw new Exception('Error al verificar preferencias existentes'); } diff --git a/app/controllers/productos_frecuentes.php b/app/controllers/productos_frecuentes.php index 85de855..9bf9a34 100644 --- a/app/controllers/productos_frecuentes.php +++ b/app/controllers/productos_frecuentes.php @@ -1,6 +1,4 @@ []]; @@ -93,6 +90,7 @@ function lista() header('Location: /IMPORTADORES/login'); exit; } + include __DIR__ . '/../../views/productos_frecuentes/lista.php'; } @@ -100,11 +98,11 @@ function lista() * Muestra el formulario de creación **/ function alta() { - if (empty($_SESSION['usuario_id'])) { header('Location: /IMPORTADORES/login'); exit; } + include __DIR__ . '/../../views/productos_frecuentes/alta.php'; } @@ -112,7 +110,6 @@ function alta() * Procesa alta de producto frecuente **/ function guardar() { - if (empty($_SESSION['usuario_id'])) { header('Location: /IMPORTADORES/login'); exit; @@ -121,29 +118,29 @@ function guardar() $conn = getConnection(); // Recoger y sanear - $sinonimo = trim($_POST['sinonimo'] ?? ''); - $fraccion = trim($_POST['fraccion'] ?? ''); - $nico = trim($_POST['nico'] ?? ''); - $numero_parte = trim($_POST['numero_parte'] ?? null); - $descripcion = trim($_POST['descripcion'] ?? null); - $umc_id = intval($_POST['umc_id'] ?? 0); - $pais_origen_destino = trim($_POST['pais_origen_destino'] ?? null); + $sinonimo = trim($_POST['sinonimo'] ?? ''); + $fraccion = trim($_POST['fraccion'] ?? ''); + $nico = trim($_POST['nico'] ?? ''); + $numero_parte = trim($_POST['numero_parte'] ?? null); + $descripcion = trim($_POST['descripcion'] ?? null); + $umc_id = intval($_POST['umc_id'] ?? 0); + $pais_origen_destino = trim($_POST['pais_origen_destino'] ?? null); $pais_comprador_vendedor = trim($_POST['pais_comprador_vendedor'] ?? null); - $uso_mercancia = trim($_POST['uso_mercancia'] ?? null); - $estado_mercancia = trim($_POST['estado_mercancia'] ?? null); - $vinculacion = trim($_POST['vinculacion'] ?? null); - $observaciones = trim($_POST['observaciones'] ?? null); - $preferencia = trim($_POST['preferencia'] ?? null); - $criterio_preferencia = trim($_POST['criterio_preferencia'] ?? null); - $uso_producto = trim($_POST['uso_producto'] ?? null); - $descripcion_producto = trim($_POST['descripcion_producto'] ?? null); - $certificado_origen = isset($_POST['certificado_origen']) ? 1 : 0; - $tipo_mercancia = trim($_POST['tipo_mercancia'] ?? null); + $uso_mercancia = trim($_POST['uso_mercancia'] ?? null); + $estado_mercancia = trim($_POST['estado_mercancia'] ?? null); + $vinculacion = trim($_POST['vinculacion'] ?? null); + $observaciones = trim($_POST['observaciones'] ?? null); + $preferencia = trim($_POST['preferencia'] ?? null); + $criterio_preferencia = trim($_POST['criterio_preferencia'] ?? null); + $uso_producto = trim($_POST['uso_producto'] ?? null); + $descripcion_producto = trim($_POST['descripcion_producto'] ?? null); + $certificado_origen = isset($_POST['certificado_origen']) ? 1 : 0; + $tipo_mercancia = trim($_POST['tipo_mercancia'] ?? null); $documento_en_original = isset($_POST['documento_en_original']) ? 1 : 0; - $proveedor = trim($_POST['proveedor'] ?? null); + $proveedor = trim($_POST['proveedor'] ?? null); $id_importador = intval($_SESSION['usuario_id']); $status = 1; - $frecuencia_uso = intval($_POST['frecuencia_uso'] ?? 1); + $frecuencia_uso = intval($_POST['frecuencia_uso'] ?? 1); // Validación mínima if ($sinonimo === '' || $fraccion === '' || $nico === '' || $umc_id <= 0) { @@ -153,41 +150,22 @@ function guardar() } // INSERT - $sql = " - INSERT INTO dbo.productos_frecuentes ( - sinonimo, fraccion, nico, numero_parte, - descripcion, umc_id, - pais_origen_destino, pais_comprador_vendedor, - uso_mercancia, estado_mercancia, vinculacion, - observaciones, preferencia, criterio_preferencia, - uso_producto, descripcion_producto, - certificado_origen, tipo_mercancia, - documento_en_original, proveedor, - id_importador, fecha_alta, status, frecuencia_uso - ) VALUES ( - ?,?,?,?, - ?,?, - ?,?, - ?,?,?, - ?,?,?, - ?,?, - ?,?, - ?,?, - ?,GETDATE(),?,? - ) - "; + $sql = "INSERT INTO dbo.productos_frecuentes + (sinonimo, fraccion, nico, numero_parte, descripcion, umc_id, + pais_origen_destino, pais_comprador_vendedor, uso_mercancia, estado_mercancia, vinculacion, + observaciones, preferencia, criterio_preferencia, uso_producto, descripcion_producto, + certificado_origen, tipo_mercancia, documento_en_original, proveedor, + id_importador, fecha_alta, status, frecuencia_uso) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, GETDATE(), ?, ?) + "; $params = [ - $sinonimo, $fraccion, $nico, $numero_parte, - $descripcion, $umc_id, - $pais_origen_destino, $pais_comprador_vendedor, - $uso_mercancia, $estado_mercancia, $vinculacion, - $observaciones, $preferencia, $criterio_preferencia, - $uso_producto, $descripcion_producto, - $certificado_origen, $tipo_mercancia, - $documento_en_original, $proveedor, - $id_importador, $status, $frecuencia_uso - ]; - $stmt = sqlsrv_query($conn, $sql, $params); + $sinonimo, $fraccion, $nico, $numero_parte, $descripcion, $umc_id, + $pais_origen_destino, $pais_comprador_vendedor, $uso_mercancia, $estado_mercancia, $vinculacion, + $observaciones, $preferencia, $criterio_preferencia, $uso_producto, $descripcion_producto, + $certificado_origen, $tipo_mercancia, $documento_en_original, $proveedor, + $id_importador, $status, $frecuencia_uso + ]; + $stmt = sqlsrv_query($conn, $sql, $params); if ($stmt === false) { $_SESSION['flash_error'] = 'Error al guardar el producto frecuente.'; @@ -204,21 +182,23 @@ function guardar() * Muestra el formulario de edición **/ function editar() { - if (empty($_SESSION['usuario_id'])) { header('Location: /IMPORTADORES/login'); exit; } $id = intval($_GET['id'] ?? 0); + if ($id <= 0) { header('Location: /IMPORTADORES/productos_frecuentes'); exit; } $conn = getConnection(); - $sql = "SELECT * FROM dbo.productos_frecuentes WHERE id_producto_frecuente = ?"; + + $sql = "SELECT * FROM dbo.productos_frecuentes WHERE id_producto_frecuente = ?"; $stmt = sqlsrv_query($conn, $sql, [$id]); + if ($stmt === false || ($producto = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) === null) { $_SESSION['flash_error'] = 'Producto frecuente no encontrado.'; header('Location: /IMPORTADORES/productos_frecuentes'); @@ -232,42 +212,30 @@ function editar() * Procesa la actualización **/ function actualizar() { - session_start(); if (empty($_SESSION['usuario_id'])) { header('Location: /IMPORTADORES/login'); exit; } - $id = intval($_POST['id_producto_frecuente'] ?? 0); - $sinonimo = trim($_POST['sinonimo'] ?? ''); - // ... (resto de campos idénticos a guardar) - // Validaciones similares... - // UPDATE ... $conn = getConnection(); - $sql = " - UPDATE dbo.productos_frecuentes SET - sinonimo = ?, fraccion = ?, nico = ?, numero_parte = ?, - descripcion = ?, umc_id = ?, - pais_origen_destino = ?, pais_comprador_vendedor = ?, - uso_mercancia = ?, estado_mercancia = ?, vinculacion = ?, - observaciones = ?, preferencia = ?, criterio_preferencia = ?, - uso_producto = ?, descripcion_producto = ?, - certificado_origen = ?, tipo_mercancia = ?, - documento_en_original = ?, proveedor = ? - WHERE id_producto_frecuente = ? - "; + + $id = intval($_POST['id_producto_frecuente'] ?? 0); + $sinonimo = trim($_POST['sinonimo'] ?? ''); + + $sql = "UPDATE dbo.productos_frecuentes SET + sinonimo = ?, fraccion = ?, nico = ?, numero_parte = ?, descripcion = ?, umc_id = ?, + pais_origen_destino = ?, pais_comprador_vendedor = ?, uso_mercancia = ?, estado_mercancia = ?, vinculacion = ?, + observaciones = ?, preferencia = ?, criterio_preferencia = ?, uso_producto = ?, descripcion_producto = ?, + certificado_origen = ?, tipo_mercancia = ?, documento_en_original = ?, proveedor = ? + WHERE id_producto_frecuente = ? + "; $params = [ - $sinonimo, $fraccion, $nico, $numero_parte, - $descripcion, $umc_id, - $pais_origen_destino, $pais_comprador_vendedor, - $uso_mercancia, $estado_mercancia, $vinculacion, - $observaciones, $preferencia, $criterio_preferencia, - $uso_producto, $descripcion_producto, - $certificado_origen, $tipo_mercancia, - $documento_en_original, $proveedor, - $id - ]; - $stmt = sqlsrv_query($conn, $sql, $params); + $sinonimo, $fraccion, $nico, $numero_parte, $descripcion, $umc_id, + $pais_origen_destino, $pais_comprador_vendedor, $uso_mercancia, $estado_mercancia, $vinculacion, + $observaciones, $preferencia, $criterio_preferencia, $uso_producto, $descripcion_producto, + $certificado_origen, $tipo_mercancia, $documento_en_original, $proveedor, $id + ]; + $stmt = sqlsrv_query($conn, $sql, $params); if ($stmt === false) { $_SESSION['flash_error'] = 'Error al actualizar el producto frecuente.'; @@ -300,6 +268,7 @@ function ajax_unidades() } $conn = getConnection(); + $sql = "SELECT id, descripcion FROM dbo.unidades_medida_apendice7 ORDER BY descripcion"; $stmt = sqlsrv_query($conn, $sql); @@ -332,7 +301,9 @@ function procesar_csv() } $file = fopen($_FILES['csv_file']['tmp_name'], 'r'); + $conn = getConnection(); + $row = 0; while (($data = fgetcsv($file, 0, ',')) !== false) { $row++; diff --git a/app/controllers/proveedores.php b/app/controllers/proveedores.php index 69f4cf6..b8292f4 100644 --- a/app/controllers/proveedores.php +++ b/app/controllers/proveedores.php @@ -1,13 +1,11 @@ $user, 'password' => $pass]); error_log("[getApiToken] POST $url → $body"); @@ -120,24 +118,24 @@ function ajax_lista() // Construir dirección $direccion = trim(implode(', ', array_filter([ - $p['Calles'] ?? '', - 'Num. Ext: ' . ($p['NumExt'] ?? ''), - 'Num. Int: ' . ($p['NumInt'] ?? ''), - $p['Colonia'] ?? '', - $p['Municipio'] ?? '', - $p['Ciudad'] ?? '', + $p['Calles'] ?? '', + 'Num. Ext: ' . ($p['NumExt'] ?? ''), + 'Num. Int: ' . ($p['NumInt'] ?? ''), + $p['Colonia'] ?? '', + $p['Municipio'] ?? '', + $p['Ciudad'] ?? '', 'C.P. ' . ($p['CodigoPostal'] ?? ''), - $p['EntidadFederativa'] ?? '', - $p['Pais'] ?? '' + $p['EntidadFederativa'] ?? '', + $p['Pais'] ?? '' ]))); $dataList[] = [ $clave, - htmlspecialchars($p['Nombre'] ?? '', ENT_QUOTES), - htmlspecialchars($p['RFC'] ?? '', ENT_QUOTES), - htmlspecialchars($p['Ciudad'] ?? '', ENT_QUOTES), - htmlspecialchars($p['Telefono']?? '', ENT_QUOTES), - htmlspecialchars($direccion ?? '', ENT_QUOTES), + htmlspecialchars($p['Nombre'] ?? '', ENT_QUOTES), + htmlspecialchars($p['RFC'] ?? '', ENT_QUOTES), + htmlspecialchars($p['Ciudad'] ?? '', ENT_QUOTES), + htmlspecialchars($p['Telefono'] ?? '', ENT_QUOTES), + htmlspecialchars($direccion ?? '', ENT_QUOTES), // Acciones "✏️ " @@ -157,6 +155,7 @@ function eliminar() { $token = getApiToken(); $clave = $_GET['clave'] ?? ''; + if (!$token || !$clave) { header('Location: /IMPORTADORES/proveedores'); exit; @@ -204,16 +203,16 @@ function guardar() // 2) Recoger datos del formulario $payload = [ - 'Clave' => trim($_POST['Clave'] ?? ''), - 'Nombre' => trim($_POST['Nombre'] ?? ''), - 'RFC' => trim($_POST['RFC'] ?? ''), - 'Ciudad' => trim($_POST['Ciudad'] ?? ''), - 'Telefono' => trim($_POST['Telefono'] ?? ''), - 'Pais' => trim($_POST['Pais'] ?? ''), - 'Colonia' => trim($_POST['Colonia'] ?? ''), - 'Municipio' => trim($_POST['Municipio'] ?? ''), - 'CodigoPostal' => trim($_POST['CodigoPostal'] ?? ''), - 'EntidadFederativa' => trim($_POST['EntidadFederativa'] ?? ''), + 'Clave' => trim($_POST['Clave'] ?? ''), + 'Nombre' => trim($_POST['Nombre'] ?? ''), + 'RFC' => trim($_POST['RFC'] ?? ''), + 'Ciudad' => trim($_POST['Ciudad'] ?? ''), + 'Telefono' => trim($_POST['Telefono'] ?? ''), + 'Pais' => trim($_POST['Pais'] ?? ''), + 'Colonia' => trim($_POST['Colonia'] ?? ''), + 'Municipio' => trim($_POST['Municipio'] ?? ''), + 'CodigoPostal' => trim($_POST['CodigoPostal'] ?? ''), + 'EntidadFederativa' => trim($_POST['EntidadFederativa'] ?? ''), ]; // 3) Validar campos obligatorios @@ -233,7 +232,7 @@ function guardar() // 5) Llamada a la API para crear el proveedor $url = rtrim($_ENV['API_URL'] ?? '', '/') . '/api/proveedores'; - $ch = curl_init($url); + $ch = curl_init($url); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ diff --git a/app/controllers/registro.php b/app/controllers/registro.php index cf07584..c56f2a2 100644 --- a/app/controllers/registro.php +++ b/app/controllers/registro.php @@ -149,6 +149,7 @@ function enviarEmailConfirmacion($destinatario, $datosEmpresa, $esAgencia = fals // Obtener configuración $conn = getConnection(); + $conf = obtenerConfiguracion($conn); $nombrePlataforma = $conf['nombre_plataforma']; @@ -228,10 +229,10 @@ function enviarSoliImportador() $rfcEncriptado = encrypt(strtoupper($rfc)); // Insertar en base de datos - $sql = "INSERT INTO solicitudes_importadores - (company_name, rfc, email, phone, opinion_file, request_status, request_date) - VALUES (?, ?, ?, ?, ?, 'pending', GETDATE())"; - + $sql = "INSERT INTO solicitudes_importadores + (company_name, rfc, email, phone, opinion_file, request_status, request_date) + VALUES (?, ?, ?, ?, ?, 'pending', GETDATE()) + "; $params = [$empresaEncriptada, $rfcEncriptado, $email, $telefono, $nombreArchivo]; $stmt = sqlsrv_query($conn, $sql, $params); @@ -289,10 +290,10 @@ function enviarSoliAgencia() $adminEncriptado = encrypt($admin); // Insertar en base de datos - $sql = "INSERT INTO solicitudes_agencias - (agencia_name, rfc, email, phone, direccion, opinion_file, admin_name, admin_email, request_status, request_date) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'pending', GETDATE())"; - + $sql = "INSERT INTO solicitudes_agencias + (agencia_name, rfc, email, phone, direccion, opinion_file, admin_name, admin_email, request_status, request_date) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'pending', GETDATE()) + "; $params = [$agenciaEncriptada, $rfcEncriptado, $correo, $telefono, $direccion, $nombreArchivo, $adminEncriptado, $admin_correo]; $stmt = sqlsrv_query($conn, $sql, $params); diff --git a/app/controllers/reset.php b/app/controllers/reset.php index f905525..bee438c 100644 --- a/app/controllers/reset.php +++ b/app/controllers/reset.php @@ -4,8 +4,8 @@ require_once __DIR__ . '/../../config/database.php'; require_once __DIR__ . '/../helpers/crypto.php'; require_once __DIR__ . '/../helpers/bitacoras.php'; require_once __DIR__ . '/../helpers/env.php'; - require_once __DIR__ . '/../../vendor/autoload.php'; + use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception; @@ -22,17 +22,18 @@ function enviarCodigoInterno() } $conn = getConnection(); + if (!$conn) { echo json_encode(['success' => false, 'message' => '❌ Error de conexión con la base de datos.']); exit; } - $id_usuario = $_SESSION['usuario_id']; - $email = $_SESSION['usuario_email']; + $id_usuario = $_SESSION['usuario_id']; + $email = $_SESSION['usuario_email']; $emailEncrypted = encrypt($email); // Verificar que la cuenta esté activa - $sql = "SELECT activo FROM usuarios_sistema WHERE id_usuario = ?"; + $sql = "SELECT activo FROM usuarios_sistema WHERE id_usuario = ?"; $stmt = sqlsrv_query($conn, $sql, [$id_usuario]); if (!$stmt || !($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC))) { @@ -46,11 +47,10 @@ function enviarCodigoInterno() } // Verificar si ya existe un código activo - $now = (new DateTime())->format('Y-m-d H:i:s'); - $sqlCheck = "SELECT COUNT(*) AS total FROM recuperacion_password - WHERE email = ? AND estatus = 0 AND expiracion > ?"; + $now = (new DateTime())->format('Y-m-d H:i:s'); + $sqlCheck = "SELECT COUNT(*) AS total FROM recuperacion_password WHERE email = ? AND estatus = 0 AND expiracion > ?"; $checkStmt = sqlsrv_query($conn, $sqlCheck, [$emailEncrypted, $now]); - $checkRow = sqlsrv_fetch_array($checkStmt, SQLSRV_FETCH_ASSOC); + $checkRow = sqlsrv_fetch_array($checkStmt, SQLSRV_FETCH_ASSOC); if ($checkRow['total'] > 0) { echo json_encode(['success' => false, 'message' => '⚠️ Ya tienes un código activo. Revisa tu correo o espera 10 minutos.']); @@ -58,8 +58,8 @@ function enviarCodigoInterno() } // Generar nuevo código - $codigo = strval(random_int(100000, 999999)); - $expira = (new DateTime('+10 minutes'))->format('Y-m-d H:i:s'); + $codigo = strval(random_int(100000, 999999)); + $expira = (new DateTime('+10 minutes'))->format('Y-m-d H:i:s'); $estatus = 0; $insert = "INSERT INTO recuperacion_password (email, codigo, expiracion, estatus) VALUES (?, ?, ?, ?)"; @@ -72,7 +72,7 @@ function enviarCodigoInterno() } // Establecer variables de sesión para el cambio interno - $_SESSION['cambio_interno'] = true; + $_SESSION['cambio_interno'] = true; $_SESSION['codigo_timestamp'] = time(); // Agregar estos logs: @@ -143,6 +143,7 @@ function reenviarCodigoInterno() } $conn = getConnection(); + if (!$conn) { echo json_encode(['success' => false, 'message' => '❌ Error de conexión con la base de datos.']); exit; @@ -153,9 +154,7 @@ function reenviarCodigoInterno() // Obtener el último código activo de recuperación $now = (new DateTime())->format('Y-m-d H:i:s'); - $sql = "SELECT TOP 1 codigo FROM recuperacion_password - WHERE email = ? AND estatus = 0 AND expiracion > ? - ORDER BY expiracion DESC"; + $sql = "SELECT TOP 1 codigo FROM recuperacion_password WHERE email = ? AND estatus = 0 AND expiracion > ? ORDER BY expiracion DESC"; $stmt = sqlsrv_query($conn, $sql, [$emailEncrypted, $now]); if (!$stmt || !($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC))) { @@ -167,7 +166,7 @@ function reenviarCodigoInterno() // Llamar a la función para reenviar el correo al respaldo if (enviarCorreoRespaldo($conn, $id_usuario, $codigo)) { - echo json_encode(['success' => true, 'message' => '📤 Código reenviado al correo de respaldo.']); + echo json_encode(['success' => true, 'message' => '📤 Código reenviado al correo de respaldo.']); } else { echo json_encode(['success' => false, 'message' => '❌ Error al reenviar el código al correo de respaldo.']); } @@ -261,15 +260,15 @@ function verificarCodigoInterno() $conn = getConnection(); - $email = $_SESSION['usuario_email']; + $email = $_SESSION['usuario_email']; $emailEncrypted = encrypt($email); // aplica aquí también try { // Verificar conexión if (!isset($conn) || $conn === false) { echo json_encode([ - 'success' => false, - 'message' => '❌ Error de conexión a la base de datos.', + 'success' => false, + 'message' => '❌ Error de conexión a la base de datos.', 'intentos_restantes' => max(0, 3 - ($_SESSION['intentos_codigo_interno'] ?? 0)) ]); exit; @@ -279,8 +278,8 @@ function verificarCodigoInterno() if (empty($codigo)) { echo json_encode([ - 'success' => false, - 'message' => '❌ Código requerido.', + 'success' => false, + 'message' => '❌ Código requerido.', 'intentos_restantes' => max(0, 3 - ($_SESSION['intentos_codigo_interno'] ?? 0)) ]); exit; @@ -288,8 +287,8 @@ function verificarCodigoInterno() if (!preg_match('/^\d{6}$/', $codigo)) { echo json_encode([ - 'success' => false, - 'message' => '❌ El código debe tener 6 dígitos numéricos.', + 'success' => false, + 'message' => '❌ El código debe tener 6 dígitos numéricos.', 'intentos_restantes' => max(0, 3 - ($_SESSION['intentos_codigo_interno'] ?? 0)) ]); exit; @@ -299,10 +298,10 @@ function verificarCodigoInterno() if ($intentosActuales >= 3) { echo json_encode([ - 'success' => false, - 'message' => '❌ Demasiados intentos fallidos. Solicita un nuevo código.', - 'blocked' => true, - 'redirect' => '/IMPORTADORES/seguridad/index', + 'success' => false, + 'message' => '❌ Demasiados intentos fallidos. Solicita un nuevo código.', + 'blocked' => true, + 'redirect' => '/IMPORTADORES/seguridad/index', 'intentos_restantes' => 0 ]); exit; @@ -310,21 +309,23 @@ function verificarCodigoInterno() if (!isset($_SESSION['usuario_id']) || !isset($_SESSION['usuario_email'])) { echo json_encode([ - 'success' => false, - 'message' => '❌ Sesión inválida. Intenta nuevamente.', - 'blocked' => true, + 'success' => false, + 'message' => '❌ Sesión inválida. Intenta nuevamente.', + 'blocked' => true, 'redirect' => '/IMPORTADORES/seguridad/index' ]); exit; } // Consulta principal para verificar el código - $sql = "SELECT id, codigo, expiracion + $sql = "SELECT + id, codigo, expiracion FROM recuperacion_password - WHERE email = ? AND estatus = 0 AND expiracion > GETDATE() + WHERE email = ? + AND estatus = 0 + AND expiracion > GETDATE() ORDER BY expiracion DESC "; - $stmt = sqlsrv_query($conn, $sql, [$emailEncrypted]); if (!$stmt) { @@ -337,8 +338,8 @@ function verificarCodigoInterno() if (!$row) { $_SESSION['intentos_codigo_interno'] = $intentosActuales + 1; echo json_encode([ - 'success' => false, - 'message' => '❌ Código inválido o expirado.', + 'success' => false, + 'message' => '❌ Código inválido o expirado.', 'intentos_restantes' => max(0, 3 - $_SESSION['intentos_codigo_interno']) ]); exit; @@ -351,15 +352,15 @@ function verificarCodigoInterno() if ($codigo !== $row['codigo']) { $_SESSION['intentos_codigo_interno'] = $intentosActuales + 1; echo json_encode([ - 'success' => false, - 'message' => '❌ Código incorrecto.', + 'success' => false, + 'message' => '❌ Código incorrecto.', 'intentos_restantes' => max(0, 3 - $_SESSION['intentos_codigo_interno']) ]); exit; } $expiracion = $row['expiracion']; - $ahora = new DateTime(); + $ahora = new DateTime(); if ($expiracion instanceof DateTime) { $expiracionStr = $expiracion->format('Y-m-d H:i:s'); @@ -367,8 +368,8 @@ function verificarCodigoInterno() if ($expiracion <= $ahora) { $_SESSION['intentos_codigo_interno'] = $intentosActuales + 1; echo json_encode([ - 'success' => false, - 'message' => '❌ El código ha expirado.', + 'success' => false, + 'message' => '❌ El código ha expirado.', 'intentos_restantes' => max(0, 3 - $_SESSION['intentos_codigo_interno']) ]); exit; @@ -390,15 +391,15 @@ function verificarCodigoInterno() unset($_SESSION['intentos_codigo_interno']); echo json_encode([ - 'success' => true, - 'message' => '✅ Código verificado correctamente.', + 'success' => true, + 'message' => '✅ Código verificado correctamente.', 'redirect' => '/IMPORTADORES/reset/cambiarPasswordInternoView' ]); } catch (Exception $e) { echo json_encode([ - 'success' => false, - 'message' => '❌ Error interno del servidor. Intenta nuevamente.', + 'success' => false, + 'message' => '❌ Error interno del servidor. Intenta nuevamente.', 'intentos_restantes' => max(0, 3 - ($_SESSION['intentos_codigo_interno'] ?? 0)) ]); exit; @@ -413,7 +414,7 @@ function verificarCodigoInterno() function cambiarPasswordInternoView() { // Verificar si el usuario ya está autenticado y el código verificado - if (!isset($_SESSION['usuario_id']) || !isset($_SESSION['usuario_email']) || + if (!isset($_SESSION['usuario_id']) || !isset($_SESSION['usuario_email']) || !isset($_SESSION['cambio_interno']) || !isset($_SESSION['codigo_verificado_interno'])) { header("Location: /IMPORTADORES/login"); exit; @@ -425,23 +426,34 @@ function cambiarPasswordInternoView() function cambiarPasswordInterno() { + // Limpiar buffer de salida + if (ob_get_level()) { + ob_end_clean(); + } + + // Iniciar buffer limpio + ob_start(); + header('Content-Type: application/json'); // ⬅️ AGREGAR ESTA LÍNEA // Verificar autorización completa - if (!isset($_SESSION['usuario_id']) || !isset($_SESSION['usuario_email']) || + if (!isset($_SESSION['usuario_id']) || !isset($_SESSION['usuario_email']) || !isset($_SESSION['cambio_interno']) || !isset($_SESSION['codigo_verificado_interno'])) { + + ob_end_clean(); // Limpiar buffer antes de enviar JSON echo json_encode(['success' => false, 'message' => '❌ No tienes autorización para cambiar la contraseña.']); exit; } $conn = getConnection(); + if (!$conn) { echo json_encode(['success' => false, 'message' => '❌ Error de conexión con la base de datos.']); exit; } - $passwordActual = $_POST['password_actual'] ?? ''; - $passwordNueva = $_POST['password_nueva'] ?? ''; + $passwordActual = $_POST['password_actual'] ?? ''; + $passwordNueva = $_POST['password_nueva'] ?? ''; $confirmarPassword = $_POST['confirmar_password'] ?? ''; // Validaciones @@ -465,12 +477,12 @@ function cambiarPasswordInterno() exit; } - $id_usuario = $_SESSION['usuario_id']; - $email = $_SESSION['usuario_email']; + $id_usuario = $_SESSION['usuario_id']; + $email = $_SESSION['usuario_email']; $emailEncrypted = encrypt($email); // Verificar contraseña actual - $sql = "SELECT password_hash FROM usuarios_sistema WHERE id_usuario = ?"; + $sql = "SELECT password_hash FROM usuarios_sistema WHERE id_usuario = ?"; $stmt = sqlsrv_query($conn, $sql, [$id_usuario]); if (!$stmt || !($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC))) { @@ -484,8 +496,8 @@ function cambiarPasswordInterno() } // Actualizar contraseña - $hashNueva = password_hash($passwordNueva, PASSWORD_BCRYPT); - $sqlUpdate = "UPDATE usuarios_sistema SET password_hash = ? WHERE id_usuario = ?"; + $hashNueva = password_hash($passwordNueva, PASSWORD_BCRYPT); + $sqlUpdate = "UPDATE usuarios_sistema SET password_hash = ? WHERE id_usuario = ?"; $stmtUpdate = sqlsrv_prepare($conn, $sqlUpdate, [$hashNueva, $id_usuario]); if (!$stmtUpdate || !sqlsrv_execute($stmtUpdate)) { @@ -495,18 +507,18 @@ function cambiarPasswordInterno() // Registrar en bitácora $ip = $_SERVER['REMOTE_ADDR'] ?? 'N/A'; - registrarBitacora($conn, $id_usuario, $email, $ip, 1, 'Cambio de contraseña interno'); + registrarBitacora($id_usuario, $email, $ip, 1, 'Cambio de contraseña interno'); // Enviar correo de confirmación try { - $mail = new PHPMailer(true); + $mail = new PHPMailer(true); $mail->isSMTP(); - $mail->Host = 'secure.emailsrvr.com'; - $mail->SMTPAuth = true; - $mail->Username = 'noreply@aduanasoft.com.mx'; - $mail->Password = $_ENV['SMTP_PASS']; + $mail->Host = 'secure.emailsrvr.com'; + $mail->SMTPAuth = true; + $mail->Username = 'noreply@aduanasoft.com.mx'; + $mail->Password = $_ENV['SMTP_PASS']; $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; - $mail->Port = 587; + $mail->Port = 587; $mail->setFrom('noreply@aduanasoft.com.mx', 'SIIH | AduanaSoft'); $mail->addAddress($email); @@ -547,9 +559,11 @@ function cambiarPasswordInterno() unset($_SESSION['codigo_verificado_interno']); unset($_SESSION['codigo_timestamp']); + // Al final, antes de cada echo json_encode: + ob_end_clean(); echo json_encode([ - 'success' => true, - 'message' => '✅ Contraseña actualizada exitosamente.', + 'success' => true, + 'message' => '✅ Contraseña actualizada exitosamente.', 'redirect' => '/IMPORTADORES/login' // Redirigir a la página de seguridad ]); exit; @@ -565,8 +579,8 @@ function cancelarCambioInterno() if ($conn && isset($_SESSION['usuario_email'])) { // Invalidar códigos activos $emailEncrypted = encrypt($_SESSION['usuario_email']); - $sql = "UPDATE recuperacion_password SET estatus = 1 WHERE email = ? AND estatus = 0"; - $stmt = sqlsrv_query($conn, $sql, [$emailEncrypted]); + $sql = "UPDATE recuperacion_password SET estatus = 1 WHERE email = ? AND estatus = 0"; + $stmt = sqlsrv_query($conn, $sql, [$emailEncrypted]); if ($stmt) sqlsrv_free_stmt($stmt); } @@ -587,16 +601,16 @@ function obtenerEstadoDosFactores() // CORRIGIDO: Cambiar id_usuario por usuario_id $id_usuario = $_SESSION['usuario_id'] ?? null; + if (!$id_usuario) { return 0; // valor por defecto si no hay sesión } - $sql_dos_factores = "SELECT dos_factores FROM usuarios_sistema WHERE id_usuario = ?"; - $params = [$id_usuario]; + $sql_dos_factores = "SELECT dos_factores FROM usuarios_sistema WHERE id_usuario = ?"; + $params = [$id_usuario]; $stmt_dos_factores = sqlsrv_prepare($conn, $sql_dos_factores, $params); $dos_factores_estado = 0; // valor por defecto - if ($stmt_dos_factores && sqlsrv_execute($stmt_dos_factores)) { if ($row = sqlsrv_fetch_array($stmt_dos_factores, SQLSRV_FETCH_ASSOC)) { $dos_factores_estado = (int)$row['dos_factores']; diff --git a/app/controllers/seguridad.php b/app/controllers/seguridad.php index 001d0da..1ab764f 100644 --- a/app/controllers/seguridad.php +++ b/app/controllers/seguridad.php @@ -25,6 +25,7 @@ function index() function opciones() { $conn = getConnection(); + $id_usuario = $_SESSION['usuario_id'] ?? null; // Asegúrate de que el usuario está autenticado @@ -49,12 +50,11 @@ function obtenerEstadoDosFactores() return 0; // valor por defecto si no hay sesión } - $sql_dos_factores = "SELECT dos_factores FROM usuarios_sistema WHERE id_usuario = ?"; - $params = [$id_usuario]; + $sql_dos_factores = "SELECT dos_factores FROM usuarios_sistema WHERE id_usuario = ?"; + $params = [$id_usuario]; $stmt_dos_factores = sqlsrv_prepare($conn, $sql_dos_factores, $params); $dos_factores_estado = 0; // valor por defecto - if ($stmt_dos_factores && sqlsrv_execute($stmt_dos_factores)) { if ($row = sqlsrv_fetch_array($stmt_dos_factores, SQLSRV_FETCH_ASSOC)) { $dos_factores_estado = (int)$row['dos_factores']; @@ -90,10 +90,9 @@ function autenticacionDosFactores() } $dos_factores = isset($_POST['dos_factores']) ? 1 : 0; - - $sql = "UPDATE usuarios_sistema SET dos_factores = ? WHERE id_usuario = ?"; - $params = [$dos_factores, $id_usuario]; - $stmt = sqlsrv_prepare($conn, $sql, $params); + $sql = "UPDATE usuarios_sistema SET dos_factores = ? WHERE id_usuario = ?"; + $params = [$dos_factores, $id_usuario]; + $stmt = sqlsrv_prepare($conn, $sql, $params); if (!$stmt) { die("Error en la preparación: " . print_r(sqlsrv_errors(), true)); @@ -125,12 +124,13 @@ function correoExtra() exit; } - $id_usuario = $_SESSION['usuario_id']; // CORRIGIDO + $id_usuario = $_SESSION['usuario_id']; + $conn = getConnection(); - $sql_check = "SELECT COUNT(*) AS total FROM correo_extra WHERE id_usuario = ?"; + $sql_check = "SELECT COUNT(*) AS total FROM correo_extra WHERE id_usuario = ?"; $stmt_check = sqlsrv_query($conn, $sql_check, [$id_usuario]); - $row = sqlsrv_fetch_array($stmt_check, SQLSRV_FETCH_ASSOC); + $row = sqlsrv_fetch_array($stmt_check, SQLSRV_FETCH_ASSOC); if ($row['total'] > 0) { echo "Ya tienes un correo adicional registrado."; @@ -145,7 +145,7 @@ function correoExtra() } $query = "INSERT INTO correo_extra (id_usuario, correo) VALUES (?, ?)"; - $stmt = sqlsrv_prepare($conn, $query, [$id_usuario, $correo]); + $stmt = sqlsrv_prepare($conn, $query, [$id_usuario, $correo]); if ($stmt && sqlsrv_execute($stmt)) { $_SESSION['config_success'] = 'Correo adicional registrado correctamente.'; @@ -164,6 +164,7 @@ function modificarCorreoExtra() } $id_usuario = $_SESSION['usuario_id']; + $conn = getConnection(); $correo = $_POST['email-extra'] ?? ''; @@ -174,7 +175,7 @@ function modificarCorreoExtra() } $query = "UPDATE correo_extra SET correo = ? WHERE id_usuario = ?"; - $stmt = sqlsrv_prepare($conn, $query, [$correo, $id_usuario]); + $stmt = sqlsrv_prepare($conn, $query, [$correo, $id_usuario]); if ($stmt && sqlsrv_execute($stmt)) { $_SESSION['config_success'] = 'Correo adicional actualizado correctamente.'; @@ -193,10 +194,11 @@ function eliminarCorreoExtra() } $id_usuario = $_SESSION['usuario_id']; + $conn = getConnection(); $query = "DELETE FROM correo_extra WHERE id_usuario = ?"; - $stmt = sqlsrv_prepare($conn, $query, [$id_usuario]); + $stmt = sqlsrv_prepare($conn, $query, [$id_usuario]); if ($stmt && sqlsrv_execute($stmt)) { $_SESSION['config_success'] = 'Correo adicional eliminado correctamente.'; @@ -215,12 +217,13 @@ function correoRespaldo() exit; } - $id_usuario = $_SESSION['usuario_id']; // CORRIGIDO + $id_usuario = $_SESSION['usuario_id']; + $conn = getConnection(); - $sql_check = "SELECT COUNT(*) AS total FROM correo_respaldo WHERE id_usuario = ?"; + $sql_check = "SELECT COUNT(*) AS total FROM correo_respaldo WHERE id_usuario = ?"; $stmt_check = sqlsrv_query($conn, $sql_check, [$id_usuario]); - $row = sqlsrv_fetch_array($stmt_check, SQLSRV_FETCH_ASSOC); + $row = sqlsrv_fetch_array($stmt_check, SQLSRV_FETCH_ASSOC); if ($row['total'] > 0) { echo "Ya tienes un correo de respaldo registrado."; @@ -235,7 +238,7 @@ function correoRespaldo() } $query = "INSERT INTO correo_respaldo (id_usuario, correo) VALUES (?, ?)"; - $stmt = sqlsrv_prepare($conn, $query, [$id_usuario, $correo]); + $stmt = sqlsrv_prepare($conn, $query, [$id_usuario, $correo]); if ($stmt && sqlsrv_execute($stmt)) { $_SESSION['config_success'] = 'Correo de respaldo registrado correctamente.'; @@ -246,7 +249,7 @@ function correoRespaldo() } } -function modificarCorreoRspaldo() +function modificarCorreoRespaldo() { if (!isset($_SESSION['usuario_id']) || ($_SESSION['pendiente_confirmacion'] ?? false)) { echo "Error: no se ha iniciado sesión o sesión incompleta."; @@ -254,6 +257,7 @@ function modificarCorreoRspaldo() } $id_usuario = $_SESSION['usuario_id']; + $conn = getConnection(); $correo = $_POST['email-respaldo'] ?? ''; @@ -264,7 +268,7 @@ function modificarCorreoRspaldo() } $query = "UPDATE correo_respaldo SET correo = ? WHERE id_usuario = ?"; - $stmt = sqlsrv_prepare($conn, $query, [$correo, $id_usuario]); + $stmt = sqlsrv_prepare($conn, $query, [$correo, $id_usuario]); if ($stmt && sqlsrv_execute($stmt)) { $_SESSION['config_success'] = 'Correo de respaldo actualizado correctamente.'; @@ -283,10 +287,11 @@ function eliminarCorreoRespaldo() } $id_usuario = $_SESSION['usuario_id']; + $conn = getConnection(); $query = "DELETE FROM correo_respaldo WHERE id_usuario = ?"; - $stmt = sqlsrv_prepare($conn, $query, [$id_usuario]); + $stmt = sqlsrv_prepare($conn, $query, [$id_usuario]); if ($stmt && sqlsrv_execute($stmt)) { $_SESSION['config_success'] = 'Correo de respaldo eliminado correctamente.'; @@ -300,15 +305,16 @@ function eliminarCorreoRespaldo() function obtenerCorreos($conn, $id_usuario) { $correos = [ - 'dos_factores' => 0, - 'correo_extra' => '', + 'dos_factores' => 0, + 'correo_extra' => '', 'correo_respaldo' => '' ]; // Obtener estado dos_factores - $sql_dos_factores = "SELECT dos_factores FROM usuarios_sistema WHERE id_usuario = ?"; - $params = [$id_usuario]; + $sql_dos_factores = "SELECT dos_factores FROM usuarios_sistema WHERE id_usuario = ?"; + $params = [$id_usuario]; $stmt_dos_factores = sqlsrv_prepare($conn, $sql_dos_factores, $params); + if ($stmt_dos_factores && sqlsrv_execute($stmt_dos_factores)) { if ($row = sqlsrv_fetch_array($stmt_dos_factores, SQLSRV_FETCH_ASSOC)) { $correos['dos_factores'] = (int)$row['dos_factores']; // MEJORADO: Cast a int @@ -316,8 +322,9 @@ function obtenerCorreos($conn, $id_usuario) } // Obtener correo_extra - $sql_extra = "SELECT correo FROM correo_extra WHERE id_usuario = ?"; + $sql_extra = "SELECT correo FROM correo_extra WHERE id_usuario = ?"; $stmt_extra = sqlsrv_prepare($conn, $sql_extra, $params); + if ($stmt_extra && sqlsrv_execute($stmt_extra)) { if ($row = sqlsrv_fetch_array($stmt_extra, SQLSRV_FETCH_ASSOC)) { $correos['correo_extra'] = $row['correo']; @@ -325,8 +332,9 @@ function obtenerCorreos($conn, $id_usuario) } // Obtener correo_respaldo - $sql_respaldo = "SELECT correo FROM correo_respaldo WHERE id_usuario = ?"; + $sql_respaldo = "SELECT correo FROM correo_respaldo WHERE id_usuario = ?"; $stmt_respaldo = sqlsrv_prepare($conn, $sql_respaldo, $params); + if ($stmt_respaldo && sqlsrv_execute($stmt_respaldo)) { if ($row = sqlsrv_fetch_array($stmt_respaldo, SQLSRV_FETCH_ASSOC)) { $correos['correo_respaldo'] = $row['correo']; diff --git a/app/controllers/solicitud_importacion.php b/app/controllers/solicitud_importacion.php index 64d8023..12a0381 100644 --- a/app/controllers/solicitud_importacion.php +++ b/app/controllers/solicitud_importacion.php @@ -1,14 +1,19 @@ $user, 'password' => $pass]); error_log("[getApiToken] POST $url → $body"); @@ -70,38 +75,40 @@ function lista() exit; } $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.*, - tr.nombre AS transportista, - (c.nombre + ' ' + c.apellido) AS chofer, - p.nombre AS nombre_pais_proveedor, - f.foto_solicitud_url, - a.patente AS patente - FROM dbo.solicitud_importacion_factura f - JOIN dbo.transportistas tr - ON f.transportista_id = tr.id_transportista - LEFT JOIN dbo.choferes c - ON f.chofer_id = c.id_chofer - LEFT JOIN dbo.paises p - ON f.pais_proveedor = p.id_pais - LEFT JOIN dbo.agentes_aduanales a - ON f.patente_id = a.id_agente - WHERE f.id_importador = ? - AND f.id_agencia = ? - AND f.status >= 1 - ORDER BY f.created_at DESC - "; + $sql = "SELECT + f.*, + tr.nombre AS transportista, + (c.nombre + ' ' + c.apellido) AS chofer, + p.nombre AS nombre_pais_proveedor, + f.foto_solicitud_url, + a.patente AS patente + FROM dbo.solicitud_importacion_factura f + JOIN dbo.transportistas tr + ON f.transportista_id = tr.id_transportista + LEFT JOIN dbo.choferes c + ON f.chofer_id = c.id_chofer + LEFT JOIN dbo.paises p + ON f.pais_proveedor = p.id_pais + LEFT JOIN dbo.agentes_aduanales a + ON f.patente_id = a.id_agente + 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, $id_agencia]); + if ($stmt === false) { die("Error en lista(): " . print_r(sqlsrv_errors(), true)); } @@ -126,11 +133,13 @@ function crear() } $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]); if ($stmt === false) { die(print_r(sqlsrv_errors(), true)); } + $id_agencia = null; if ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { $id_agencia = $row['id_agencia_en_uso']; } @@ -180,7 +189,7 @@ function obtenerChoferesPorTransportista() exit; } - $id_importador = $_SESSION['usuario_id']; + $id_importador = $_SESSION['usuario_id']; $transportista_id = $_GET['transportista_id'] ?? null; if (!$transportista_id || !is_numeric($transportista_id)) { @@ -238,10 +247,12 @@ function guardar() } $id_importador = $_SESSION['usuario_id']; - $conn = getConnection(); + + $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']; @@ -282,47 +293,45 @@ function guardar() } // Foto solicitud - $fotoUrl=null; + $fotoUrl = null; if (!empty($_FILES['foto_solicitud']['tmp_name']) && $_FILES['foto_solicitud']['error']===UPLOAD_ERR_OK) { - $ext=pathinfo($_FILES['foto_solicitud']['name'],PATHINFO_EXTENSION); - $dest=__DIR__.'/../../public/uploads/solicitud_'.uniqid().".$ext"; + $ext = pathinfo($_FILES['foto_solicitud']['name'], PATHINFO_EXTENSION); + $dest = __DIR__.'/../../public/uploads/solicitud_'.uniqid().".$ext"; if (!is_dir(dirname($dest))) mkdir(dirname($dest),0755,true); if(move_uploaded_file($_FILES['foto_solicitud']['tmp_name'],$dest)) { - $fotoUrl="/IMPORTADORES/public/uploads/".basename($dest); + $fotoUrl = "/IMPORTADORES/public/uploads/".basename($dest); } } $params = [ - $id_importador, - $id_agencia, - $aduana_seccion, - $aduana_seccion, - $num_factura, - $fecha, - $incoterm, - $pais_proveedor, - $tipo_moneda, - $valor_factura, - $vinculacion, - (int)$transportista_id, - (int)$chofer_id, - $fotoUrl, - $status, - $proveedor_clave, - $patente_id ? (int)$patente_id : null - ]; + $id_importador, + $id_agencia, + $aduana_seccion, + $aduana_seccion, + $num_factura, + $fecha, + $incoterm, + $pais_proveedor, + $tipo_moneda, + $valor_factura, + $vinculacion, + (int)$transportista_id, + (int)$chofer_id, + $fotoUrl, + $status, + $proveedor_clave, + $patente_id ? (int)$patente_id : null + ]; + $sql = "INSERT INTO dbo.solicitud_importacion_factura + (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, patente_id) + OUTPUT INSERTED.id_solicitud + VALUES(?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + "; + $stmt = sqlsrv_query($conn, $sql, $params, ['Scrollable' => SQLSRV_CURSOR_KEYSET]); - $sql = " - INSERT INTO dbo.solicitud_importacion_factura - (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, patente_id) - OUTPUT INSERTED.id_solicitud - VALUES(?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - "; - - $stmt = sqlsrv_query($conn, $sql, $params, ['Scrollable' => SQLSRV_CURSOR_KEYSET]); if ($stmt === false) { die("❌ Error ejecutando INSERT con OUTPUT: " . print_r(sqlsrv_errors(), true)); } @@ -336,22 +345,17 @@ function guardar() try { // Verificar configuración de notificaciones del usuario - $sqlNotif = " - SELECT - u.nombre, - u.email, - u.notificaciones, - u.notificaciones_extra, - COALESCE(p.nuevas_solicitudes, 0) as nuevas_solicitudes, - ce.correo as correo_extra - FROM usuarios_sistema u - LEFT JOIN preferencias_notificaciones_usuario p - ON u.id_usuario = p.id_usuario - LEFT JOIN correo_extra ce - ON u.id_usuario = ce.id_usuario - WHERE u.id_usuario = ? - "; - + $sqlNotif = "SELECT + u.nombre, u.email, u.notificaciones, u.notificaciones_extra, + COALESCE(p.nuevas_solicitudes, 0) as nuevas_solicitudes, + ce.correo as correo_extra + FROM usuarios_sistema u + LEFT JOIN preferencias_notificaciones_usuario p + ON u.id_usuario = p.id_usuario + LEFT JOIN correo_extra ce + ON u.id_usuario = ce.id_usuario + WHERE u.id_usuario = ? + "; $stmtNotif = sqlsrv_prepare($conn, $sqlNotif, [$id_importador]); if ($stmtNotif && sqlsrv_execute($stmtNotif)) { @@ -361,7 +365,7 @@ function guardar() // 🔐 Desencriptar datos if ($notifConfig) { // Correo - $notifConfig['email'] = decrypt($notifConfig['email']); + $notifConfig['email'] = decrypt($notifConfig['email']); // Nombre $notifConfig['nombre'] = decrypt($notifConfig['nombre']); } @@ -452,10 +456,8 @@ function guardar() } /** Función para generar la notificación **/ -use PHPMailer\PHPMailer\PHPMailer; -use PHPMailer\PHPMailer\Exception; - -function enviarNotificacionNuevaSolicitud($email, $nombreUsuario, $datosSolicitud, $esCorreoExtra = false) { +function enviarNotificacionNuevaSolicitud($email, $nombreUsuario, $datosSolicitud, $esCorreoExtra = false) +{ $mail = new PHPMailer(true); try { @@ -558,16 +560,19 @@ function editar() } $id_solicitud = $_GET['id']??null; + if(!$id_solicitud || !is_numeric($id_solicitud)) { die("❌ ID inválido."); } $id_importador = $_SESSION['usuario_id']; - $conn = getConnection(); + + $conn = getConnection(); // ✅ NUEVO: Obtener la agencia actual del usuario $stmtAg = sqlsrv_query($conn, "SELECT id_agencia_en_uso FROM dbo.usuarios_sistema WHERE id_usuario = ?", [$id_importador]); if ($stmtAg === false) { die(print_r(sqlsrv_errors(), true)); } + $id_agencia = null; if ($row = sqlsrv_fetch_array($stmtAg, SQLSRV_FETCH_ASSOC)) { $id_agencia = $row['id_agencia_en_uso']; } @@ -575,10 +580,12 @@ function editar() if($stmt === false) { die(print_r(sqlsrv_errors(),true)); } + $factura = sqlsrv_fetch_array($stmt,SQLSRV_FETCH_ASSOC); if(!$factura) { die("❌ No autorizado."); } + if($factura['fecha_factura'] instanceof DateTime) { $factura['fecha_factura'] = $factura['fecha_factura']->format('Y-m-d'); } @@ -595,24 +602,24 @@ function editar() // 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]); - while($r = sqlsrv_fetch_array($stmtT,SQLSRV_FETCH_ASSOC)) { $transportistas[] = $r; } + while ($r = sqlsrv_fetch_array($stmtT, SQLSRV_FETCH_ASSOC)) { $transportistas[] = $r; } // Choferes $choferes = []; - $stmtC = sqlsrv_query($conn, "SELECT c.id_chofer, c.nombre+' '+c.apellido AS nombre, c.transportista_id FROM dbo.choferes c JOIN dbo.transportistas t ON c.transportista_id=t.id_transportista - WHERE t.id_usuario=? AND c.status=1 ORDER BY c.nombre",[$id_importador]); - while($r=sqlsrv_fetch_array($stmtC,SQLSRV_FETCH_ASSOC)) { $choferes[] = $r; } + $stmtC = sqlsrv_query($conn, "SELECT c.id_chofer, c.nombre+' '+c.apellido AS nombre, c.transportista_id FROM dbo.choferes c JOIN dbo.transportistas t ON c.transportista_id = t.id_transportista + WHERE t.id_usuario=? AND c.status=1 ORDER BY c.nombre",[$id_importador]); + while ($r = sqlsrv_fetch_array($stmtC, SQLSRV_FETCH_ASSOC)) { $choferes[] = $r; } // Paises $paises = []; $stmtP = sqlsrv_query($conn, "SELECT id_pais, nombre FROM dbo.paises ORDER BY nombre"); - while($r=sqlsrv_fetch_array($stmtP,SQLSRV_FETCH_ASSOC)) { $paises[] = $r;} + while ($r = sqlsrv_fetch_array($stmtP, SQLSRV_FETCH_ASSOC)) { $paises[] = $r;} // Aduanas $aduanas = []; $stmtA = sqlsrv_query($conn, "SELECT DISTINCT RIGHT(REPLICATE('0', 3) + CAST(aduana_seccion AS VARCHAR), 3) AS aduana_seccion, nombre FROM dbo.aduanas ORDER BY aduana_seccion"); - while($r = sqlsrv_fetch_array($stmtA,SQLSRV_FETCH_ASSOC)) { $aduanas[] = $r; } + while ($r = sqlsrv_fetch_array($stmtA, SQLSRV_FETCH_ASSOC)) { $aduanas[] = $r; } // Incoterms $incoterms = []; $stmtI = sqlsrv_query($conn, "SELECT INCOTERM, DESCESPANOL FROM dbo.gIncoterms ORDER BY INCOTERM"); - while($r = sqlsrv_fetch_array($stmtI,SQLSRV_FETCH_ASSOC)) { $incoterms[] = $r; } + while ($r = sqlsrv_fetch_array($stmtI, SQLSRV_FETCH_ASSOC)) { $incoterms[] = $r; } // Unidades de Medida $unidades_medida = []; $stmtU = sqlsrv_query($conn, "SELECT id, descripcion FROM dbo.unidades_medida_apendice7 ORDER BY id"); @@ -620,12 +627,9 @@ function editar() // Partidas existentes $partidas = []; - $stmtPar = sqlsrv_query($conn, - "SELECT id_partida, descripcion, cantidad_comercial, cantidad_tarifa, valor_factura, peso_bruto, unidad_comercial_id, tasa_preferencial - FROM dbo.solicitud_importacion_partidas WHERE id_solicitud=? ORDER BY id_partida", [(int)$id_solicitud]); - while($r=sqlsrv_fetch_array($stmtPar,SQLSRV_FETCH_ASSOC)) { - $partidas[]=$r; - } + $stmtPar = sqlsrv_query($conn, "SELECT id_partida, descripcion, cantidad_comercial, cantidad_tarifa, valor_factura, peso_bruto, unidad_comercial_id, tasa_preferencial + FROM dbo.solicitud_importacion_partidas WHERE id_solicitud = ? ORDER BY id_partida", [(int)$id_solicitud]); + while ($r = sqlsrv_fetch_array($stmtPar, SQLSRV_FETCH_ASSOC)) { $partidas[]=$r; } include __DIR__ . '/../../views/solicitud_importacion/editar.php'; } @@ -638,8 +642,8 @@ function actualizar() } $id_importador = $_SESSION['usuario_id']; + $id_solicitud = (int)($_POST['id_solicitud'] ?? 0); - $id_solicitud = (int)($_POST['id_solicitud'] ?? 0); if ($id_solicitud <= 0) { die("❌ ID inválido."); } @@ -649,6 +653,7 @@ function actualizar() // ✅ 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']; @@ -656,28 +661,20 @@ function actualizar() // 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 = ? AND id_agencia = ?", - [ $id_solicitud, $_SESSION['usuario_id'], $id_agencia ] - ); + $stmtFoto = sqlsrv_query($conn, "SELECT foto_solicitud_url FROM dbo.solicitud_importacion_factura 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']; } // 3) Procesar posible nueva foto - if (!empty($_FILES['foto_solicitud']['tmp_name']) - && $_FILES['foto_solicitud']['error'] === UPLOAD_ERR_OK) { + if (!empty($_FILES['foto_solicitud']['tmp_name']) && $_FILES['foto_solicitud']['error'] === UPLOAD_ERR_OK) { $ext = pathinfo($_FILES['foto_solicitud']['name'], PATHINFO_EXTENSION); $dest = __DIR__ . '/../../public/uploads/solicitud_' . uniqid() . ".$ext"; - if (!is_dir(dirname($dest))) { - mkdir(dirname($dest), 0755, true); - } - if (move_uploaded_file($_FILES['foto_solicitud']['tmp_name'], $dest)) { - $fotoUrl = "/IMPORTADORES/public/uploads/" . basename($dest); - } + + if (!is_dir(dirname($dest))) { mkdir(dirname($dest), 0755, true); } + + if (move_uploaded_file($_FILES['foto_solicitud']['tmp_name'], $dest)) { $fotoUrl = "/IMPORTADORES/public/uploads/" . basename($dest); } } // 4) Extraer campos del formulario @@ -697,9 +694,7 @@ function actualizar() // ✅ NUEVO: Validar que la patente pertenezca a la agencia del usuario (si se seleccionó una) if ($patente_id) { - $stmtValidatePatente = sqlsrv_query($conn, - "SELECT id_agente FROM dbo.agentes_aduanales WHERE id_agente = ? AND id_agencia = ? AND activo = 1", - [$patente_id, $id_agencia]); + $stmtValidatePatente = sqlsrv_query($conn, "SELECT id_agente FROM dbo.agentes_aduanales WHERE id_agente = ? AND id_agencia = ? AND activo = 1", [$patente_id, $id_agencia]); if (!$stmtValidatePatente || !sqlsrv_fetch_array($stmtValidatePatente, SQLSRV_FETCH_ASSOC)) { die("❌ La patente seleccionada no es válida para su agencia."); @@ -714,68 +709,66 @@ function actualizar() // 6) UPDATE de la cabecera $paramsU = [ - $aduana_seccion, - $aduana_seccion, - $num_factura, - $fecha, - $incoterm, - $pais_proveedor, - $tipo_moneda, - $valor_factura, - $vinculacion, - (int)$transportista_id, - (int)$chofer_id, - $fotoUrl, - $status, - $proveedor_clave, - $patente_id ? (int)$patente_id : null, - $id_solicitud, - $_SESSION['usuario_id'], - $id_agencia - ]; + $aduana_seccion, + $aduana_seccion, + $num_factura, + $fecha, + $incoterm, + $pais_proveedor, + $tipo_moneda, + $valor_factura, + $vinculacion, + (int)$transportista_id, + (int)$chofer_id, + $fotoUrl, + $status, + $proveedor_clave, + $patente_id ? (int)$patente_id : null, + $id_solicitud, + $_SESSION['usuario_id'], + $id_agencia + ]; + $sqlU = "UPDATE dbo.solicitud_importacion_factura SET + aduana = ?, + anexo22_apendice = ?, + numero_factura = ?, + fecha_factura = ?, + incoterm = ?, + pais_proveedor = ?, + tipo_moneda = ?, + valor_factura = ?, + vinculacion = ?, + transportista_id = ?, + chofer_id = ?, + foto_solicitud_url = ?, + status = ?, + proveedor_clave = ?, + patente_id = ?, + updated_at = GETDATE() + WHERE id_solicitud = ? + AND id_importador = ? + AND id_agencia = ? + "; + $stmtU = sqlsrv_query($conn, $sqlU, $paramsU); - $sqlU = " - UPDATE dbo.solicitud_importacion_factura - SET aduana = ?, - anexo22_apendice = ?, - numero_factura = ?, - fecha_factura = ?, - incoterm = ?, - pais_proveedor = ?, - tipo_moneda = ?, - valor_factura = ?, - vinculacion = ?, - transportista_id = ?, - chofer_id = ?, - foto_solicitud_url = ?, - status = ?, - proveedor_clave = ?, - patente_id = ?, - updated_at = GETDATE() - WHERE id_solicitud = ? - AND id_importador = ? - AND id_agencia = ? - "; - - $stmtU = sqlsrv_query($conn, $sqlU, $paramsU); if ($stmtU === false) { die("❌ Error ejecutando UPDATE: " . print_r(sqlsrv_errors(), true)); } // 7) Borrar partidas anteriores $del = sqlsrv_query($conn, "DELETE FROM dbo.solicitud_importacion_partidas WHERE id_solicitud = ?", [ $id_solicitud ]); + if ($del === false) { die("❌ Error borrando partidas previas: " . print_r(sqlsrv_errors(), true)); } // 8) Reinsertar partidas desde el formulario if (!empty($_POST['partidas']) && is_array($_POST['partidas'])) { - $sqlP = " - INSERT INTO dbo.solicitud_importacion_partidas - (id_solicitud, descripcion, cantidad_comercial, cantidad_tarifa, - valor_factura, peso_bruto, unidad_comercial_id, tasa_preferencial) - VALUES (?, ?, ?, ?, ?, ?, ?, ?) - "; + $sqlP = "INSERT INTO dbo.solicitud_importacion_partidas + (id_solicitud, descripcion, cantidad_comercial, cantidad_tarifa, + valor_factura, peso_bruto, unidad_comercial_id, tasa_preferencial) + VALUES (?, ?, ?, ?, ?, ?, ?, ?) + "; foreach ($_POST['partidas'] as $i => $p) { $desc = trim($p['descripcion'] ?? ''); $cantCom = floatval($p['cantidad_comercial'] ?? 0); @@ -788,16 +781,17 @@ function actualizar() // Sólo inserta si descripción y cantidad comercial válidos if ($desc !== '' && $cantCom > 0) { $paramsP = [ - $id_solicitud, - $desc, - $cantCom, - $cantTar, - $valPart, - $peso, - $umId, - $tasaPref - ]; - $stmtP = sqlsrv_query($conn, $sqlP, $paramsP); + $id_solicitud, + $desc, + $cantCom, + $cantTar, + $valPart, + $peso, + $umId, + $tasaPref + ]; + $stmtP = sqlsrv_query($conn, $sqlP, $paramsP); + if ($stmtP === false) { die("❌ Error insertando partida #$i: " . print_r(sqlsrv_errors(), true)); } @@ -811,19 +805,24 @@ function actualizar() } /** “Soft-delete” de una factura **/ -function eliminar() { +function eliminar() +{ if (!($_SESSION['usuario_id'] ?? false)) { header('Location: /IMPORTADORES/login'); exit; } + $id = (int) ($_GET['id'] ?? 0); + $conn = getConnection(); + sqlsrv_query($conn, "UPDATE dbo.solicitud_importacion_factura SET status = 0, updated_at = GETDATE() WHERE id_solicitud = ? AND id_importador = ?",[$id,$_SESSION['usuario_id']]); header('Location: /IMPORTADORES/solicitud_importacion/lista?deleted=ok'); exit; } -function actualizar_masivo() { +function actualizar_masivo() +{ header('Content-Type: application/json; charset=utf-8'); if (!($_SESSION['usuario_id'] ?? false)) { @@ -838,7 +837,7 @@ function actualizar_masivo() { exit; } - $ids = $_POST['ids'] ?? []; + $ids = $_POST['ids'] ?? []; $status = (int) ($_POST['status'] ?? 0); if (empty($ids) || !is_array($ids)) { @@ -847,18 +846,19 @@ function actualizar_masivo() { } $conn = getConnection(); - $usuarioId = $_SESSION['usuario_id']; - $token = ($status === 2) ? getApiToken() : null; - $actualizadas = 0; - $fallidas = []; + $usuarioId = $_SESSION['usuario_id']; + $token = ($status === 2) ? getApiToken() : null; + + $actualizadas = 0; + $fallidas = []; $pedimentosGenerados = []; foreach ($ids as $id) { $id = (int)$id; // 1. Actualizar el status - $sql = "UPDATE dbo.solicitud_importacion_factura SET status = ? WHERE id_solicitud = ? AND id_importador = ?"; + $sql = "UPDATE dbo.solicitud_importacion_factura SET status = ? WHERE id_solicitud = ? AND id_importador = ?"; $stmt = sqlsrv_query($conn, $sql, [$status, $id, $usuarioId]); if ($stmt === false) { @@ -880,47 +880,49 @@ function actualizar_masivo() { } echo json_encode([ - 'success' => true, + 'success' => true, 'actualizadas' => $actualizadas, - 'fallidas' => $fallidas, - 'pedimentos' => $pedimentosGenerados + 'fallidas' => $fallidas, + 'pedimentos' => $pedimentosGenerados ]); exit; } -function generarPedimentoDesdeSolicitud($conn, $id, $usuarioId, $token) { +function generarPedimentoDesdeSolicitud($conn, $id, $usuarioId, $token) +{ try { // Consulta solicitud - $sqlSel = "SELECT *, '9999' as patente FROM dbo.solicitud_importacion_factura WHERE id_solicitud = ? AND id_importador = ?"; - $stmtSel = sqlsrv_query($conn, $sqlSel, [$id, $usuarioId]); + $sqlSel = "SELECT *, '9999' as patente FROM dbo.solicitud_importacion_factura WHERE id_solicitud = ? AND id_importador = ?"; + $stmtSel = sqlsrv_query($conn, $sqlSel, [$id, $usuarioId]); $solicitud = sqlsrv_fetch_array($stmtSel, SQLSRV_FETCH_ASSOC); + if (!$solicitud) return ['success' => false, 'error' => 'Solicitud no encontrada']; // Fechas - $solicitud['fecha_factura'] = $solicitud['fecha_factura'] instanceof DateTime ? $solicitud['fecha_factura']->format('Y-m-d') : $solicitud['fecha_factura']; - $solicitud['created_at'] = $solicitud['created_at'] instanceof DateTime ? $solicitud['created_at']->format('Y-m-d\TH:i:s') : $solicitud['created_at']; - $solicitud['updated_at'] = $solicitud['updated_at'] instanceof DateTime ? $solicitud['updated_at']->format('Y-m-d\TH:i:s') : $solicitud['updated_at']; + $solicitud['fecha_factura'] = $solicitud['fecha_factura'] instanceof DateTime ? $solicitud['fecha_factura'] ->format('Y-m-d') : $solicitud['fecha_factura']; + $solicitud['created_at'] = $solicitud['created_at'] instanceof DateTime ? $solicitud['created_at'] ->format('Y-m-d\TH:i:s') : $solicitud['created_at']; + $solicitud['updated_at'] = $solicitud['updated_at'] instanceof DateTime ? $solicitud['updated_at'] ->format('Y-m-d\TH:i:s') : $solicitud['updated_at']; // Partidas $partidas = []; $stmtPart = sqlsrv_query($conn, "SELECT * FROM dbo.solicitud_importacion_partidas WHERE id_solicitud = ?", [$id]); while ($p = sqlsrv_fetch_array($stmtPart, SQLSRV_FETCH_ASSOC)) { if ($p['creado_en'] instanceof DateTime) $p['creado_en'] = $p['creado_en']->format('Y-m-d\TH:i:s'); - $p['cantidad_comercial'] = (float)$p['cantidad_comercial']; - $p['cantidad_tarifa'] = (float)$p['cantidad_tarifa']; - $p['valor_factura'] = (float)$p['valor_factura']; - $p['peso_bruto'] = (float)$p['peso_bruto']; + $p['cantidad_comercial'] = (float)$p['cantidad_comercial']; + $p['cantidad_tarifa'] = (float)$p['cantidad_tarifa']; + $p['valor_factura'] = (float)$p['valor_factura']; + $p['peso_bruto'] = (float)$p['peso_bruto']; $p['unidad_comercial_id'] = (int)$p['unidad_comercial_id']; $partidas[] = $p; } $solicitud['numero_pedimento'] = ""; - $solicitud['transporte_id'] = null; - $solicitud['partidas'] = $partidas; + $solicitud['transporte_id'] = null; + $solicitud['partidas'] = $partidas; $jsonPayload = json_encode($solicitud); - $apiBase = rtrim($_ENV['API_URL'] ?? '', '/'); - $urlPed = $apiBase . '/pedimentos/crearPedimento'; + $apiBase = rtrim($_ENV['API_URL'] ?? '', '/'); + $urlPed = $apiBase . '/pedimentos/crearPedimento'; $ch = curl_init($urlPed); curl_setopt_array($ch, [ @@ -1036,15 +1038,15 @@ function ajax_lista() // Construir dirección $direccion = trim(implode(', ', array_filter([ - $p['Calles'] ?? '', - 'Num. Ext: ' . ($p['NumExt'] ?? ''), - 'Num. Int: ' . ($p['NumInt'] ?? ''), - $p['Colonia'] ?? '', - $p['Municipio'] ?? '', - $p['Ciudad'] ?? '', + $p['Calles'] ?? '', + 'Num. Ext: ' . ($p['NumExt'] ?? ''), + 'Num. Int: ' . ($p['NumInt'] ?? ''), + $p['Colonia'] ?? '', + $p['Municipio'] ?? '', + $p['Ciudad'] ?? '', 'C.P. ' . ($p['CodigoPostal'] ?? ''), - $p['EntidadFederativa'] ?? '', - $p['Pais'] ?? '' + $p['EntidadFederativa'] ?? '', + $p['Pais'] ?? '' ]))); $dataList[] = [ @@ -1067,8 +1069,10 @@ function ajax_lista() echo json_encode(['data' => $dataList]); } -function update_status() { +function update_status() +{ header('Content-Type: application/json; charset=utf-8'); + if (!($_SESSION['usuario_id'] ?? false)) { http_response_code(401); echo json_encode(['error' => 'No autorizado']); @@ -1082,11 +1086,10 @@ function update_status() { $conn = getConnection(); // 2) Actualizar el status en la tabla solicitud_importacion_factura - $sql = "UPDATE dbo.solicitud_importacion_factura - SET status=? - WHERE id_solicitud=? AND id_importador=?"; + $sql = "UPDATE dbo.solicitud_importacion_factura SET status = ? WHERE id_solicitud=? AND id_importador=?"; $params = [$status, $id, $_SESSION['usuario_id']]; - $stmt = sqlsrv_query($conn, $sql, $params); + $stmt = sqlsrv_query($conn, $sql, $params); + if ($stmt === false) { http_response_code(500); echo json_encode(['error' => 'Error al actualizar status']); @@ -1095,24 +1098,21 @@ function update_status() { // 3) Obtener datos del usuario y solicitud para notificación try { - $sqlNotif = " - SELECT - u.nombre, - u.email, - u.notificaciones, - u.notificaciones_extra, - COALESCE(p.cambio_estado, 0) as cambio_estado, - ce.correo as correo_extra, - s.numero_factura, - s.fecha_factura, - s.valor_factura, - s.tipo_moneda - FROM usuarios_sistema u - LEFT JOIN preferencias_notificaciones_usuario p ON u.id_usuario = p.id_usuario - LEFT JOIN correo_extra ce ON u.id_usuario = ce.id_usuario - INNER JOIN solicitud_importacion_factura s ON s.id_importador = u.id_usuario - WHERE u.id_usuario = ? AND s.id_solicitud = ?"; - + $sqlNotif = "SELECT + u.nombre, u.email, u.notificaciones, u.notificaciones_extra, + COALESCE(p.cambio_estado, 0) as cambio_estado, + ce.correo as correo_extra, + s.numero_factura, s.fecha_factura, s.valor_factura, s.tipo_moneda + FROM usuarios_sistema u + LEFT JOIN preferencias_notificaciones_usuario p + ON u.id_usuario = p.id_usuario + LEFT JOIN correo_extra ce + ON u.id_usuario = ce.id_usuario + INNER JOIN solicitud_importacion_factura s + ON s.id_importador = u.id_usuario + WHERE u.id_usuario = ? + AND s.id_solicitud = ? + "; $stmtNotif = sqlsrv_prepare($conn, $sqlNotif, [$_SESSION['usuario_id'], $id]); if ($stmtNotif && sqlsrv_execute($stmtNotif)) { @@ -1121,14 +1121,12 @@ function update_status() { // 🔐 Desencriptar datos if ($notifConfig) { - $notifConfig['email'] = decrypt($notifConfig['email']); + $notifConfig['email'] = decrypt($notifConfig['email']); $notifConfig['nombre'] = decrypt($notifConfig['nombre']); } // Verificar si debe enviar notificaciones de cambio de status - if ($notifConfig && - $notifConfig['notificaciones'] == 1 && - $notifConfig['cambio_estado'] == 1) { + if ($notifConfig && $notifConfig['notificaciones'] == 1 && $notifConfig['cambio_estado'] == 1) { // Formatear fecha si es DateTime $fechaFactura = ($notifConfig['fecha_factura'] instanceof DateTime) @@ -1137,16 +1135,16 @@ function update_status() { // Preparar datos para la notificación $datosSolicitud = [ - 'id_solicitud' => $id, + 'id_solicitud' => $id, 'numero_factura' => $notifConfig['numero_factura'], - 'fecha_factura' => $fechaFactura, - 'valor_factura' => $notifConfig['valor_factura'], - 'tipo_moneda' => $notifConfig['tipo_moneda'], - 'nuevo_status' => $status + 'fecha_factura' => $fechaFactura, + 'valor_factura' => $notifConfig['valor_factura'], + 'tipo_moneda' => $notifConfig['tipo_moneda'], + 'nuevo_status' => $status ]; $notificacionesEnviadas = 0; - $erroresNotificacion = []; + $erroresNotificacion = []; // Enviar al correo principal if (!empty($notifConfig['email']) && filter_var($notifConfig['email'], FILTER_VALIDATE_EMAIL)) { @@ -1199,7 +1197,7 @@ function update_status() { $razon[] = 'configuración no encontrada'; } else { if ($notifConfig['notificaciones'] != 1) $razon[] = 'notificaciones generales deshabilitadas'; - if ($notifConfig['cambio_estado'] != 1) $razon[] = 'notificaciones de cambio de estado deshabilitadas'; + if ($notifConfig['cambio_estado'] != 1) $razon[] = 'notificaciones de cambio de estado deshabilitadas'; } error_log("ℹ️ Usuario ID: {$_SESSION['usuario_id']} no recibirá notificación de cambio de status. Razón: " . implode(', ', $razon)); @@ -1225,36 +1223,24 @@ function update_status() { } // 4.2) Leer de la BD todos los campos de la cabecera de la solicitud - $sqlSel = " - SELECT - s.id_solicitud, - s.id_importador, - s.aduana, - s.numero_pedimento, - s.anexo22_apendice, - s.numero_factura, - s.fecha_factura, - s.incoterm, - s.pais_proveedor, - s.tipo_moneda, - s.valor_factura, - s.vinculacion, - s.transportista_id, - s.chofer_id, - s.foto_solicitud_url, - s.proveedor_clave, - s.created_at, - s.updated_at, - '9999' as patente - FROM dbo.solicitud_importacion_factura s - WHERE s.id_solicitud = ? AND s.id_importador = ? - "; + $sqlSel = "SELECT + s.id_solicitud, s.id_importador, s.aduana, s.numero_pedimento, s.anexo22_apendice, + s.numero_factura, s.fecha_factura, s.incoterm, s.pais_proveedor, + s.tipo_moneda, s.valor_factura, s.vinculacion, s.transportista_id, s.chofer_id, + s.foto_solicitud_url, s.proveedor_clave, s.created_at, s.updated_at, + '9999' as patente + FROM dbo.solicitud_importacion_factura s + WHERE s.id_solicitud = ? + AND s.id_importador = ? + "; $stmtSel = sqlsrv_query($conn, $sqlSel, [$id, $_SESSION['usuario_id']]); + if ($stmtSel === false) { error_log("[update_status] Error al consultar solicitud: " . print_r(sqlsrv_errors(), true)); echo json_encode(['success' => true, 'warning' => 'Status actualizado, fallo al leer datos para pedimento']); exit; } + $solicitud = sqlsrv_fetch_array($stmtSel, SQLSRV_FETCH_ASSOC); sqlsrv_free_stmt($stmtSel); @@ -1269,37 +1255,30 @@ function update_status() { ? $solicitud['fecha_factura']->format('Y-m-d') : $solicitud['fecha_factura']; - $createdAt = ($solicitud['created_at'] instanceof DateTime) - ? $solicitud['created_at']->format('Y-m-d\TH:i:s') - : $solicitud['created_at']; + $createdAt = ($solicitud['created_at'] instanceof DateTime) + ? $solicitud['created_at']->format('Y-m-d\TH:i:s') + : $solicitud['created_at']; - $updatedAt = ($solicitud['updated_at'] instanceof DateTime) - ? $solicitud['updated_at']->format('Y-m-d\TH:i:s') - : $solicitud['updated_at']; + $updatedAt = ($solicitud['updated_at'] instanceof DateTime) + ? $solicitud['updated_at']->format('Y-m-d\TH:i:s') + : $solicitud['updated_at']; // 4.4) Obtener todas las partidas asociadas a esta solicitud - $sqlPart = " - SELECT - p.id_partida, - p.id_solicitud, - p.descripcion, - p.creado_en, - p.cantidad_comercial, - p.cantidad_tarifa, - p.valor_factura, - p.peso_bruto, - p.unidad_comercial_id, - p.tasa_preferencial - FROM dbo.solicitud_importacion_partidas p - WHERE p.id_solicitud = ? - ORDER BY p.id_partida - "; + $sqlPart = "SELECT + p.id_partida, p.id_solicitud, p.descripcion, p.creado_en, p.cantidad_comercial, + p.cantidad_tarifa, p.valor_factura, p.peso_bruto, p.unidad_comercial_id, p.tasa_preferencial + FROM dbo.solicitud_importacion_partidas p + WHERE p.id_solicitud = ? + ORDER BY p.id_partida + "; $stmtPart = sqlsrv_query($conn, $sqlPart, [$id]); + if ($stmtPart === false) { error_log("[update_status] Error al consultar partidas: " . print_r(sqlsrv_errors(), true)); echo json_encode(['success' => true, 'warning' => 'Status actualizado, fallo al leer partidas para pedimento']); exit; } + $partidas = []; while ($row = sqlsrv_fetch_array($stmtPart, SQLSRV_FETCH_ASSOC)) { if ($row['creado_en'] instanceof DateTime) { @@ -1315,30 +1294,29 @@ function update_status() { sqlsrv_free_stmt($stmtPart); // 4.5) Construir el arreglo PHP con la misma estructura JSON que envías - $payload = [ - "id_solicitud" => intval($solicitud['id_solicitud']), - "id_importador" => intval($solicitud['id_importador']), - "aduana" => strval($solicitud['aduana']), - "patente" => strval($solicitud['patente']), - "anexo22_apendice" => strval($solicitud['anexo22_apendice']), - "numero_factura" => strval($solicitud['numero_factura']), - "fecha_factura" => $fechaFactura, - "numero_pedimento" => "", // La API lo rellenará - "incoterm" => strval($solicitud['incoterm']), - "pais_proveedor" => strval($solicitud['pais_proveedor']), - "tipo_moneda" => strval($solicitud['tipo_moneda']), - "valor_factura" => floatval($solicitud['valor_factura']), - "vinculacion" => intval($solicitud['vinculacion']), - "transportista_id" => intval($solicitud['transportista_id']), - - "created_at" => $createdAt, - "updated_at" => $updatedAt, - "transporte_id" => null, - "chofer_id" => intval($solicitud['chofer_id']), - "foto_solicitud_url"=> strval($solicitud['foto_solicitud_url']), - "proveedor_clave" => strval($solicitud['proveedor_clave']), - "partidas" => $partidas - ]; + $payload = [ + "id_solicitud" => intval($solicitud['id_solicitud']), + "id_importador" => intval($solicitud['id_importador']), + "aduana" => strval($solicitud['aduana']), + "patente" => strval($solicitud['patente']), + "anexo22_apendice" => strval($solicitud['anexo22_apendice']), + "numero_factura" => strval($solicitud['numero_factura']), + "fecha_factura" => $fechaFactura, + "numero_pedimento" => "", // La API lo rellenará + "incoterm" => strval($solicitud['incoterm']), + "pais_proveedor" => strval($solicitud['pais_proveedor']), + "tipo_moneda" => strval($solicitud['tipo_moneda']), + "valor_factura" => floatval($solicitud['valor_factura']), + "vinculacion" => intval($solicitud['vinculacion']), + "transportista_id" => intval($solicitud['transportista_id']), + "created_at" => $createdAt, + "updated_at" => $updatedAt, + "transporte_id" => null, + "chofer_id" => intval($solicitud['chofer_id']), + "foto_solicitud_url"=> strval($solicitud['foto_solicitud_url']), + "proveedor_clave" => strval($solicitud['proveedor_clave']), + "partidas" => $partidas + ]; $jsonPayload = json_encode($payload); // 3.6) Preparar cURL para hacer POST a /pedimentos/crearPedimento @@ -1350,7 +1328,7 @@ function update_status() { CURLOPT_CUSTOMREQUEST => 'POST', CURLOPT_HTTPHEADER => [ "Authorization: $token", - 'Content-Type: application/json' + 'Content-Type: application/json' ], CURLOPT_POSTFIELDS => $jsonPayload, CURLOPT_RETURNTRANSFER => true, @@ -1369,17 +1347,9 @@ function update_status() { $numeroPedimento = $decoded['pedimento']['PEDIMENTO']; // 3.8) Actualizar localmente el campo numero_pedimento - $sqlUpdPed = " - UPDATE dbo.solicitud_importacion_factura - SET numero_pedimento = ? - WHERE id_solicitud = ? - AND id_importador = ? - "; - $stmtUpdPed = sqlsrv_query( - $conn, - $sqlUpdPed, - [$numeroPedimento, $id, $_SESSION['usuario_id']] - ); + $sqlUpdPed = "UPDATE dbo.solicitud_importacion_factura SET numero_pedimento = ? WHERE id_solicitud = ? AND id_importador = ?"; + $stmtUpdPed = sqlsrv_query($conn, $sqlUpdPed, [$numeroPedimento, $id, $_SESSION['usuario_id']]); + if ($stmtUpdPed === false) { error_log("[update_status] Error al actualizar numero_pedimento en BD: " . print_r(sqlsrv_errors(), true)); } @@ -1387,9 +1357,9 @@ function update_status() { error_log("[update_status] Pedimento creado con éxito para solicitud $id → HTTP $httpPed → $respPed"); echo json_encode([ - 'success' => true, - 'pedimento' => $decoded['pedimento'], - 'numeroPedimentoLocal' => $numeroPedimento + 'success' => true, + 'pedimento' => $decoded['pedimento'], + 'numeroPedimentoLocal' => $numeroPedimento ]); exit; } else { @@ -1408,7 +1378,8 @@ function update_status() { } /** Envía notificación de cambio de estado de solicitud de importación **/ -function enviarNotificacionCambioStatus($email, $nombreCompleto, $datosSolicitud, $esCorreoExtra = false) { +function enviarNotificacionCambioStatus($email, $nombreCompleto, $datosSolicitud, $esCorreoExtra = false) +{ // Validar datos de entrada if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) { error_log("❌ Email inválido para notificación: $email"); @@ -1425,13 +1396,13 @@ function enviarNotificacionCambioStatus($email, $nombreCompleto, $datosSolicitud try { // Configuración SMTP $mail->isSMTP(); - $mail->Host = 'secure.emailsrvr.com'; - $mail->SMTPAuth = true; - $mail->Username = 'noreply@aduanasoft.com.mx'; - $mail->Password = $_ENV['SMTP_PASS'] ?? ''; + $mail->Host = 'secure.emailsrvr.com'; + $mail->SMTPAuth = true; + $mail->Username = 'noreply@aduanasoft.com.mx'; + $mail->Password = $_ENV['SMTP_PASS'] ?? ''; $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; - $mail->Port = 587; - $mail->CharSet = 'UTF-8'; + $mail->Port = 587; + $mail->CharSet = 'UTF-8'; // Configuración del mensaje $mail->setFrom('noreply@aduanasoft.com.mx', 'SIIH | AduanaSoft'); @@ -1484,32 +1455,34 @@ function obtenerInfoStatus($status) { ]; return $statusMap[$status] ?? [ - 'emoji' => '📝', + 'emoji' => '📝', 'descripcion' => 'Estado actualizado', - 'color' => '#6c757d' + 'color' => '#6c757d' ]; } /** Prepara los datos para el template del email **/ -function prepararDatosTemplate($datosSolicitud, $nombreCompleto, $statusInfo, $esCorreoExtra) { +function prepararDatosTemplate($datosSolicitud, $nombreCompleto, $statusInfo, $esCorreoExtra) +{ return [ - 'nombreCompleto' => htmlspecialchars($nombreCompleto ?? 'Usuario'), - 'idSolicitud' => intval($datosSolicitud['id_solicitud'] ?? 0), - 'numeroFactura' => htmlspecialchars($datosSolicitud['numero_factura'] ?? 'N/A'), - 'fechaFactura' => htmlspecialchars($datosSolicitud['fecha_factura'] ?? 'N/A'), - 'valorFactura' => number_format(floatval($datosSolicitud['valor_factura'] ?? 0), 2), - 'tipoMoneda' => htmlspecialchars($datosSolicitud['tipo_moneda'] ?? 'USD'), - 'statusEmoji' => $statusInfo['emoji'], + 'nombreCompleto' => htmlspecialchars($nombreCompleto ?? 'Usuario'), + 'idSolicitud' => intval($datosSolicitud['id_solicitud'] ?? 0), + 'numeroFactura' => htmlspecialchars($datosSolicitud['numero_factura'] ?? 'N/A'), + 'fechaFactura' => htmlspecialchars($datosSolicitud['fecha_factura'] ?? 'N/A'), + 'valorFactura' => number_format(floatval($datosSolicitud['valor_factura'] ?? 0), 2), + 'tipoMoneda' => htmlspecialchars($datosSolicitud['tipo_moneda'] ?? 'USD'), + 'statusEmoji' => $statusInfo['emoji'], 'statusDescripcion' => $statusInfo['descripcion'], - 'statusColor' => $statusInfo['color'], - 'esCorreoExtra' => $esCorreoExtra, - 'fechaActual' => date('Y-m-d H:i:s'), - 'anioActual' => date('Y') + 'statusColor' => $statusInfo['color'], + 'esCorreoExtra' => $esCorreoExtra, + 'fechaActual' => date('Y-m-d H:i:s'), + 'anioActual' => date('Y') ]; } /** Genera el HTML para la notificación **/ -function generarHtmlNotificacion($datos) { +function generarHtmlNotificacion($datos) +{ $tipoNotificacion = $datos['esCorreoExtra'] ? '