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;
}