false, 'catalogos' => []]; } $usuario = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); if (!$usuario) { sqlsrv_close($conn); return ['catalogos_activos' => false, 'catalogos' => []]; } $catalogos_general = $usuario['preferencias_catalogos'] ?? 0; $tipoUsuario = $usuario['tipo_usuario'] ?? 'importador'; sqlsrv_free_stmt($stmt); // Si los catálogos están desactivados, solo mostrar obligatorios if (!$catalogos_general) { // Obtener solo catálogos obligatorios $query = "SELECT nombre, descripcion, color, ruta, accion FROM tipos_catalogos WHERE tipo_usuario = ? AND nombre IN ('Configuración', 'Cerrar sesión') ORDER BY id"; $stmt = sqlsrv_prepare($conn, $query, [$tipoUsuario]); if (!$stmt || !sqlsrv_execute($stmt)) { sqlsrv_close($conn); return ['catalogos_activos' => false, 'catalogos' => []]; } $catalogos = []; while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { $catalogos[] = [ 'nombre' => $row['nombre'], 'descripcion' => $row['descripcion'], 'color' => $row['color'], 'ruta' => $row['ruta'], 'accion' => $row['accion'], 'visible' => true, 'obligatorio' => true ]; } sqlsrv_free_stmt($stmt); sqlsrv_close($conn); return ['catalogos_activos' => false, 'catalogos' => $catalogos]; } // Obtener todos los catálogos para este tipo de usuario $query = "SELECT nombre, descripcion, color, ruta, accion FROM tipos_catalogos WHERE tipo_usuario = ? ORDER BY id"; $stmt = sqlsrv_prepare($conn, $query, [$tipoUsuario]); if (!$stmt || !sqlsrv_execute($stmt)) { sqlsrv_close($conn); return ['catalogos_activos' => false, 'catalogos' => []]; } // Crear array de catálogos disponibles $catalogos_disponibles = []; while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { $catalogos_disponibles[] = [ 'nombre' => $row['nombre'], 'descripcion' => $row['descripcion'], 'color' => $row['color'], 'ruta' => $row['ruta'], 'accion' => $row['accion'], 'campo_bd' => strtolower(str_replace([' ', 'ó', 'ú', 'á', 'é', 'í'], ['_', 'o', 'u', 'a', 'e', 'i'], $row['nombre'])) ]; } sqlsrv_free_stmt($stmt); // Obtener preferencias específicas del usuario $preferencias = []; switch ($tipoUsuario) { case 'importador': $query = "SELECT * FROM preferencias_catalogos_usuario WHERE id_usuario = ?"; $stmt = sqlsrv_prepare($conn, $query, [$idUsuario]); if ($stmt && sqlsrv_execute($stmt)) { $preferenciasRow = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC); if ($preferenciasRow) { $preferencias = $preferenciasRow; } sqlsrv_free_stmt($stmt); } break; // Aquí agregarías otros casos cuando implementes otros tipos de usuario } // Determinar qué catálogos mostrar $catalogos_visibles = []; foreach ($catalogos_disponibles as $catalogo) { $campo = $catalogo['campo_bd']; $esObligatorio = in_array($catalogo['nombre'], ['Configuración', 'Cerrar sesión']); if ($esObligatorio) { // Catálogos obligatorios siempre visibles $catalogo['visible'] = true; $catalogo['obligatorio'] = true; } else { // Verificar si está activado en preferencias $catalogo['visible'] = isset($preferencias[$campo]) && $preferencias[$campo] == 1; $catalogo['obligatorio'] = false; } if ($catalogo['visible']) { $catalogos_visibles[] = $catalogo; } } sqlsrv_close($conn); return [ 'catalogos_activos' => true, 'catalogos' => $catalogos_visibles, 'tipo_usuario' => $tipoUsuario ]; } // Función para obtener icono según el nombre del catálogo function obtenerIconoCatalogo($nombre) { $iconos = [ 'Locaciones' => '📍', 'Vinculación' => '🔗', 'Transportistas' => '🚚', 'Transportes' => '🚛', 'Choferes' => '👨‍✈️', 'Proveedores' => '🏭', 'Productos frecuentes' => '⭐', 'Solicitudes importación' => '📄', 'Expediente electrónico' => '📁', 'Configuración' => '⚙️', 'Cerrar sesión' => '🚪' ]; return $iconos[$nombre] ?? '📁'; } // Función para el dashboard del importador function dashboard() { $idUsuario = $_SESSION['usuario_id'] ?? null; if (!$idUsuario) { header("Location: /IMPORTADORES/login"); exit; } // Obtener catálogos visibles $catalogosData = obtenerCatalogosVisibles($idUsuario); include __DIR__ . '/../../views/importadores/dashboard_importador.php'; } function lista() { $conn = getConnection(); // 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 "; $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"; $stmt_paises_select = sqlsrv_query($conn, $sql_paises_select); $paises = []; while ($row = sqlsrv_fetch_array($stmt_paises_select, SQLSRV_FETCH_ASSOC)) { $paises[] = $row; } include __DIR__ . '/../../views/locaciones/lista.php'; } function vincular() { if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'importador') { header('Location: /IMPORTADORES/login'); exit; } $conn = getConnection(); $id_importador = $_SESSION['usuario_id']; $id_agencia = (int) $_GET['id']; // Verificar si ya existe una solicitud pendiente $checkSql = "SELECT COUNT(*) AS total FROM solicitudes_vinculacion WHERE id_importador = ? AND id_agencia = ? AND estado = 'PENDIENTE'"; $checkParams = [$id_importador, $id_agencia]; $checkStmt = sqlsrv_query($conn, $checkSql, $checkParams); if ($checkStmt && $row = sqlsrv_fetch_array($checkStmt, SQLSRV_FETCH_ASSOC)) { if ($row['total'] > 0) { header('Location: /IMPORTADORES/vinculaciones/nuevaVinculacion?error=pending_request'); exit; } } // Obtener información del importador y la agencia para el correo $infoSql = "SELECT u.nombre AS nombre_importador, u.email AS email_importador, a.nombre_agencia, a.email AS email_agencia, admin.email AS admin_email, admin.nombre AS admin_nombre FROM usuarios_sistema u CROSS JOIN agencias_aduanales a LEFT JOIN usuarios_sistema admin ON a.id_administrador = admin.id_usuario WHERE u.id_usuario = ? AND a.id_agencia = ? "; $infoStmt = sqlsrv_query($conn, $infoSql, [$id_importador, $id_agencia]); $info = sqlsrv_fetch_array($infoStmt, SQLSRV_FETCH_ASSOC); // Insertar la nueva solicitud $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); if ($stmt && sqlsrv_execute($stmt)) { // Enviar notificación al administrador de la agencia if (!empty($info['admin_email'])) { $mail = new PHPMailer(true); try { $mail->isSMTP(); $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->setFrom('noreply@aduanasoft.com.mx', 'SIIH | Sistema Integral para Importadores de Hidrocarburos'); $mail->addAddress($info['admin_email']); $mail->CharSet = 'UTF-8'; $mail->isHTML(true); $mail->Subject = 'Nueva solicitud de vinculación en SIIH'; $mail->Body = "

