Files
MVE/app/controllers/administrador.php
2025-07-08 09:05:48 -06:00

1091 lines
42 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
require_once __DIR__ . '/../../config/database.php';
require_once __DIR__ . '/../helpers/env.php';
require_once __DIR__ . '/../helpers/crypto.php';
require_once __DIR__ . '/../helpers/session.php';
require_once __DIR__ . '/../../vendor/autoload.php';
require_once __DIR__ . '/../helpers/bitacoras.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
loadEnv();
function dashboard()
{
if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'super_admin') {
header('Location: /IMPORTADORES/login');
exit;
}
include __DIR__ . '/../../views/admin/dashboard_admin.php';
}
/** USUARIOS **/
function aprobarUsuarios()
{
if (!($_SESSION['usuario_id'] ?? false) || $_SESSION['tipo_usuario'] !== 'super_admin') {
header('Location: /IMPORTADORES/login');
exit;
}
$conn = getConnection();
$sql = "SELECT request_id, company_name, rfc, email, phone, request_date, opinion_file
FROM solicitudes_importadores
WHERE request_status = 'pending'
ORDER BY request_date DESC
";
$stmt = sqlsrv_query($conn, $sql);
$solicitudes = [];
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$solicitudes[] = $row;
}
include __DIR__ . '/../../views/admin/aprobar_usuarios.php';
}
function aprobar_usuario()
{
$conn = getConnection();
$id = $_GET['id'] ?? null;
if (!$id || !is_numeric($id)) {
header("Location: /IMPORTADORES/administrador/aprobarUsuarios?error=invalid_id");
exit;
}
// Verificar sesión del usuario administrador
if (!isset($_SESSION['usuario_id']) || empty($_SESSION['usuario_id'])) {
header("Location: /IMPORTADORES/administrador/aprobarUsuarios?error=session_error");
exit;
}
try {
// Iniciar transacción
sqlsrv_begin_transaction($conn);
// Obtener la solicitud
$sql = "SELECT * FROM solicitudes_importadores WHERE request_id = ?";
$stmt = sqlsrv_query($conn, $sql, [$id]);
if (!$stmt) {
throw new Exception("Error en consulta de solicitud: " . print_r(sqlsrv_errors(), true));
}
$solicitud = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (!$solicitud) {
throw new Exception("Solicitud no encontrada");
}
// Validar que no haya sido aprobada ya
if ($solicitud['request_status'] === 'approved') {
header("Location: /IMPORTADORES/administrador/aprobarUsuarios?error=already_approved");
exit;
}
// Preparar datos con validación
$nombre = !empty($solicitud['company_name']) ? decrypt($solicitud['company_name']) : null;
$email = $solicitud['email'] ?? null;
$rfc = !empty($solicitud['rfc']) ? decrypt($solicitud['rfc']) : null;
$telefono = $solicitud['phone'] ?? null;
// Validar datos requeridos
if (empty($nombre) || empty($email) || empty($rfc)) {
throw new Exception("Datos requeridos faltantes: nombre, email o RFC");
}
$tipo = 'importador';
// Generar contraseña aleatoria
$password_plain = bin2hex(random_bytes(5));
$password_hash = password_hash($password_plain, PASSWORD_DEFAULT);
// Encriptar datos sensibles
$nombre_encrypt = encrypt($nombre);
$email_encrypt = encrypt($email);
// Insertar en usuarios_sistema y obtener ID en la misma consulta
$sqlInsert = "INSERT INTO usuarios_sistema
(nombre, email, password_hash, tipo_usuario, activo, creado_en, dos_factores, creado_por, preferencias_catalogos)
OUTPUT INSERTED.id_usuario
VALUES (?, ?, ?, ?, 1, GETDATE(), 0, ?, 1)
";
$stmtInsert = sqlsrv_query($conn, $sqlInsert, [
$nombre_encrypt, $email_encrypt, $password_hash, $tipo, $_SESSION['usuario_id']
]);
if (!$stmtInsert) {
throw new Exception("Error al insertar usuario: " . print_r(sqlsrv_errors(), true));
}
// Obtener el ID directamente del OUTPUT
$idUsuarioRow = sqlsrv_fetch_array($stmtInsert, SQLSRV_FETCH_ASSOC);
$id_usuario = $idUsuarioRow['id_usuario'] ?? null;
if (!$id_usuario) {
throw new Exception("No se pudo obtener el ID del usuario creado. ID obtenido: " . var_export($idUsuarioRow, true));
}
// Insertar en informacion_general
$sqlInfo = "INSERT INTO informacion_general (id_usuario, nombre, rfc, correo, telefono) VALUES (?, ?, ?, ?, ?)";
$stmtInfo = sqlsrv_query($conn, $sqlInfo, [
$id_usuario, $nombre, $rfc, $email, $telefono
]);
if (!$stmtInfo) {
throw new Exception("Error al insertar información general: " . print_r(sqlsrv_errors(), true));
}
// Insertar en preferencias de catalogos
$sqlPref = "INSERT INTO preferencias_catalogos_usuario
(id_usuario, locaciones, vinculacion, transportistas, transportes, choferes, proveedores,
productos_frecuentes, solicitudes_importacion, expediente_electronico, configuracion, cerrar_sesion)
VALUES (?, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
";
$stmtPref = sqlsrv_query($conn, $sqlPref, [$id_usuario]);
if (!$stmtPref) {
throw new Exception("Error al insertar preferencias de catalogos: " . print_r(sqlsrv_errors(), true));
}
// Actualizar solicitud
$sqlUpdate = "UPDATE solicitudes_importadores
SET request_status = 'approved',
approval_date = GETDATE(),
approved_by = ?
WHERE request_id = ?
";
$stmtUpdate = sqlsrv_query($conn, $sqlUpdate, [$_SESSION['usuario_id'], $id]);
if (!$stmtUpdate) {
throw new Exception("Error al actualizar solicitud: " . print_r(sqlsrv_errors(), true));
}
// Confirmar transacción
sqlsrv_commit($conn);
// Enviar correo al importador (fuera de la transacción)
$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($email);
$mail->CharSet = 'UTF-8';
$mail->isHTML(true);
$mail->Subject = 'Tu acceso a la plataforma SIIH ha sido autorizado';
$mail->Body = "
<div style='font-family: Segoe UI, sans-serif; background-color: #f4f6f9; padding: 40px;'>
<div style='max-width: 600px; margin: auto; background: #fff; border: 1px solid #ddd; border-radius: 10px; overflow: hidden;'>
<div style='background: linear-gradient(to right, #003366, #0055A5); padding: 20px; text-align: center;'>
<h2 style='color: white;'>¡Bienvenido a SIIH!</h2>
</div>
<div style='padding: 30px; color: #333; font-size: 16px;'>
<p>Tu registro como importador ha sido aprobado. Aquí tienes tus credenciales de acceso:</p>
<p><strong>Correo:</strong> $email</p>
<p><strong>Contraseña:</strong> $password_plain</p>
<p>📌 Te recomendamos cambiar tu contraseña una vez que ingreses al sistema.</p>
<p><a href='http://siih.aduanasoft.com/IMPORTADORES/login' class='btn btn-primary'>Ir al sistema</a></p>
</div>
<div style='background: #e9ecef; text-align: center; padding: 15px; font-size: 13px; color: #666;'>
&copy; " . date('Y') . " SIIH · Sistema Integral para Importadores de Hidrocarburos
</div>
</div>
</div>";
$mail->send();
// Éxito completo (usuario creado, solicitud actualizada y correo enviado)
header("Location: /IMPORTADORES/administrador/aprobarUsuarios?success=approved");
} catch (Exception $mailException) {
// Error en el correo, pero el usuario fue creado exitosamente
error_log("Error al enviar correo de bienvenida: " . $mailException->getMessage());
// Redirigir con mensaje de éxito parcial
header("Location: /IMPORTADORES/administrador/aprobarUsuarios?success=approved&warning=email_failed");
}
} catch (Exception $e) {
// Revertir transacción
sqlsrv_rollback($conn);
// Log del error para debugging
error_log("Error al aprobar usuario: " . $e->getMessage());
// Redirigir con error específico basado en el tipo de error
if (strpos($e->getMessage(), 'información general') !== false) {
header("Location: /IMPORTADORES/administrador/aprobarUsuarios?error=info_general_failed");
} elseif (strpos($e->getMessage(), 'ID del usuario') !== false) {
header("Location: /IMPORTADORES/administrador/aprobarUsuarios?error=user_id_failed");
} else {
header("Location: /IMPORTADORES/administrador/aprobarUsuarios?error=process_failed");
}
}
exit;
}
function altaUsuarios()
{
if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'super_admin') {
header('Location: /IMPORTADORES/login');
exit;
}
$conn = getConnection();
$sql = "SELECT u.*, creador.nombre as nombre_creador
FROM usuarios_sistema u
LEFT JOIN usuarios_sistema creador
ON u.creado_por = creador.id_usuario
WHERE u.activo = 1
ORDER BY u.creado_en DESC
";
$stmt = sqlsrv_query($conn, $sql);
$usuarios = [];
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$usuarios[] = $row;
}
include __DIR__ . '/../../views/admin/alta_usuarios.php';
}
function guardar_usuario()
{
if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'super_admin') {
header("Location: /IMPORTADORES/administrador/altaUsuarios?error=unauthorized");
exit;
}
$conn = getConnection();
// 1. Capturar y validar datos
$nombre = trim($_POST['nombre'] ?? '');
$email = trim($_POST['email'] ?? '');
$password = $_POST['password'] ?? '';
$tipo = $_POST['tipo_usuario'] ?? '';
if (empty($nombre) || empty($email) || empty($password) || empty($tipo)) {
header("Location: /IMPORTADORES/administrador/altaUsuarios?error=invalid_data");
exit;
}
if (!in_array($tipo, ['importador', 'super_admin'])) {
header("Location: /IMPORTADORES/administrador/altaUsuarios?error=invalid_user_type");
exit;
}
// 2. Encriptar datos sensibles
$nombre_encrypted = encrypt($nombre);
$email_encrypted = encrypt($email);
$password_hash = password_hash($password, PASSWORD_DEFAULT);
// 3. Validar duplicado por email encriptado
$sqlCheck = "SELECT COUNT(*) AS total FROM usuarios_sistema WHERE email = ?";
$stmtCheck = sqlsrv_query($conn, $sqlCheck, [$email_encrypted]);
$rowCheck = sqlsrv_fetch_array($stmtCheck, SQLSRV_FETCH_ASSOC);
if ($rowCheck['total'] > 0) {
header("Location: /IMPORTADORES/administrador/altaUsuarios?error=email_exists");
exit;
}
// 4. Insertar usuario
$sqlInsert = "INSERT INTO usuarios_sistema
(nombre, email, password_hash, tipo_usuario, activo, creado_en, dos_factores, creado_por)
OUTPUT INSERTED.id_usuario
VALUES (?, ?, ?, ?, 1, GETDATE(), 0, ?)
";
$params = [$nombre_encrypted, $email_encrypted, $password_hash, $tipo, $_SESSION['usuario_id']];
$stmtInsert = sqlsrv_query($conn, $sqlInsert, $params);
if ($stmtInsert === false) {
header("Location: /IMPORTADORES/administrador/altaUsuarios?error=save_failed");
exit;
}
// 5. Obtener ID del nuevo usuario (para posibles tablas relacionadas)
$idUsuarioRow = sqlsrv_fetch_array($stmtInsert, SQLSRV_FETCH_ASSOC);
$id_usuario = $idUsuarioRow['id_usuario'] ?? null;
// 6. Insertar en informacion_general
$sqlInfo = "INSERT INTO informacion_general (id_usuario, nombre, correo) VALUES (?, ?, ?)";
$stmtInfo = sqlsrv_query($conn, $sqlInfo, [$id_usuario, $nombre, $email]);
if (!$stmtInfo) {
throw new Exception("Error al insertar información general: " . print_r(sqlsrv_errors(), true));
}
// 7. Insertar en preferencias de catalogos
$sqlPref = "INSERT INTO preferencias_catalogos_usuario
(id_usuario, locaciones, vinculacion, transportistas, transportes, choferes, proveedores,
productos_frecuentes, solicitudes_importacion, expediente_electronico, configuracion, cerrar_sesion)
VALUES (?, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
";
$stmtPref = sqlsrv_query($conn, $sqlPref, [$id_usuario]);
if (!$stmtPref) {
throw new Exception("Error al insertar preferencias de catalogos: " . print_r(sqlsrv_errors(), true));
}
// 8. Enviar correo de bienvenida
$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($email); // Email sin encriptar para el envío
$mail->CharSet = 'UTF-8';
$mail->isHTML(true);
$mail->Subject = 'Tu acceso a la plataforma SIIH ha sido creado';
// Determinar el tipo de usuario para el mensaje
$tipoUsuarioTexto = match($tipo) {
'importador' => 'importador',
'super_admin' => 'administrador'
};
$mail->Body = "
<div style='font-family: Segoe UI, sans-serif; background-color: #f4f6f9; padding: 40px;'>
<div style='max-width: 600px; margin: auto; background: #fff; border: 1px solid #ddd; border-radius: 10px; overflow: hidden;'>
<div style='background: linear-gradient(to right, #003366, #0055A5); padding: 20px; text-align: center;'>
<h2 style='color: white;'>¡Bienvenido a SIIH!</h2>
</div>
<div style='padding: 30px; color: #333; font-size: 16px;'>
<p>Hola <strong>$nombre</strong>,</p>
<p>Se ha creado tu cuenta en la plataforma SIIH con el rol de <strong>$tipoUsuarioTexto</strong>.</p>
<p>Aquí tienes tus credenciales de acceso:</p>
<div style='background: #f8f9fa; padding: 15px; border-radius: 5px; margin: 20px 0;'>
<p><strong>Correo:</strong> $email</p>
<p><strong>Contraseña:</strong> $password</p>
</div>
<p>📌 <strong>Importante:</strong> Te recomendamos cambiar tu contraseña una vez que ingreses al sistema por primera vez.</p>
<p style='text-align: center; margin-top: 30px;'>
<a href='http://siih.aduanasoft.com/IMPORTADORES/login'
style='background: #0055A5; color: white; padding: 12px 25px; text-decoration: none; border-radius: 5px; display: inline-block;'>
Acceder al Sistema
</a>
</p>
</div>
<div style='background: #e9ecef; text-align: center; padding: 15px; font-size: 13px; color: #666;'>
&copy; " . date('Y') . " SIIH · Sistema Integral para Importadores de Hidrocarburos
</div>
</div>
</div>";
$mail->send();
// Log de éxito (opcional)
error_log("Correo de bienvenida enviado exitosamente a: $email");
} catch (Exception $e) {
// Log del error pero no detener el proceso
error_log("Error al enviar correo de bienvenida a $email: {$mail->ErrorInfo}");
// Opcional: Puedes mostrar una advertencia al usuario
$_SESSION['mensaje_advertencia'] = "Usuario creado exitosamente, pero no se pudo enviar el correo de bienvenida.";
}
// 7. Redirigir con mensaje de éxito
$_SESSION['mensaje_exito'] = "Usuario creado exitosamente. Se ha enviado un correo con las credenciales de acceso.";
header("Location: /IMPORTADORES/administrador/altaUsuarios?success=created");
exit;
}
function usuariosInactivos()
{
if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'super_admin') {
header('Location: /IMPORTADORES/login');
exit;
}
$conn = getConnection();
$sql = "SELECT u.*, creador.nombre as nombre_creador
FROM usuarios_sistema u
LEFT JOIN usuarios_sistema creador
ON u.creado_por = creador.id_usuario
WHERE u.activo = 0
ORDER BY u.creado_en DESC
";
$stmt = sqlsrv_query($conn, $sql);
$usuarios = [];
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$usuarios[] = $row;
}
include __DIR__ . '/../../views/admin/usuarios_inactivos.php';
}
/** AGENCIAS **/
function aprobarAgencias()
{
if (!($_SESSION['usuario_id'] ?? false) || $_SESSION['tipo_usuario'] !== 'super_admin') {
header('Location: /IMPORTADORES/login');
exit;
}
$conn = getConnection();
$sql = "SELECT request_id, agencia_name, rfc, email, phone, direccion, request_date, opinion_file
FROM solicitudes_agencias
WHERE request_status = 'pending'
ORDER BY request_date DESC
";
$stmt = sqlsrv_query($conn, $sql);
$solicitudes = [];
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$solicitudes[] = $row;
}
include __DIR__ . '/../../views/admin/aprobar_agencias.php';
}
function aprobar_agencia()
{
$conn = getConnection();
$id = $_GET['id'] ?? null;
$usuario_id = $_SESSION['usuario_id'];
if (!$id || !is_numeric($id)) {
die("❌ ID inválido.");
}
// Obtener la solicitud
$sql = "SELECT * FROM solicitudes_agencias WHERE request_id = ?";
$stmt = sqlsrv_query($conn, $sql, [$id]);
$solicitud = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (!$solicitud) {
die("❌ Solicitud no encontrada.");
}
// Validar que no haya sido aprobada ya
if ($solicitud['request_status'] === 'approved') {
die("⚠️ Esta solicitud ya fue aprobada.");
}
// Preparar datos
$nombre = decrypt($solicitud['agencia_name']);
$email = $solicitud['email'];
$rfc = decrypt($solicitud['rfc']);
$phone = $solicitud['phone'];
$direccion = $solicitud['direccion'];
// Preparar datos de administrador de agencia
$admin_name = decrypt($solicitud['admin_name']);
$admin_email = $solicitud['admin_email'];
$tipo = 'admin_agencia';
// Generar contraseña aleatoria
$password_plain = bin2hex(random_bytes(5));
$password_hash = password_hash($password_plain, PASSWORD_DEFAULT);
// Encriptar datos sensibles
$nombre_encrypt = encrypt($nombre);
$email_encrypt = encrypt($email);
$admin_name_encrypt = encrypt($admin_name);
$admin_email_encrypt = encrypt($admin_email);
// Insertar en agencias_aduanales
$sqlInsert = "INSERT INTO agencias_aduanales
(nombre_agencia, rfc_agencia, direccion, telefono, email, creado_en, creado_por)
VALUES (?, ?, ?, ?, ?, GETDATE(), ?)
";
$stmtInsert = sqlsrv_query($conn, $sqlInsert, [
$nombre_encrypt, $rfc, $direccion, $phone, $email_encrypt, $usuario_id
]);
if (!$stmtInsert) {
die("❌ Error al crear agencia: " . print_r(sqlsrv_errors(), true));
}
// Obtener ID de la agencia recién creada
$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;
if (!$id_agencia) {
die("❌ No se pudo obtener el ID de la agencia recién creada.");
}
// Insertar en usuarios_sistema
$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
]);
if (!$stmtInsert2) {
die("❌ Error al crear usuario administrador: " . print_r(sqlsrv_errors(), true));
}
// Obtener ID del nuevo usuario
$sqlGetId = "SELECT SCOPE_IDENTITY() AS id_usuario";
$stmtGetId = sqlsrv_query($conn, $sqlGetId);
$idUsuarioRow = sqlsrv_fetch_array($stmtGetId, SQLSRV_FETCH_ASSOC);
$id_usuario = $idUsuarioRow['id_usuario'] ?? null;
if (!$id_usuario) {
die("❌ No se pudo obtener el ID del usuario recién creado.");
}
// Actualizar agencia con el ID del administrador
$sqlUpdateAgencia = "UPDATE agencias_aduanales SET id_administrador = ? WHERE id_agencia = ?";
$stmtUpdateAgencia = sqlsrv_query($conn, $sqlUpdateAgencia, [$id_usuario, $id_agencia]);
if (!$stmtUpdateAgencia) {
die("❌ Error al actualizar agencia con administrador: " . print_r(sqlsrv_errors(), true));
}
// Insertar en informacion_general
$sqlInfo = "INSERT INTO informacion_general (id_usuario, nombre, correo) VALUES (?, ?, ?)";
$stmtInfo = sqlsrv_query($conn, $sqlInfo, [
$id_usuario, $admin_name, $admin_email
]);
if (!$stmtInfo) {
die("❌ Error al insertar información general: " . print_r(sqlsrv_errors(), true));
}
// Actualizar solicitud
$sqlUpdate = "UPDATE solicitudes_agencias
SET request_status = 'approved',
approval_date = GETDATE(),
approved_by = ?
WHERE request_id = ?";
$stmtUpdate = sqlsrv_query($conn, $sqlUpdate, [$usuario_id, $id]);
if (!$stmtUpdate) {
die("❌ Error al actualizar solicitud: " . print_r(sqlsrv_errors(), true));
}
// Enviar correo a la agencia
$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($admin_email);
$mail->CharSet = 'UTF-8';
$mail->isHTML(true);
$mail->Subject = 'Te asignaron como administrador de agencia en SIIH';
$mail->Body = "
<div style='font-family: Segoe UI, sans-serif; background-color: #f4f6f9; padding: 40px;'>
<div style='max-width: 600px; margin: auto; background: #fff; border: 1px solid #ddd; border-radius: 10px; overflow: hidden;'>
<div style='background: linear-gradient(to right, #003366, #0055A5); padding: 20px; text-align: center;'>
<h2 style='color: white;'>¡Bienvenido a SIIH!</h2>
</div>
<div style='padding: 30px; color: #333; font-size: 16px;'>
<p>Te asignaron como administrador de la agencia <strong>$nombre</strong></p>
<p><strong>Correo:</strong> $admin_email</p>
<p><strong>Contraseña:</strong> $password_plain</p>
<p>📌 Te recomendamos cambiar tu contraseña una vez que ingreses al sistema.</p>
<p><a href='http://siih.aduanasoft.com/IMPORTADORES/login' style='background: #0055A5; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;'>Ir al sistema</a></p>
</div>
<div style='background: #e9ecef; text-align: center; padding: 15px; font-size: 13px; color: #666;'>
&copy; " . date('Y') . " SIIH · Sistema Integral para Importadores de Hidrocarburos
</div>
</div>
</div>";
$mail->send();
} catch (Exception $e) {
error_log("Error al enviar correo: {$mail->ErrorInfo}");
}
// Registrar en bitácora
registrar_bitacora_agencia($id_agencia, $nombre, 'CREACION', $usuario_id);
header("Location: /IMPORTADORES/administrador/agenciasActivas");
exit;
}
function altaAgencias()
{
if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'super_admin') {
header('Location: /IMPORTADORES/login');
exit;
}
$conn = getConnection();
$sql = "SELECT * FROM agencias_aduanales ORDER BY creado_en DESC";
$stmt = sqlsrv_query($conn, $sql);
$agencias = [];
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$agencias[] = $row;
}
include __DIR__ . '/../../views/admin/alta_agencias.php';
}
function guardar_agencia()
{
if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'super_admin') {
header("Location: /IMPORTADORES/administrador/altaAgencias?error=unauthorized");
exit;
}
$conn = getConnection();
try {
if (!sqlsrv_begin_transaction($conn)) {
throw new Exception("Error al iniciar transacción");
}
// 1⃣ Captura y validación de datos
$nombre_agencia = trim($_POST['nombre_agencia'] ?? '');
$rfc_agencia = trim($_POST['rfc_agencia'] ?? '');
$correo_agencia = trim($_POST['correo'] ?? '');
$telefono = trim($_POST['telefono'] ?? '');
$direccion = trim($_POST['direccion'] ?? '');
$nombre_admin = trim($_POST['nombre_admin'] ?? '');
$correo_admin = trim($_POST['correo_admin'] ?? '');
if (empty($nombre_agencia) || empty($rfc_agencia) || empty($correo_agencia) ||
empty($telefono) || empty($direccion) || empty($nombre_admin) || empty($correo_admin)) {
throw new Exception("Datos incompletos");
}
// 2⃣ Verificar función de encriptación
if (!function_exists('encrypt')) {
throw new Exception("Función de encriptación no disponible");
}
// Encriptar datos
$nombre_agencia_enc = encrypt($nombre_agencia);
$correo_agencia_enc = encrypt($correo_agencia);
$nombre_admin_enc = encrypt($nombre_admin);
$correo_admin_enc = encrypt($correo_admin);
// 3⃣ CREAR USUARIO ADMINISTRADOR Y OBTENER SU ID EN UNA SOLA CONSULTA
$password_plain = bin2hex(random_bytes(5));
$password_hash = password_hash($password_plain, PASSWORD_DEFAULT);
// ✅ SOLUCIÓN: INSERT con OUTPUT para obtener el ID inmediatamente
$sqlInsertAdmin = "INSERT INTO usuarios_sistema
(nombre, email, password_hash, tipo_usuario, activo, creado_en, dos_factores, creado_por)
OUTPUT INSERTED.id_usuario
VALUES (?, ?, ?, 'admin_agencia', 1, GETDATE(), 0, ?);
";
$paramsAdmin = [$nombre_admin_enc, $correo_admin_enc, $password_hash, $_SESSION['usuario_id']];
$stmtAdmin = sqlsrv_query($conn, $sqlInsertAdmin, $paramsAdmin);
if (!$stmtAdmin) {
$errors = sqlsrv_errors();
throw new Exception("Error al crear administrador: " . print_r($errors, true));
}
// Obtener el ID directamente del resultado del OUTPUT
$rowAdmin = sqlsrv_fetch_array($stmtAdmin, SQLSRV_FETCH_ASSOC);
$id_admin = $rowAdmin['id_usuario'] ?? null;
if (!$id_admin) {
throw new Exception("No se pudo obtener ID de administrador");
}
// 4⃣ CREAR AGENCIA Y OBTENER SU ID
$sqlInsertAgencia = "INSERT INTO agencias_aduanales
(nombre_agencia, rfc_agencia, direccion, telefono, email, id_administrador, activo, creado_en, creado_por)
OUTPUT INSERTED.id_agencia
VALUES (?, ?, ?, ?, ?, ?, 1, GETDATE(), ?)
";
$paramsAgencia = [$nombre_agencia_enc, $rfc_agencia, $direccion, $telefono, $correo_agencia_enc, $id_admin, $_SESSION['usuario_id']];
$stmtAgencia = sqlsrv_query($conn, $sqlInsertAgencia, $paramsAgencia);
if (!$stmtAgencia) {
$errors = sqlsrv_errors();
throw new Exception("Error al crear agencia: " . print_r($errors, true));
}
// Obtener el ID de la agencia directamente
$rowAgencia = sqlsrv_fetch_array($stmtAgencia, SQLSRV_FETCH_ASSOC);
$id_agencia = $rowAgencia['id_agencia'] ?? null;
if (!$id_agencia) {
throw new Exception("No se pudo obtener ID de agencia");
}
// 5⃣ CREAR RELACIÓN AGENTE-AGENCIA
$sqlInsertRelacion = "INSERT INTO agente_agencia
(id_agente, id_agencia, fecha_asignacion, activo, asignado_por)
VALUES (?, ?, GETDATE(), 1, ?)
";
$paramsRelacion = [$id_admin, $id_agencia, $_SESSION['usuario_id']];
$stmtRelacion = sqlsrv_query($conn, $sqlInsertRelacion, $paramsRelacion);
if (!$stmtRelacion) {
$errors = sqlsrv_errors();
throw new Exception("Error al crear relación agente-agencia: " . print_r($errors, true));
}
// 6⃣ CONFIRMAR TRANSACCIÓN ✅
if (!sqlsrv_commit($conn)) {
throw new Exception("Error al confirmar transacción");
}
// Registrar en bitácora
registrar_bitacora_agencia($id_agencia, $nombre_agencia, 'CREACION', $_SESSION['usuario_id']);
// 7⃣ Enviar correo (DESPUÉS de confirmar transacción)
if (class_exists('PHPMailer\PHPMailer\PHPMailer')) {
$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($correo_admin);
$mail->CharSet = 'UTF-8';
$mail->isHTML(true);
$mail->Subject = 'Te asignaron como administrador de una nueva agencia en SIIH';
$mail->Body = "
<div style='font-family: Segoe UI, sans-serif; background-color: #f4f6f9; padding: 40px;'>
<div style='max-width: 600px; margin: auto; background: #fff; border: 1px solid #ddd; border-radius: 10px; overflow: hidden;'>
<div style='background: linear-gradient(to right, #003366, #0055A5); padding: 20px; text-align: center;'>
<h2 style='color: white;'>¡Bienvenido a SIIH!</h2>
</div>
<div style='padding: 30px; color: #333; font-size: 16px;'>
<p>Has sido registrado como <strong>Administrador</strong> de la agencia <strong>{$nombre_agencia}</strong>.</p>
<p><strong>Correo de acceso:</strong> {$correo_admin}</p>
<p><strong>Contraseña temporal:</strong> {$password_plain}</p>
<p>📌 Te recomendamos cambiar tu contraseña al primer inicio de sesión.</p>
<p><a href='http://siih.aduanasoft.com/IMPORTADORES/login' style='background: #0055A5; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;'>Ir al sistema</a></p>
</div>
<div style='background: #e9ecef; text-align: center; padding: 15px; font-size: 13px; color: #666;'>
&copy; " . date('Y') . " SIIH · Sistema Integral para Importadores de Hidrocarburos
</div>
</div>
</div>";
$mail->send();
} catch (Exception $e) {
error_log("Error al enviar correo: " . $e->getMessage());
// No es crítico, continúa
}
}
// 8⃣ Redirigir con éxito
header("Location: /IMPORTADORES/administrador/altaAgencias?success=created");
exit;
} catch (Exception $e) {
error_log("ERROR CAPTURADO: " . $e->getMessage());
if (!sqlsrv_rollback($conn)) {
error_log("ERROR: No se pudo revertir la transacción");
} else {
error_log("Transacción revertida exitosamente");
}
header("Location: /IMPORTADORES/administrador/altaAgencias?error=save_failed");
exit;
} finally {
if ($conn) {
sqlsrv_close($conn);
}
}
}
function agenciasActivas()
{
if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'super_admin') {
header('Location: /IMPORTADORES/login');
exit;
}
$conn = getConnection();
$sql = "SELECT aa.*, u.nombre as nombre_admin
FROM agencias_aduanales aa
INNER JOIN usuarios_sistema u
ON aa.id_administrador = u.id_usuario
ORDER BY creado_en DESC
";
$stmt = sqlsrv_query($conn, $sql);
$agencias = [];
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$agencias[] = $row;
}
include __DIR__ . '/../../views/admin/agencias_activas.php';
}
function suspender()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header("Location: /IMPORTADORES/administrador/altaUsuarios?error=unauthorized");
exit;
}
$conn = getConnection();
$id = $_GET['id'] ?? null;
if (!$id || !is_numeric($id)) {
header("Location: /IMPORTADORES/administrador/altaUsuarios?error=invalid_id");
exit;
}
// Obtener el estado actual
$sqlEstado = "SELECT activo FROM usuarios_sistema WHERE id_usuario = ?";
$stmtEstado = sqlsrv_query($conn, $sqlEstado, [$id]);
if (!$stmtEstado || !($row = sqlsrv_fetch_array($stmtEstado, SQLSRV_FETCH_ASSOC))) {
header("Location: /IMPORTADORES/administrador/altaUsuarios?error=user_not_found");
exit;
}
$nuevoEstado = $row['activo'] ? 0 : 1;
// Actualizar estado
$sqlUpdate = "UPDATE usuarios_sistema SET activo = ? WHERE id_usuario = ?";
$stmtUpdate = sqlsrv_query($conn, $sqlUpdate, [$nuevoEstado, $id]);
if (!$stmtUpdate) {
header("Location: /IMPORTADORES/administrador/altaUsuarios?error=update_failed");
exit;
}
// Determinar el tipo de cambio para el mensaje
$accion = $nuevoEstado ? 'activated' : 'deactivated';
header("Location: /IMPORTADORES/administrador/altaUsuarios?success=status_$accion");
exit;
}
function activar()
{
if (!($_SESSION['tipo_usuario'] ?? false)) {
header("Location: /IMPORTADORES/administrador/usuariosInactivos?error=unauthorized");
exit;
}
$conn = getConnection();
$id = $_GET['id'] ?? null;
if (!$id || !is_numeric($id)) {
header("Location: /IMPORTADORES/administrador/usuariosInactivos?error=invalid_id");
exit;
}
// Obtener el estado actual
$sqlEstado = "SELECT activo FROM usuarios_sistema WHERE id_usuario = ?";
$stmtEstado = sqlsrv_query($conn, $sqlEstado, [$id]);
if (!$stmtEstado || !($row = sqlsrv_fetch_array($stmtEstado, SQLSRV_FETCH_ASSOC))) {
header("Location: /IMPORTADORES/administrador/usuariosInactivos?error=user_not_found");
exit;
}
$nuevoEstado = $row['activo'] ? 0 : 1;
// Actualizar estado
$sqlUpdate = "UPDATE usuarios_sistema SET activo = ? WHERE id_usuario = ?";
$stmtUpdate = sqlsrv_query($conn, $sqlUpdate, [$nuevoEstado, $id]);
if (!$stmtUpdate) {
header("Location: /IMPORTADORES/administrador/usuariosInactivos?error=update_failed");
exit;
}
// Determinar el tipo de cambio para el mensaje
$accion = $nuevoEstado ? 'activated' : 'deactivated';
header("Location: /IMPORTADORES/administrador/usuariosInactivos?success=status_$accion");
exit;
}
function reset_password()
{
if (!($_SESSION['tipo_usuario'] ?? false)) {
header("Location: /IMPORTADORES/administrador/usuariosInactivos?error=unauthorized");
exit;
}
$conn = getConnection();
$id = $_GET['id'] ?? null;
if (!$id || !is_numeric($id)) {
header("Location: /IMPORTADORES/administrador/usuariosInactivos?error=invalid_id");
exit;
}
// 🔐 Generar contraseña aleatoria de 10 caracteres
$randomPassword = bin2hex(random_bytes(5)); // genera algo como 'a8c4f1b92d'
$passwordHash = password_hash($randomPassword, PASSWORD_DEFAULT);
$sqlEmail = "SELECT email FROM usuarios_sistema WHERE id_usuario = ?";
$stmtEmail = sqlsrv_query($conn, $sqlEmail, [$id]);
$row = sqlsrv_fetch_array($stmtEmail, SQLSRV_FETCH_ASSOC);
$sql = "UPDATE usuarios_sistema SET password_hash = ? WHERE id_usuario = ?";
$stmt = sqlsrv_query($conn, $sql, [$passwordHash, $id]);
if (!$stmt) {
header("Location: /IMPORTADORES/administrador/usuariosInactivos?error=update_failed");
exit;
}
enviar_password_directamente($row['email'], $randomPassword);
// 🔁 Redirigir pasando la contraseña como parámetro temporal (solo visible para el admin)
header("Location: /IMPORTADORES/administrador/usuariosInactivos?success=update_success");
exit;
}
function enviar_password_directamente($email_encrypted, $pass)
{
$email = decrypt($email_encrypted);
$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 | AduanaSoft');
$mail->addAddress($email);
$mail->isHTML(true);
$mail->Subject = 'Nueva Contraseña de Acceso Temporal';
$mail->CharSet = 'UTF-8';
$logoURL = 'http://siih.aduanasoft.com/IMPORTADORES/public/assets/img/logo_siih.png';
$mail->Body = "
<div style='font-family: Segoe UI, sans-serif; background-color: #f4f6f9; padding: 40px;'>
<div style='max-width: 600px; margin: auto; background: #fff; border: 1px solid #ddd; border-radius: 10px; overflow: hidden;'>
<div style='background: linear-gradient(to right, #003366, #0055A5); padding: 20px; text-align: center;'>
<img src='$logoURL' alt='Logo SIIH' style='height: 80px; width: 80px; margin-bottom: 10px;'>
<h2 style='color: white;'>Contraseña restablecida</h2>
</div>
<div style='padding: 30px; color: #333; font-size: 16px;'>
<p>Tu contraseña de acceso al <strong>SIIH</strong> ha sido restablecida por el administrador.</p>
<p style='margin-top: 20px; font-size: 18px;'>
<strong>Nueva contraseña:</strong><br>
<span style='background-color: #f0f0f0; padding: 10px 15px; border-radius: 5px; display: inline-block; font-family: monospace;'>$pass</span>
</p>
<p style='margin-top: 20px;'>Por favor, cambia esta contraseña una vez que inicies sesión.</p>
</div>
<div style='background: #e9ecef; text-align: center; padding: 15px; font-size: 13px; color: #666;'>
&copy; " . date('Y') . " SIIH · Sistema Integral para Importadores de Hidrocarburos
</div>
</div>
</div>";
$mail->send();
} catch (Exception $e) {
error_log("Error al enviar correo: {$mail->ErrorInfo}");
}
}
function suspenderAgencia()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header("Location: /IMPORTADORES/administrador/agenciasActivas?error=unauthorized");
exit;
}
$conn = getConnection();
$id = $_GET['id'] ?? null;
if (!$id || !is_numeric($id)) {
header("Location: /IMPORTADORES/administrador/agenciasActivas?error=invalid_id");
exit;
}
// Obtener el estado actual
$sqlEstado = "SELECT activo FROM agencias_aduanles WHERE id_usuario = ?";
$stmtEstado = sqlsrv_query($conn, $sqlEstado, [$id]);
if (!$stmtEstado || !($row = sqlsrv_fetch_array($stmtEstado, SQLSRV_FETCH_ASSOC))) {
header("Location: /IMPORTADORES/administrador/agenciasActivas?error=agencia_not_found");
exit;
}
$nuevoEstado = $row['activo'] ? 0 : 1;
// Actualizar estado
$sqlUpdate = "UPDATE agencias_aduanles SET activo = ? WHERE id_usuario = ?";
$stmtUpdate = sqlsrv_query($conn, $sqlUpdate, [$nuevoEstado, $id]);
if (!$stmtUpdate) {
header("Location: /IMPORTADORES/administrador/agenciasActivas?error=update_failed");
exit;
}
// Determinar el tipo de cambio para el mensaje
$accion = $nuevoEstado ? 'activated' : 'deactivated';
header("Location: /IMPORTADORES/administrador/agenciasActivas?success=status_$accion");
exit;
}
function configuracion()
{
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'] ?? null;
if (!$id_usuario) {
die("ID de usuario no disponible en la sesión.");
}
$sql = "SELECT * FROM informacion_general WHERE id_usuario = ?";
$params = [$id_usuario];
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
die(print_r(sqlsrv_errors(), true));
}
$datos = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
include __DIR__ . '/../../views/configuracion/dashboard_configuracion.php';
}