¡Nueva solicitud de vinculación!

El importador {$info['nombre_importador']} ha solicitado vincularse con su agencia {$info['nombre_agencia']}.

Correo del importador: {$info['email_importador']}

Por favor, revise la solicitud en su panel de administración para aprobarla o rechazarla.

© " . date('Y') . " SIIH · Sistema Integral para Importadores de Hidrocarburos
"; $mail->send(); } catch (Exception $e) { error_log("Error al enviar correo: " . $mail->ErrorInfo); } } header('Location: /IMPORTADORES/vinculaciones/nuevaVinculacion?success=sended_request'); exit; } else { header('Location: /IMPORTADORES/vinculaciones/nuevaVinculacion?error=failed_request'); exit; } } function cancelarVinculacion() { if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'importador') { header('Location: /IMPORTADORES/login'); exit; } $conn = getConnection(); $id_importador = $_SESSION['usuario_id']; $id_agencia = (int) $_GET['id']; // Obtener información para el correo $infoSql = "SELECT u.nombre AS nombre_importador, u.email AS email_importador, a.nombre_agencia FROM solicitudes_vinculacion sv JOIN usuarios_sistema u ON sv.id_importador = u.id_usuario JOIN agencias_aduanales a ON sv.id_agencia = a.id_agencia WHERE sv.id_importador = ? AND sv.id_agencia = ? AND sv.estado = 'PENDIENTE'"; $infoStmt = sqlsrv_query($conn, $infoSql, [$id_importador, $id_agencia]); $info = sqlsrv_fetch_array($infoStmt, SQLSRV_FETCH_ASSOC); $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); if ($stmt && sqlsrv_execute($stmt)) { // Enviar notificación al importador if (!empty($info['email_importador'])) { $mail = new PHPMailer(true); try { $mail->isSMTP(); $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->setFrom('noreply@aduanasoft.com.mx', 'SIIH | Sistema Integral para Importadores de Hidrocarburos'); $mail->addAddress($info['email_importador']); $mail->CharSet = 'UTF-8'; $mail->isHTML(true); $mail->Subject = 'Cancelación de solicitud de vinculación en SIIH'; $mail->Body = "

Solicitud cancelada

Estimado/a {$info['nombre_importador']},

Has cancelado tu solicitud de vinculación con la agencia {$info['nombre_agencia']}.

Si esto fue un error, puedes volver a solicitar la vinculación desde tu panel de importador.

© " . date('Y') . " SIIH · Sistema Integral para Importadores de Hidrocarburos
"; $mail->send(); } catch (Exception $e) { error_log("Error al enviar correo: " . $mail->ErrorInfo); } } header('Location: /IMPORTADORES/vinculaciones/nuevaVinculacion?success=cancelled'); exit; } } function desvincularUsuario() { if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'importador') { header('Location: /IMPORTADORES/login'); exit; } // Verificar que se recibió el ID de la relación $id_relacion = $_GET['id'] ?? null; if (!$id_relacion || !is_numeric($id_relacion)) { header('Location: /IMPORTADORES/vinculaciones/vinculacionesUsuario?error=invalid_id'); exit; } $conn = getConnection(); try { $stmtActualizarAgencia = null; // Iniciar transacción 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, u.email as importador_email, aa.nombre_agencia, aa.email as agencia_email, admin.email as admin_email, admin.nombre as admin_nombre 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 LEFT JOIN usuarios_sistema admin ON aa.id_administrador = admin.id_usuario WHERE ia.id_relacion = ? AND ia.id_importador = ? "; $stmtVerificar = sqlsrv_query($conn, $sqlVerificar, [$id_relacion, $_SESSION['usuario_id']]); // Verificar si la consulta fue exitosa if ($stmtVerificar === false) { $errors = sqlsrv_errors(); error_log("Error en consulta verificar: " . print_r($errors, true)); throw new Exception('Error en la consulta de verificación'); } $relacion = sqlsrv_fetch_array($stmtVerificar, SQLSRV_FETCH_ASSOC); if (!$relacion) { throw new Exception('Relación no encontrada o no tienes permisos para desvincularla'); } if ($relacion['activo'] == 0) { throw new Exception('Esta relación ya está inactiva'); } // 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 = ? "; $stmtDesactivar = sqlsrv_query($conn, $sqlDesactivar, [$id_relacion, $_SESSION['usuario_id']]); if ($stmtDesactivar === false) { $errors = sqlsrv_errors(); error_log("Error en actualización: " . print_r($errors, true)); throw new Exception('Error al desactivar la relación'); } // Verificar que se actualizó al menos una fila $filasAfectadas = sqlsrv_rows_affected($stmtDesactivar); if ($filasAfectadas === 0) { throw new Exception('No se pudo actualizar la relación'); } // 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 = ?"; $stmtActualizarAgencia = sqlsrv_query($conn, $sqlActualizarAgencia, [$_SESSION['usuario_id']]); if ($stmtActualizarAgencia === false) { $errors = sqlsrv_errors(); error_log("Error al actualizar agencia en uso: " . print_r($errors, true)); throw new Exception('Error al actualizar la agencia en uso'); } } // Enviar notificaciones por correo if (!empty($relacion['importador_email'])) { // Notificación al importador $mailImportador = new PHPMailer(true); try { $mailImportador->isSMTP(); $mailImportador->Host = 'secure.emailsrvr.com'; $mailImportador->SMTPAuth = true; $mailImportador->Username = 'noreply@aduanasoft.com.mx'; $mailImportador->Password = $_ENV['SMTP_PASS']; $mailImportador->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; $mailImportador->Port = 587; $mailImportador->setFrom('noreply@aduanasoft.com.mx', 'SIIH | Sistema Integral para Importadores de Hidrocarburos'); $mailImportador->addAddress($relacion['importador_email']); $mailImportador->CharSet = 'UTF-8'; $mailImportador->isHTML(true); $mailImportador->Subject = 'Confirmación de desvinculación en SIIH'; $mailImportador->Body = "

Desvinculación completada

Estimado/a {$relacion['importador_nombre']},

Has sido desvinculado de la agencia {$relacion['nombre_agencia']}.

Fecha de desvinculación: " . date('d/m/Y H:i:s') . "

Si esto es un error, por favor contacta al administrador de la agencia.

© " . date('Y') . " SIIH · Sistema Integral para Importadores de Hidrocarburos
"; $mailImportador->send(); } catch (Exception $e) { error_log("Error al enviar correo a importador: " . $mailImportador->ErrorInfo); } } if (!empty($relacion['admin_email'])) { // Notificación al administrador de la agencia $mailAdmin = new PHPMailer(true); try { $mailAdmin->isSMTP(); $mailAdmin->Host = 'secure.emailsrvr.com'; $mailAdmin->SMTPAuth = true; $mailAdmin->Username = 'noreply@aduanasoft.com.mx'; $mailAdmin->Password = $_ENV['SMTP_PASS']; $mailAdmin->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; $mailAdmin->Port = 587; $mailAdmin->setFrom('noreply@aduanasoft.com.mx', 'SIIH | Sistema Integral para Importadores de Hidrocarburos'); $mailAdmin->addAddress($relacion['admin_email']); $mailAdmin->CharSet = 'UTF-8'; $mailAdmin->isHTML(true); $mailAdmin->Subject = 'Notificación de desvinculación en SIIH'; $mailAdmin->Body = "

Notificación de desvinculación

Estimado/a {$relacion['admin_nombre']},

El importador {$relacion['importador_nombre']} se ha desvinculado de su agencia {$relacion['nombre_agencia']}.

Correo del importador: {$relacion['importador_email']}

Fecha de desvinculación: " . date('d/m/Y H:i:s') . "

© " . date('Y') . " SIIH · Sistema Integral para Importadores de Hidrocarburos
"; $mailAdmin->send(); } catch (Exception $e) { error_log("Error al enviar correo a administrador: " . $mailAdmin->ErrorInfo); } } // Limpiar statements if (isset($stmtVerificar) && is_resource($stmtVerificar)) { sqlsrv_free_stmt($stmtVerificar); } if (isset($stmtDesactivar) && is_resource($stmtDesactivar)) { sqlsrv_free_stmt($stmtDesactivar); } if (isset($stmtActualizarAgencia) && is_resource($stmtActualizarAgencia)) { sqlsrv_free_stmt($stmtActualizarAgencia); } // Confirmar transacción sqlsrv_commit($conn); sqlsrv_close($conn); header('Location: /IMPORTADORES/vinculaciones/vinculacionesUsuario?success=unlinked'); exit; } catch (Exception $e) { // Revertir transacción en caso de error sqlsrv_rollback($conn); sqlsrv_close($conn); header('Location: /IMPORTADORES/vinculaciones/vinculacionesUsuario?error=unlinked_failed&msg=' . urlencode($e->getMessage())); exit; } } /** Función para cambiar la agencia activa del usuario **/ function cambiarAgenciaActiva() { if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'importador') { header('Location: /IMPORTADORES/login'); exit; } if (!isset($_GET['id']) || !is_numeric($_GET['id'])) { header("Location: /IMPORTADORES/vinculaciones/vinculacionesusuario?error=invalid_id"); exit; } $id_agencia = intval($_GET['id']); $id_usuario = $_SESSION['usuario_id']; $conn = getConnection(); // Validar que el importador está vinculado a esta agencia $sqlVerificacion = "SELECT 1 FROM importador_agencia WHERE id_importador = ? AND id_agencia = ? AND activo = 1"; $stmtVerificacion = sqlsrv_query($conn, $sqlVerificacion, [$id_usuario, $id_agencia]); if ($stmtVerificacion === false || !sqlsrv_fetch($stmtVerificacion)) { header("Location: /IMPORTADORES/vinculaciones/vinculacionesusuario?error=invalid_agency"); exit; } // Actualizar campo id_agencia_en_uso $sqlUpdate = "UPDATE usuarios_sistema SET id_agencia_en_uso = ? WHERE id_usuario = ?"; $stmtUpdate = sqlsrv_query($conn, $sqlUpdate, [$id_agencia, $id_usuario]); if ($stmtUpdate === false) { header("Location: /IMPORTADORES/vinculaciones/vinculacionesusuario?error=agency_changed_failed"); exit; } // Opcional: actualizar también la sesión si lo usas en tu lógica $_SESSION['id_agencia_en_uso'] = $id_agencia; // Redirigir con éxito header("Location: /IMPORTADORES/vinculaciones/vinculacionesusuario?success=agency_changed"); exit; }