Sprint 2
This commit is contained in:
@@ -13,7 +13,8 @@ use PHPMailer\PHPMailer\Exception;
|
|||||||
|
|
||||||
loadEnv();
|
loadEnv();
|
||||||
|
|
||||||
function dashboard() {
|
function dashboard()
|
||||||
|
{
|
||||||
if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'agente_aduanal') {
|
if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'agente_aduanal') {
|
||||||
header("Location: /IMPORTADORES/login");
|
header("Location: /IMPORTADORES/login");
|
||||||
exit;
|
exit;
|
||||||
@@ -28,7 +29,8 @@ function dashboard() {
|
|||||||
include __DIR__ . '/../../views/agentes/dashboard.php';
|
include __DIR__ . '/../../views/agentes/dashboard.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
function importadores_activos() {
|
function importadores_activos()
|
||||||
|
{
|
||||||
if (!($_SESSION['usuario_id'] ?? false) || $_SESSION['tipo_usuario'] !== 'agente_aduanal') {
|
if (!($_SESSION['usuario_id'] ?? false) || $_SESSION['tipo_usuario'] !== 'agente_aduanal') {
|
||||||
header('Location: /IMPORTADORES/login');
|
header('Location: /IMPORTADORES/login');
|
||||||
exit;
|
exit;
|
||||||
@@ -175,8 +177,8 @@ function aprobar_solicitud()
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
function activos() {
|
function activos()
|
||||||
|
{
|
||||||
if (!($_SESSION['usuario_id'] ?? false)) {
|
if (!($_SESSION['usuario_id'] ?? false)) {
|
||||||
die("⚠️ No autorizado.");
|
die("⚠️ No autorizado.");
|
||||||
}
|
}
|
||||||
@@ -203,9 +205,8 @@ function activos() {
|
|||||||
include __DIR__ . '/../../views/agentes/importadores_activos.php';
|
include __DIR__ . '/../../views/agentes/importadores_activos.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle_estado() {
|
function toggle_estado()
|
||||||
|
{
|
||||||
|
|
||||||
if (!($_SESSION['usuario_id'] ?? false) || $_SESSION['tipo_usuario'] !== 'agente_aduanal') {
|
if (!($_SESSION['usuario_id'] ?? false) || $_SESSION['tipo_usuario'] !== 'agente_aduanal') {
|
||||||
die("⚠️ No autorizado.");
|
die("⚠️ No autorizado.");
|
||||||
}
|
}
|
||||||
@@ -241,3 +242,32 @@ function toggle_estado() {
|
|||||||
header("Location: /IMPORTADORES/agentes/activos");
|
header("Location: /IMPORTADORES/agentes/activos");
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bitacora()
|
||||||
|
{
|
||||||
|
$conn = getConnection();
|
||||||
|
if (!($_SESSION['usuario_id'] ?? false)) {
|
||||||
|
header('Location: /IMPORTADORES/login');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = "
|
||||||
|
SELECT u.id_usuario, u.nombre, b.email, b.ip, b.fecha, b.exito, b.detalle
|
||||||
|
FROM dbo.bitacora_login b
|
||||||
|
JOIN dbo.usuarios_sistema u ON u.id_usuario = b.id_usuario
|
||||||
|
ORDER BY b.fecha DESC
|
||||||
|
";
|
||||||
|
|
||||||
|
$stmt = sqlsrv_query($conn, $sql);
|
||||||
|
if ($stmt === false) {
|
||||||
|
die("Error en bitacora(): " . print_r(sqlsrv_errors(), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
$bitacoras = [];
|
||||||
|
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
|
||||||
|
$row['nombre'] = decrypt($row['nombre']); // Desencripta aquí
|
||||||
|
$bitacoras[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
include __DIR__ . '/../../views/agentes/bitacora.php';
|
||||||
|
}
|
||||||
@@ -62,7 +62,7 @@ function guardar()
|
|||||||
// Captura los datos del formulario
|
// Captura los datos del formulario
|
||||||
$campos = [
|
$campos = [
|
||||||
'clave', 'tipo_identificador', 'curp', 'calle', 'num_exterior', 'num_interior',
|
'clave', 'tipo_identificador', 'curp', 'calle', 'num_exterior', 'num_interior',
|
||||||
'ciudad', 'colonia', 'pais', 'codigo_postal', 'municipio', 'estado', 'fax', 'observaciones'
|
'ciudad', 'colonia', 'pais', 'codigo_postal', 'municipio', 'estado', 'telefono', 'fax', 'observaciones'
|
||||||
];
|
];
|
||||||
|
|
||||||
$sql_parts = [];
|
$sql_parts = [];
|
||||||
@@ -75,23 +75,95 @@ function guardar()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si no hay datos que actualizar
|
|
||||||
if (empty($sql_parts)) {
|
if (empty($sql_parts)) {
|
||||||
header("Location: /IMPORTADORES/configuracion");
|
header("Location: /IMPORTADORES/configuracion");
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Iniciar transacción para asegurar consistencia
|
||||||
|
sqlsrv_begin_transaction($conn);
|
||||||
|
|
||||||
|
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;
|
$params[] = $id_usuario;
|
||||||
|
|
||||||
$stmt = sqlsrv_query($conn, $sql, $params);
|
$stmt = sqlsrv_query($conn, $sql, $params);
|
||||||
|
|
||||||
if ($stmt === false) {
|
if ($stmt === false) {
|
||||||
die(print_r(sqlsrv_errors(), true));
|
throw new Exception(print_r(sqlsrv_errors(), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. Actualiza el teléfono en solicitudes_importadores usando company_name encriptado
|
||||||
|
if (isset($_POST['telefono']) && $_POST['telefono'] !== '') {
|
||||||
|
$telefono = $_POST['telefono'];
|
||||||
|
|
||||||
|
// Primero obtenemos el nombre de la empresa de informacion_general
|
||||||
|
$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);
|
||||||
|
|
||||||
|
if ($stmt_get_name === false) {
|
||||||
|
throw new Exception("Error al obtener nombre de empresa: " . print_r(sqlsrv_errors(), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
$empresa_data = sqlsrv_fetch_array($stmt_get_name, SQLSRV_FETCH_ASSOC);
|
||||||
|
|
||||||
|
if ($empresa_data && !empty($empresa_data['nombre'])) {
|
||||||
|
$nombre_empresa = $empresa_data['nombre'];
|
||||||
|
|
||||||
|
// Encriptar el nombre de la empresa para comparar
|
||||||
|
$nombre_encriptado = encrypt($nombre_empresa);
|
||||||
|
|
||||||
|
// Actualizar solicitudes_importadores usando el company_name encriptado
|
||||||
|
$sql_solicitud = "UPDATE solicitudes_importadores SET phone = ? WHERE company_name = ?";
|
||||||
|
$params_solicitud = [$telefono, $nombre_encriptado];
|
||||||
|
|
||||||
|
$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));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verificar si se actualizó algún registro
|
||||||
|
$rows_affected = sqlsrv_rows_affected($stmt_solicitud);
|
||||||
|
if ($rows_affected === false || $rows_affected == 0) {
|
||||||
|
// Log para debugging
|
||||||
|
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 = ?";
|
||||||
|
$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 = ?";
|
||||||
|
$params_solicitud_rfc = [$telefono, $rfc_data['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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error_log("No se pudo obtener el nombre de la empresa para el usuario: " . $id_usuario);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Confirmar transacción
|
||||||
|
sqlsrv_commit($conn);
|
||||||
|
|
||||||
header("Location: /IMPORTADORES/configuracion/index");
|
header("Location: /IMPORTADORES/configuracion/index");
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// Revertir transacción en caso de error
|
||||||
|
sqlsrv_rollback($conn);
|
||||||
|
die("Error al actualizar datos: " . $e->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function automatizaciones()
|
function automatizaciones()
|
||||||
|
|||||||
@@ -24,6 +24,17 @@ function index()
|
|||||||
|
|
||||||
function opciones()
|
function opciones()
|
||||||
{
|
{
|
||||||
|
$conn = getConnection();
|
||||||
|
$id_usuario = $_SESSION['usuario_id'] ?? null;
|
||||||
|
|
||||||
|
// Asegúrate de que el usuario está autenticado
|
||||||
|
if (!$id_usuario) {
|
||||||
|
die("Usuario no autenticado.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtener correos
|
||||||
|
$correos = obtenerCorreos($conn, $id_usuario);
|
||||||
|
|
||||||
include __DIR__ . '/../../views/seguridad/agregar.php';
|
include __DIR__ . '/../../views/seguridad/agregar.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,6 +156,35 @@ function correoExtra()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function modificarCorreoExtra()
|
||||||
|
{
|
||||||
|
if (!isset($_SESSION['usuario_id']) || ($_SESSION['pendiente_confirmacion'] ?? false)) {
|
||||||
|
echo "Error: no se ha iniciado sesión o sesión incompleta.";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$id_usuario = $_SESSION['usuario_id'];
|
||||||
|
$conn = getConnection();
|
||||||
|
|
||||||
|
$correo = $_POST['email-extra'] ?? '';
|
||||||
|
|
||||||
|
if (!filter_var($correo, FILTER_VALIDATE_EMAIL)) {
|
||||||
|
echo "Correo inválido.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = "UPDATE correo_extra SET correo = ? WHERE id_usuario = ?";
|
||||||
|
$stmt = sqlsrv_prepare($conn, $query, [$correo, $id_usuario]);
|
||||||
|
|
||||||
|
if ($stmt && sqlsrv_execute($stmt)) {
|
||||||
|
$_SESSION['config_success'] = 'Correo adicional actualizado correctamente.';
|
||||||
|
header('Location: /IMPORTADORES/seguridad/index');
|
||||||
|
exit;
|
||||||
|
} else {
|
||||||
|
echo "Error al actualizar el correo extra.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function correoRespaldo()
|
function correoRespaldo()
|
||||||
{
|
{
|
||||||
// CORRIGIDO: Cambiar id_usuario por usuario_id y verificar confirmación
|
// CORRIGIDO: Cambiar id_usuario por usuario_id y verificar confirmación
|
||||||
@@ -184,6 +224,35 @@ function correoRespaldo()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function modificarCorreoRspaldo()
|
||||||
|
{
|
||||||
|
if (!isset($_SESSION['usuario_id']) || ($_SESSION['pendiente_confirmacion'] ?? false)) {
|
||||||
|
echo "Error: no se ha iniciado sesión o sesión incompleta.";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$id_usuario = $_SESSION['usuario_id'];
|
||||||
|
$conn = getConnection();
|
||||||
|
|
||||||
|
$correo = $_POST['email-respaldo'] ?? '';
|
||||||
|
|
||||||
|
if (!filter_var($correo, FILTER_VALIDATE_EMAIL)) {
|
||||||
|
echo "Correo inválido.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = "UPDATE correo_respaldo SET correo = ? WHERE id_usuario = ?";
|
||||||
|
$stmt = sqlsrv_prepare($conn, $query, [$correo, $id_usuario]);
|
||||||
|
|
||||||
|
if ($stmt && sqlsrv_execute($stmt)) {
|
||||||
|
$_SESSION['config_success'] = 'Correo de respaldo actualizado correctamente.';
|
||||||
|
header('Location: /IMPORTADORES/seguridad/index');
|
||||||
|
exit;
|
||||||
|
} else {
|
||||||
|
echo "Error al actualizar el correo de respaldo.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function obtenerCorreos($conn, $id_usuario)
|
function obtenerCorreos($conn, $id_usuario)
|
||||||
{
|
{
|
||||||
$correos = [
|
$correos = [
|
||||||
|
|||||||
@@ -77,12 +77,15 @@ function lista() {
|
|||||||
f.*,
|
f.*,
|
||||||
tr.nombre AS transportista,
|
tr.nombre AS transportista,
|
||||||
(c.nombre + ' ' + c.apellido) AS chofer,
|
(c.nombre + ' ' + c.apellido) AS chofer,
|
||||||
|
p.nombre AS nombre_pais_proveedor,
|
||||||
f.foto_solicitud_url
|
f.foto_solicitud_url
|
||||||
FROM dbo.solicitud_importacion_factura f
|
FROM dbo.solicitud_importacion_factura f
|
||||||
JOIN dbo.transportistas tr
|
JOIN dbo.transportistas tr
|
||||||
ON f.transportista_id = tr.id_transportista
|
ON f.transportista_id = tr.id_transportista
|
||||||
LEFT JOIN dbo.choferes c
|
LEFT JOIN dbo.choferes c
|
||||||
ON f.chofer_id = c.id_chofer
|
ON f.chofer_id = c.id_chofer
|
||||||
|
LEFT JOIN dbo.paises p
|
||||||
|
ON f.pais_proveedor = p.id_pais
|
||||||
WHERE f.id_importador = ?
|
WHERE f.id_importador = ?
|
||||||
AND f.status >= 1
|
AND f.status >= 1
|
||||||
ORDER BY f.created_at DESC
|
ORDER BY f.created_at DESC
|
||||||
@@ -104,7 +107,8 @@ function lista() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Formulario de nueva factura **/
|
/** Formulario de nueva factura **/
|
||||||
function crear() {
|
function crear()
|
||||||
|
{
|
||||||
if (!($_SESSION['usuario_id'] ?? false)) {
|
if (!($_SESSION['usuario_id'] ?? false)) {
|
||||||
header('Location: /IMPORTADORES/login');
|
header('Location: /IMPORTADORES/login');
|
||||||
exit;
|
exit;
|
||||||
@@ -114,7 +118,7 @@ function crear() {
|
|||||||
|
|
||||||
// Carga de datos para selects
|
// Carga de datos para selects
|
||||||
$transportistas = [];
|
$transportistas = [];
|
||||||
$stmtT = sqlsrv_query($conn, "SELECT id_transportista,nombre FROM dbo.transportistas WHERE id_usuario=? AND activo=1 ORDER BY nombre",[$id_importador]);
|
$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 = [];
|
||||||
@@ -126,7 +130,7 @@ function crear() {
|
|||||||
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 aduana_seccion,nombre FROM dbo.aduanas ORDER BY aduana_seccion");
|
$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 = [];
|
||||||
@@ -143,7 +147,8 @@ function crear() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Procesa la creación de una nueva factura y sus partidas **/
|
/** Procesa la creación de una nueva factura y sus partidas **/
|
||||||
function guardar() {
|
function guardar()
|
||||||
|
{
|
||||||
if (!($_SESSION['usuario_id'] ?? false)) {
|
if (!($_SESSION['usuario_id'] ?? false)) {
|
||||||
die("⚠️ No autorizado.");
|
die("⚠️ No autorizado.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,7 @@
|
|||||||
session_start();
|
session_start();
|
||||||
require_once __DIR__ . '/../../config/database.php';
|
require_once __DIR__ . '/../../config/database.php';
|
||||||
|
|
||||||
/**
|
/** Listado de transportes (sólo activos) para el importador logueado **/
|
||||||
* Listado de transportes (sólo activos) para el importador logueado
|
|
||||||
*/
|
|
||||||
function lista() {
|
function lista() {
|
||||||
if (!($_SESSION['usuario_id'] ?? false)) {
|
if (!($_SESSION['usuario_id'] ?? false)) {
|
||||||
header('Location: /IMPORTADORES/login');
|
header('Location: /IMPORTADORES/login');
|
||||||
@@ -31,9 +29,7 @@ function lista() {
|
|||||||
include __DIR__ . '/../../views/transportes/lista.php';
|
include __DIR__ . '/../../views/transportes/lista.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Formulario de alta de transporte **/
|
||||||
* Formulario de alta de transporte
|
|
||||||
*/
|
|
||||||
function crear() {
|
function crear() {
|
||||||
if (!($_SESSION['usuario_id'] ?? false)) {
|
if (!($_SESSION['usuario_id'] ?? false)) {
|
||||||
header('Location: /IMPORTADORES/login');
|
header('Location: /IMPORTADORES/login');
|
||||||
@@ -44,7 +40,7 @@ function crear() {
|
|||||||
|
|
||||||
// Traer transportistas propios para el select
|
// Traer transportistas propios para el select
|
||||||
$sql = "
|
$sql = "
|
||||||
SELECT id_transportista, nombre
|
SELECT id_transportista, clave_identificador, nombre
|
||||||
FROM dbo.transportistas
|
FROM dbo.transportistas
|
||||||
WHERE id_usuario = ? AND activo = 1
|
WHERE id_usuario = ? AND activo = 1
|
||||||
ORDER BY nombre
|
ORDER BY nombre
|
||||||
@@ -58,9 +54,7 @@ function crear() {
|
|||||||
include __DIR__ . '/../../views/transportes/crear.php';
|
include __DIR__ . '/../../views/transportes/crear.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Procesa la creación de un nuevo transporte **/
|
||||||
* Procesa la creación de un nuevo transporte
|
|
||||||
*/
|
|
||||||
function guardar() {
|
function guardar() {
|
||||||
|
|
||||||
if (!($_SESSION['usuario_id'] ?? false)) {
|
if (!($_SESSION['usuario_id'] ?? false)) {
|
||||||
@@ -101,9 +95,7 @@ function guardar() {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Formulario de edición **/
|
||||||
* Formulario de edición
|
|
||||||
*/
|
|
||||||
function editar() {
|
function editar() {
|
||||||
|
|
||||||
if (!($_SESSION['usuario_id'] ?? false)) {
|
if (!($_SESSION['usuario_id'] ?? false)) {
|
||||||
@@ -143,9 +135,7 @@ function editar() {
|
|||||||
include __DIR__ . '/../../views/transportes/editar.php';
|
include __DIR__ . '/../../views/transportes/editar.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Procesa la actualización **/
|
||||||
* Procesa la actualización
|
|
||||||
*/
|
|
||||||
function actualizar() {
|
function actualizar() {
|
||||||
if (!($_SESSION['usuario_id'] ?? false)) {
|
if (!($_SESSION['usuario_id'] ?? false)) {
|
||||||
die("⚠️ No autorizado.");
|
die("⚠️ No autorizado.");
|
||||||
@@ -206,11 +196,7 @@ function actualizar() {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** “Soft-delete” (status = 0) **/
|
||||||
|
|
||||||
/**
|
|
||||||
* “Soft-delete” (status = 0)
|
|
||||||
*/
|
|
||||||
function eliminar() {
|
function eliminar() {
|
||||||
|
|
||||||
if (!($_SESSION['usuario_id'] ?? false)) {
|
if (!($_SESSION['usuario_id'] ?? false)) {
|
||||||
@@ -232,9 +218,7 @@ function eliminar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/** Formulario de importación masiva **/
|
||||||
* Formulario de importación masiva
|
|
||||||
*/
|
|
||||||
function masivo() {
|
function masivo() {
|
||||||
if (!($_SESSION['usuario_id'] ?? false)) {
|
if (!($_SESSION['usuario_id'] ?? false)) {
|
||||||
header('Location: /IMPORTADORES/login');
|
header('Location: /IMPORTADORES/login');
|
||||||
@@ -243,9 +227,7 @@ function masivo() {
|
|||||||
include __DIR__ . '/../../views/transportes/importar_masivo.php';
|
include __DIR__ . '/../../views/transportes/importar_masivo.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Procesa la importación masiva desde CSV **/
|
||||||
* Procesa la importación masiva desde CSV
|
|
||||||
*/
|
|
||||||
function importarGuardar() {
|
function importarGuardar() {
|
||||||
if (!($_SESSION['usuario_id'] ?? false)) {
|
if (!($_SESSION['usuario_id'] ?? false)) {
|
||||||
die("⚠️ No autorizado.");
|
die("⚠️ No autorizado.");
|
||||||
|
|||||||
@@ -460,7 +460,6 @@ function actualizar() {
|
|||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function eliminar() {
|
function eliminar() {
|
||||||
session_start();
|
session_start();
|
||||||
if (!($_SESSION['usuario_id'] ?? false)) {
|
if (!($_SESSION['usuario_id'] ?? false)) {
|
||||||
|
|||||||
132
views/agentes/bitacora.php
Normal file
132
views/agentes/bitacora.php
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
<?php
|
||||||
|
include __DIR__ . '/../partials/sidebar_agente.php';
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="es">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Dashboard | Agente Aduanal</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<link href="https://cdn.datatables.net/1.13.4/css/jquery.dataTables.min.css" rel="stylesheet">
|
||||||
|
<script src="https://code.jquery.com/jquery-3.7.0.min.js"></script>
|
||||||
|
<script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', sans-serif;
|
||||||
|
background-color: #f4f6f9;
|
||||||
|
}
|
||||||
|
.sidebar {
|
||||||
|
width: 220px;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #343a40;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
padding-top: 56px; /* Alineado con la altura de la navbar */
|
||||||
|
z-index: 1040; /* Asegura que esté por encima del contenido */
|
||||||
|
}
|
||||||
|
.sidebar .nav-link {
|
||||||
|
font-weight: bold;
|
||||||
|
color: white;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
.sidebar .nav-link:hover,
|
||||||
|
.sidebar .nav-link.active {
|
||||||
|
background-color: #495057;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
margin-top: 56px; /* Ajusta debajo de navbar */
|
||||||
|
padding: 40px 20px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
background-color: #f4f6f9; /* Asegura fondo uniforme */
|
||||||
|
transition: margin-left 0.3s ease;
|
||||||
|
}
|
||||||
|
.navbar {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 1050;
|
||||||
|
}
|
||||||
|
/* A partir de dispositivos medianos (>=768px), deja espacio lateral */
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.content {
|
||||||
|
margin-left: 250px; /* Ancho del sidebar */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* En móviles, sin margen lateral */
|
||||||
|
@media (max-width: 767.98px) {
|
||||||
|
.content {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
.sidebar .nav-link {
|
||||||
|
font-weight: normal;
|
||||||
|
color: #343a40;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
.sidebar .nav-link:hover,
|
||||||
|
.sidebar .nav-link.active {
|
||||||
|
background-color: #e9ecef;
|
||||||
|
color: #212529;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.card { border-radius: 12px; }
|
||||||
|
table.dataTable thead th { background: #343a40; color: #fff; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<h4 class="mb-4">👥 Acceso de Usuarios</h4>
|
||||||
|
|
||||||
|
<div class="card p-3 shadow-sm">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-striped" id="tabla-logins">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Nombre</th>
|
||||||
|
<th>Correo</th>
|
||||||
|
<th>IP</th>
|
||||||
|
<th>Fecha</th>
|
||||||
|
<th>Estatus</th>
|
||||||
|
<th>Detalles</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($bitacoras as $b): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?= htmlspecialchars($b['id_usuario']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($b['nombre']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($b['email']) ?></td>
|
||||||
|
<td><?= htmlspecialchars($b['ip']) ?></td>
|
||||||
|
<td><?= $b['fecha']->format('Y-m-d H:i:s') ?></td>
|
||||||
|
<td>
|
||||||
|
<?= $b['exito'] == 1 ? 'Éxito' : 'Fallido' ?>
|
||||||
|
</td>
|
||||||
|
<td><?= htmlspecialchars($b['detalle']) ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('#tabla-logins').DataTable({
|
||||||
|
language: {
|
||||||
|
url: '//cdn.datatables.net/plug-ins/1.13.4/i18n/es-ES.json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,3 +1,7 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/../../app/helpers/crypto.php';
|
||||||
|
include __DIR__ . '/../partials/sidebar_agente.php';
|
||||||
|
?>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="es">
|
<html lang="es">
|
||||||
@@ -47,10 +51,6 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<?php
|
|
||||||
require_once __DIR__ . '/../../app/helpers/crypto.php';
|
|
||||||
include __DIR__ . '/../partials/sidebar_agente.php';
|
|
||||||
?>
|
|
||||||
<!-- 📄 CONTENIDO -->
|
<!-- 📄 CONTENIDO -->
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h4 class="mb-4">Panel principal del agente</h4>
|
<h4 class="mb-4">Panel principal del agente</h4>
|
||||||
@@ -60,7 +60,7 @@ include __DIR__ . '/../partials/sidebar_agente.php';
|
|||||||
<div class="card shadow-sm p-3">
|
<div class="card shadow-sm p-3">
|
||||||
<h5 class="text-primary">Importadores activos</h5>
|
<h5 class="text-primary">Importadores activos</h5>
|
||||||
<p>Consulta los que ya fueron autorizados.</p>
|
<p>Consulta los que ya fueron autorizados.</p>
|
||||||
<a href="/IMPORTADORES/importadores/activos" class="btn btn-primary btn-sm mt-2">Ver importadores</a>
|
<a href="/IMPORTADORES/AGENTES/activos" class="btn btn-primary btn-sm mt-2">Ver importadores</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ include __DIR__ . '/../partials/sidebar_agente.php';
|
|||||||
<div class="card shadow-sm p-3">
|
<div class="card shadow-sm p-3">
|
||||||
<h5 class="text-warning">Bitácora del sistema</h5>
|
<h5 class="text-warning">Bitácora del sistema</h5>
|
||||||
<p>Revisa los accesos y acciones recientes.</p>
|
<p>Revisa los accesos y acciones recientes.</p>
|
||||||
<a href="/IMPORTADORES/bitacoras/login" class="btn btn-warning btn-sm mt-2">Ver bitácora</a>
|
<a href="/IMPORTADORES/agentes/bitacora" class="btn btn-warning btn-sm mt-2">Ver bitácora</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
require_once __DIR__ . '/../../app/helpers/crypto.php';
|
require_once __DIR__ . '/../../app/helpers/crypto.php';
|
||||||
include __DIR__ . '/../partials/sidebar_agente.php';
|
include __DIR__ . '/../partials/sidebar_agente.php';
|
||||||
?>
|
?>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Dashboard | Agente Aduanal</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
@@ -44,6 +47,7 @@ include __DIR__ . '/../partials/sidebar_agente.php';
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
<body>
|
||||||
<div class="content px-4 pt-5 mt-4">
|
<div class="content px-4 pt-5 mt-4">
|
||||||
<h4>✅ Importadores Activos</h4>
|
<h4>✅ Importadores Activos</h4>
|
||||||
|
|
||||||
@@ -87,3 +91,6 @@ include __DIR__ . '/../partials/sidebar_agente.php';
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -2,6 +2,9 @@
|
|||||||
require_once __DIR__ . '/../../app/helpers/crypto.php';
|
require_once __DIR__ . '/../../app/helpers/crypto.php';
|
||||||
include __DIR__ . '/../partials/sidebar_agente.php';
|
include __DIR__ . '/../partials/sidebar_agente.php';
|
||||||
?>
|
?>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Dashboard | Agente Aduanal</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
@@ -43,6 +46,8 @@ include __DIR__ . '/../partials/sidebar_agente.php';
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
<div class="content px-4 pt-5 mt-4">
|
<div class="content px-4 pt-5 mt-4">
|
||||||
<h4>📥 Solicitudes Pendientes</h4>
|
<h4>📥 Solicitudes Pendientes</h4>
|
||||||
|
|
||||||
@@ -83,3 +88,6 @@ include __DIR__ . '/../partials/sidebar_agente.php';
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -84,17 +84,22 @@ include __DIR__ . '/../partials/sidebar_configuracion.php';
|
|||||||
<h4 class="mb-4">ℹ️ Información General</h4>
|
<h4 class="mb-4">ℹ️ Información General</h4>
|
||||||
<div class="card shadow-sm p-4 mb-4 bg-white">
|
<div class="card shadow-sm p-4 mb-4 bg-white">
|
||||||
<form>
|
<form>
|
||||||
<div class="row mb-2">
|
<div class="row mb-3">
|
||||||
<label class="col-md-2 col-form-label">Clave:</label>
|
<label class="col-md-2 col-form-label">Clave:</label>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<input type="text" class="form-control" value="<?= htmlspecialchars($datos['clave'] ?? '') ?>" disabled>
|
<input type="text" class="form-control" value="<?= htmlspecialchars($datos['clave'] ?? '') ?>" disabled>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-1"></div>
|
<div class="col-md-3"></div>
|
||||||
|
|
||||||
<label class="col-md-2 col-form-label">Tipo de identificador:</label>
|
<label class="col-md-2 col-form-label">Tipo de identificador:</label>
|
||||||
<div class="col-md-4">
|
<div class="col-md-2">
|
||||||
<input type="text" class="form-control" value="<?= htmlspecialchars($datos['tipo_identificador'] ?? '') ?>" disabled>
|
<select name="tipo_identificador" class="form-control" disabled>
|
||||||
|
<option value="">-- Selecciona una opción --</option>
|
||||||
|
<option value="1" <?= ($datos['tipo_identificador'] ?? '') == '1' ? 'selected' : '' ?>>1 - RFC</option>
|
||||||
|
<option value="2" <?= ($datos['tipo_identificador'] ?? '') == '2' ? 'selected' : '' ?>>2 - CURP</option>
|
||||||
|
<option value="3" <?= ($datos['tipo_identificador'] ?? '') == '3' ? 'selected' : '' ?>>3 - SIN TAX ID</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -88,20 +88,23 @@ include __DIR__ . '/../partials/sidebar_configuracion.php';
|
|||||||
<h4 class="mb-4">✏️ Editar Información</h4>
|
<h4 class="mb-4">✏️ Editar Información</h4>
|
||||||
<div class="card shadow-sm p-4 mb-4 bg-white">
|
<div class="card shadow-sm p-4 mb-4 bg-white">
|
||||||
<form id="form-edicion" method="POST" action="/IMPORTADORES/configuracion/guardar">
|
<form id="form-edicion" method="POST" action="/IMPORTADORES/configuracion/guardar">
|
||||||
<div class="row mb-2">
|
<div class="row mb-3">
|
||||||
<label class="col-md-2 col-form-label">Clave:</label>
|
<label class="col-md-2 col-form-label">Clave:</label>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<input type="text" name="clave" maxlength="8"
|
<input type="text" name="clave" maxlength="8"
|
||||||
class="form-control" value="<?= htmlspecialchars($datos['clave'] ?? '') ?>" disabled>
|
class="form-control" value="<?= htmlspecialchars($datos['clave'] ?? '') ?>" disabled>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-1"></div>
|
<div class="col-md-3"></div>
|
||||||
|
|
||||||
<label class="col-md-2 col-form-label">Tipo de identificador:</label>
|
<label class="col-md-2 col-form-label">Tipo de identificador:</label>
|
||||||
<div class="col-md-4">
|
<div class="col-md-2">
|
||||||
<input type="number" name="tipo_identificador"
|
<select name="tipo_identificador" class="form-control" required>
|
||||||
class="form-control" value="<?= htmlspecialchars($datos['tipo_identificador'] ?? '') ?>"
|
<option value="">-- Selecciona una opción --</option>
|
||||||
onfocus="this.value=''" onblur="if(this.value=='') this.value='<?= htmlspecialchars($datos['tipo_identificador'] ?? '') ?>'">
|
<option value="1" <?= ($datos['tipo_identificador'] ?? '') == '1' ? 'selected' : '' ?>>1 - RFC</option>
|
||||||
|
<option value="2" <?= ($datos['tipo_identificador'] ?? '') == '2' ? 'selected' : '' ?>>2 - CURP</option>
|
||||||
|
<option value="3" <?= ($datos['tipo_identificador'] ?? '') == '3' ? 'selected' : '' ?>>3 - SIN TAX ID</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -123,87 +126,78 @@ include __DIR__ . '/../partials/sidebar_configuracion.php';
|
|||||||
<label class="col-md-1 col-form-label">CURP:</label>
|
<label class="col-md-1 col-form-label">CURP:</label>
|
||||||
<div class="col-md-5">
|
<div class="col-md-5">
|
||||||
<input type="text" name="curp" maxlength="18"
|
<input type="text" name="curp" maxlength="18"
|
||||||
class="form-control" value="<?= htmlspecialchars($datos['curp'] ?? '') ?>"
|
class="form-control" value="<?= htmlspecialchars($datos['curp'] ?? '') ?>">
|
||||||
onfocus="this.value=''" onblur="if(this.value=='') this.value='<?= htmlspecialchars($datos['curp'] ?? '') ?>'">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label class="col-md-2 col-form-label">Calle:</label>
|
<label class="col-md-2 col-form-label">Calle:</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<input type="text" name="calle" class="form-control" value="<?= htmlspecialchars($datos['calle'] ?? '') ?>"
|
<input type="text" name="calle" class="form-control" value="<?= htmlspecialchars($datos['calle'] ?? '') ?>">
|
||||||
onfocus="this.value=''" onblur="if(this.value=='') this.value='<?= htmlspecialchars($datos['calle'] ?? '') ?>'">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label class="col-md-2 col-form-label">Núm. Exterior:</label>
|
<label class="col-md-2 col-form-label">Núm. Exterior:</label>
|
||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
<input type="number" name="num_exterior" class="form-control" value="<?= htmlspecialchars($datos['num_exterior'] ?? '') ?>"
|
<input type="text" name="num_exterior" class="form-control" value="<?= htmlspecialchars($datos['num_exterior'] ?? '') ?>">
|
||||||
onfocus="this.value=''" onblur="if(this.value=='') this.value='<?= htmlspecialchars($datos['num_exterior'] ?? '') ?>'">
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-4"></div>
|
<div class="col-md-4"></div>
|
||||||
|
|
||||||
<label class="col-md-2 col-form-label">Núm. Interior:</label>
|
<label class="col-md-2 col-form-label">Núm. Interior:</label>
|
||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
<input type="text" name="num_interior" class="form-control" value="<?= htmlspecialchars($datos['num_interior'] ?? '') ?>"
|
<input type="text" name="num_interior" class="form-control" value="<?= htmlspecialchars($datos['num_interior'] ?? '') ?>">
|
||||||
onfocus="this.value=''" onblur="if(this.value=='') this.value='<?= htmlspecialchars($datos['num_interior'] ?? '') ?>'">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label class="col-md-2 col-form-label">Ciudad / Localidad:</label>
|
<label class="col-md-2 col-form-label">Ciudad / Localidad:</label>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<input type="text" name="ciudad" class="form-control" value="<?= htmlspecialchars($datos['ciudad'] ?? '') ?>"
|
<input type="text" name="ciudad" class="form-control" value="<?= htmlspecialchars($datos['ciudad'] ?? '') ?>">
|
||||||
onfocus="this.value=''" onblur="if(this.value=='') this.value='<?= htmlspecialchars($datos['ciudad'] ?? '') ?>'">
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-1"></div>
|
<div class="col-md-1"></div>
|
||||||
|
|
||||||
<label class="col-md-1 col-form-label">Colonia:</label>
|
<label class="col-md-1 col-form-label">Colonia:</label>
|
||||||
<div class="col-md-5">
|
<div class="col-md-5">
|
||||||
<input type="text" name="colonia" class="form-control" value="<?= htmlspecialchars($datos['colonia'] ?? '') ?>"
|
<input type="text" name="colonia" class="form-control" value="<?= htmlspecialchars($datos['colonia'] ?? '') ?>">
|
||||||
onfocus="this.value=''" onblur="if(this.value=='') this.value='<?= htmlspecialchars($datos['colonia'] ?? '') ?>'">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label class="col-md-2 col-form-label">País:</label>
|
<label class="col-md-2 col-form-label">País:</label>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<input type="text" name="pais" class="form-control" value="<?= htmlspecialchars($datos['pais'] ?? '') ?>"
|
<input type="text" name="pais" class="form-control" value="<?= htmlspecialchars($datos['pais'] ?? '') ?>">
|
||||||
onfocus="this.value=''" onblur="if(this.value=='') this.value='<?= htmlspecialchars($datos['pais'] ?? '') ?>'">
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-3"></div>
|
<div class="col-md-3"></div>
|
||||||
|
|
||||||
<label class="col-md-2 col-form-label">Código Postal:</label>
|
<label class="col-md-2 col-form-label">Código Postal:</label>
|
||||||
<div class="col-md-2">
|
<div class="col-md-2">
|
||||||
<input type="number" name="codigo_postal" class="form-control" value="<?= htmlspecialchars($datos['codigo_postal'] ?? '') ?>"
|
<input type="number" name="codigo_postal" class="form-control" value="<?= htmlspecialchars($datos['codigo_postal'] ?? '') ?>">
|
||||||
onfocus="this.value=''" onblur="if(this.value=='') this.value='<?= htmlspecialchars($datos['codigo_postal'] ?? '') ?>'">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label class="col-md-2 col-form-label">Municipio:</label>
|
<label class="col-md-2 col-form-label">Municipio:</label>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<input type="text" name="municipio" class="form-control" value="<?= htmlspecialchars($datos['municipio'] ?? '') ?>"
|
<input type="text" name="municipio" class="form-control" value="<?= htmlspecialchars($datos['municipio'] ?? '') ?>">
|
||||||
onfocus="this.value=''" onblur="if(this.value=='') this.value='<?= htmlspecialchars($datos['municipio'] ?? '') ?>'">
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-1"></div>
|
<div class="col-md-1"></div>
|
||||||
|
|
||||||
<label class="col-md-1 col-form-label">Estado:</label>
|
<label class="col-md-1 col-form-label">Estado:</label>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<input type="text" name="estado" class="form-control" value="<?= htmlspecialchars($datos['estado'] ?? '') ?>"
|
<input type="text" name="estado" class="form-control" value="<?= htmlspecialchars($datos['estado'] ?? '') ?>">
|
||||||
onfocus="this.value=''" onblur="if(this.value=='') this.value='<?= htmlspecialchars($datos['estado'] ?? '') ?>'">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<label class="col-md-2 col-form-label">Teléfono:</label>
|
<label class="col-md-2 col-form-label">Teléfono:</label>
|
||||||
<div class="col-md-5">
|
<div class="col-md-5">
|
||||||
<input type="text" class="form-control" value="<?= htmlspecialchars($datos['telefono'] ?? '') ?>" disabled>
|
<input type="text" name="telefono" maxlength="11"
|
||||||
|
class="form-control" value="<?= htmlspecialchars($datos['telefono'] ?? '') ?>">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-1"></div>
|
<div class="col-md-1"></div>
|
||||||
@@ -211,8 +205,7 @@ include __DIR__ . '/../partials/sidebar_configuracion.php';
|
|||||||
<label class="col-md-1 col-form-label">Fax:</label>
|
<label class="col-md-1 col-form-label">Fax:</label>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<input type="text" name="fax" maxlength="12"
|
<input type="text" name="fax" maxlength="12"
|
||||||
class="form-control" value="<?= htmlspecialchars($datos['fax'] ?? '') ?>"
|
class="form-control" value="<?= htmlspecialchars($datos['fax'] ?? '') ?>">
|
||||||
onfocus="this.value=''" onblur="if(this.value=='') this.value='<?= htmlspecialchars($datos['fax'] ?? '') ?>'">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -227,9 +220,7 @@ include __DIR__ . '/../partials/sidebar_configuracion.php';
|
|||||||
<label class="col-md-2 col-form-label">Observaciones:</label>
|
<label class="col-md-2 col-form-label">Observaciones:</label>
|
||||||
<div class="col-md-10">
|
<div class="col-md-10">
|
||||||
<?php $valor_obs = htmlspecialchars($datos['observaciones'] ?? ''); ?>
|
<?php $valor_obs = htmlspecialchars($datos['observaciones'] ?? ''); ?>
|
||||||
<textarea name="observaciones" class="form-control" rows="3"
|
<textarea name="observaciones" class="form-control" rows="3"><?= $valor_obs ?></textarea>
|
||||||
onfocus="if(this.value === '<?= $valor_obs ?>') this.value=''"
|
|
||||||
onblur="if(this.value === '') this.value='<?= $valor_obs ?>'"><?= $valor_obs ?></textarea>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; justify-content: right;">
|
<div style="display: flex; justify-content: right;">
|
||||||
@@ -245,6 +236,7 @@ include __DIR__ . '/../partials/sidebar_configuracion.php';
|
|||||||
event.preventDefault(); // Evita que el formulario se envíe
|
event.preventDefault(); // Evita que el formulario se envíe
|
||||||
|
|
||||||
const curp = document.querySelector('[name="curp"]').value.trim();
|
const curp = document.querySelector('[name="curp"]').value.trim();
|
||||||
|
const telefono = document.querySelector('input[name="telefono"]').value.trim();
|
||||||
const fax = document.querySelector('[name="fax"]').value.trim();
|
const fax = document.querySelector('[name="fax"]').value.trim();
|
||||||
|
|
||||||
let errores = [];
|
let errores = [];
|
||||||
@@ -254,9 +246,14 @@ include __DIR__ . '/../partials/sidebar_configuracion.php';
|
|||||||
errores.push('La CURP no tiene el formato correcto.');
|
errores.push('La CURP no tiene el formato correcto.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validación Teléfono - Ajustada para permitir diferentes formatos
|
||||||
|
if (telefono !== '' && !/^\d{10,11}$/.test(telefono.replace(/\s/g, ''))) {
|
||||||
|
errores.push('El número de teléfono debe tener 10 u 11 dígitos.');
|
||||||
|
}
|
||||||
|
|
||||||
// Validación Fax
|
// Validación Fax
|
||||||
if (fax !== '' && !/^\d{3} \d{3} \d{4}$/.test(fax)) {
|
if (fax !== '' && !/^\d{3}\s?\d{3}\s?\d{4}$/.test(fax)) {
|
||||||
errores.push('El número de fax debe tener el formato: 123 456 7890.');
|
errores.push('El número de fax debe tener el formato: 123 456 7890 o 1234567890.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si hay errores, mostrar alerta y no enviar
|
// Si hay errores, mostrar alerta y no enviar
|
||||||
|
|||||||
@@ -8,9 +8,6 @@ if (!isset($_SESSION['usuario_id']) || $_SESSION['tipo_usuario'] !== 'agente_adu
|
|||||||
$nombreAgente = $_SESSION['usuario_nombre'];
|
$nombreAgente = $_SESSION['usuario_nombre'];
|
||||||
?>
|
?>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- 🔷 NAVBAR -->
|
<!-- 🔷 NAVBAR -->
|
||||||
<nav class="navbar navbar-dark bg-dark">
|
<nav class="navbar navbar-dark bg-dark">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
@@ -28,6 +25,6 @@ $nombreAgente = $_SESSION['usuario_nombre'];
|
|||||||
<a href="/IMPORTADORES/AGENTES/dashboard" class="nav-link active">📊 Dashboard</a>
|
<a href="/IMPORTADORES/AGENTES/dashboard" class="nav-link active">📊 Dashboard</a>
|
||||||
<a href="/IMPORTADORES/AGENTES/activos" class="nav-link">✅ Importadores Activos</a>
|
<a href="/IMPORTADORES/AGENTES/activos" class="nav-link">✅ Importadores Activos</a>
|
||||||
<a href="/IMPORTADORES/AGENTES/solicitudes_pendientes" class="nav-link">📥 Solicitudes de Registro</a>
|
<a href="/IMPORTADORES/AGENTES/solicitudes_pendientes" class="nav-link">📥 Solicitudes de Registro</a>
|
||||||
<a href="/IMPORTADORES/bitacoras/login" class="nav-link">🕓 Bitácora</a>
|
<a href="/IMPORTADORES/AGENTES/bitacora" class="nav-link">🕓 Bitácora</a>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -108,15 +108,24 @@ $dos_factores_estado = obtenerEstadoDosFactores();
|
|||||||
<div class="card shadow-sm p-3">
|
<div class="card shadow-sm p-3">
|
||||||
<h4 class="mb-4 text-dark">Recibe Notificaciones</h4>
|
<h4 class="mb-4 text-dark">Recibe Notificaciones</h4>
|
||||||
<p>Agrega un correo adicional para recibir notificaciones.</p>
|
<p>Agrega un correo adicional para recibir notificaciones.</p>
|
||||||
<form action="/IMPORTADORES/seguridad/correoExtra" method="POST">
|
<?php if (!empty($correos['correo_extra'])): ?>
|
||||||
|
<p><?= htmlspecialchars($correos['correo_extra']) ?></p>
|
||||||
|
<form method="POST" action="/IMPORTADORES/seguridad/modificarCorreoExtra">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Correo electrónico</label>
|
<input type="email" name="email-extra" class="form-control" value="<?= htmlspecialchars($correos['correo_extra']) ?>" required>
|
||||||
<input type="email" name="email-extra" class="form-control" required value="">
|
|
||||||
</div>
|
</div>
|
||||||
<div class="d-grid">
|
<div class="mb-3">
|
||||||
<button type="submit" class="btn btn-primary">Registrar</button>
|
<button type="submit" class="btn btn-success">Actualizar</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<?php else: ?>
|
||||||
|
<form method="POST" action="/IMPORTADORES/seguridad/correoExtra">
|
||||||
|
<div class="mb-3">
|
||||||
|
<input type="email" name="email-extra" class="form-control" placeholder="Correo adicional" required>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Registrar</button>
|
||||||
|
</form>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -125,15 +134,22 @@ $dos_factores_estado = obtenerEstadoDosFactores();
|
|||||||
<div class="card shadow-sm p-3">
|
<div class="card shadow-sm p-3">
|
||||||
<h4 class="mb-4 text-dark">Correo de Respaldo</h4>
|
<h4 class="mb-4 text-dark">Correo de Respaldo</h4>
|
||||||
<p>Agrega un correo de respaldo para reuperación de tu cuenta.</p>
|
<p>Agrega un correo de respaldo para reuperación de tu cuenta.</p>
|
||||||
<form action="/IMPORTADORES/seguridad/correoRespaldo" method="POST">
|
<?php if (!empty($correos['correo_respaldo'])): ?>
|
||||||
|
<p><?= htmlspecialchars($correos['correo_respaldo']) ?></p>
|
||||||
|
<form method="POST" action="/IMPORTADORES/seguridad/modificarCorreoRspaldo">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label">Correo electrónico respaldo</label>
|
<input type="email" name="email-respaldo" class="form-control" value="<?= htmlspecialchars($correos['correo_respaldo']) ?>" required>
|
||||||
<input type="email" name="email-respaldo" class="form-control" required value="">
|
|
||||||
</div>
|
|
||||||
<div class="d-grid">
|
|
||||||
<button type="submit" class="btn btn-success">Registrar</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
<button type="submit" class="btn btn-success">Actualizar</button>
|
||||||
</form>
|
</form>
|
||||||
|
<?php else: ?>
|
||||||
|
<form method="POST" action="/IMPORTADORES/seguridad/correoRespaldo">
|
||||||
|
<div class="mb-3">
|
||||||
|
<input type="email" name="email-respaldo" class="form-control" placeholder="Correo de respaldo" required>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Registrar</button>
|
||||||
|
</form>
|
||||||
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -99,7 +99,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 mb-3">
|
<div class="col-md-4 mb-3">
|
||||||
<label for="pais_proveedor" class="form-label">País (Proveedor)</label>
|
<label for="pais_proveedor" class="form-label">País (Proveedor)</label>
|
||||||
<select id="pais_proveedor" name="pais_proveedor" class="form-select searchable">
|
<select id="pais_proveedor" name="pais_proveedor" class="form-select searchable" required>
|
||||||
<option value="">-- Selecciona País --</option>
|
<option value="">-- Selecciona País --</option>
|
||||||
<?php foreach($paises as $p): ?>
|
<?php foreach($paises as $p): ?>
|
||||||
<option value="<?= htmlspecialchars($p['id_pais']) ?>"><?= htmlspecialchars($p['nombre']) ?></option>
|
<option value="<?= htmlspecialchars($p['id_pais']) ?>"><?= htmlspecialchars($p['nombre']) ?></option>
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 mb-3">
|
<div class="col-md-4 mb-3">
|
||||||
<label for="tipo_moneda" class="form-label">Moneda</label>
|
<label for="tipo_moneda" class="form-label">Moneda</label>
|
||||||
<select id="tipo_moneda" name="tipo_moneda" class="form-select searchable">
|
<select id="tipo_moneda" name="tipo_moneda" class="form-select searchable" required>
|
||||||
<?php foreach(['MXN'=>'Peso Mexicano','USD'=>'Dólar USD','EUR'=>'Euro','CNY'=>'Yuan','GBP'=>'Libra GBP','JPY'=>'Yen'] as $code=>$label): ?>
|
<?php foreach(['MXN'=>'Peso Mexicano','USD'=>'Dólar USD','EUR'=>'Euro','CNY'=>'Yuan','GBP'=>'Libra GBP','JPY'=>'Yen'] as $code=>$label): ?>
|
||||||
<option value="<?= $code ?>"><?= "$label ($code)" ?></option>
|
<option value="<?= $code ?>"><?= "$label ($code)" ?></option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
@@ -139,7 +139,9 @@
|
|||||||
<select id="transportista_id" name="transportista_id" class="form-select searchable" required>
|
<select id="transportista_id" name="transportista_id" class="form-select searchable" required>
|
||||||
<option value="">-- Selecciona --</option>
|
<option value="">-- Selecciona --</option>
|
||||||
<?php foreach($transportistas as $t): ?>
|
<?php foreach($transportistas as $t): ?>
|
||||||
<option value="<?= htmlspecialchars($t['id_transportista']) ?>"><?= htmlspecialchars($t['nombre']) ?></option>
|
<option value="<?= htmlspecialchars($t['id_transportista']) ?>">
|
||||||
|
<?= htmlspecialchars($t['clave_identificador'] . ' - ' . $t['nombre']) ?>
|
||||||
|
</option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@@ -148,7 +150,9 @@
|
|||||||
<select id="chofer_id" name="chofer_id" class="form-select searchable" required>
|
<select id="chofer_id" name="chofer_id" class="form-select searchable" required>
|
||||||
<option value="">-- Selecciona Chofer --</option>
|
<option value="">-- Selecciona Chofer --</option>
|
||||||
<?php foreach($choferes as $c): ?>
|
<?php foreach($choferes as $c): ?>
|
||||||
<option value="<?= htmlspecialchars($c['id_chofer']) ?>"><?= htmlspecialchars($c['nombre']) ?></option>
|
<option value="<?= htmlspecialchars($c['id_chofer']) ?>">
|
||||||
|
<?= htmlspecialchars($c['nombre']) ?>
|
||||||
|
</option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@@ -179,12 +183,12 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td><input name="partidas[0][descripcion]" class="form-control w-100"></td>
|
<td><input name="partidas[0][descripcion]" class="form-control w-100" required></td>
|
||||||
<td><input name="partidas[0][cantidad_comercial]" type="number" step="0.0001" class="form-control w-100"></td>
|
<td><input name="partidas[0][cantidad_comercial]" type="number" step="0.0001" class="form-control w-100" min="0" required></td>
|
||||||
<td><input name="partidas[0][cantidad_tarifa]" type="number" step="0.0001" class="form-control w-100"></td>
|
<td><input name="partidas[0][cantidad_tarifa]" type="number" step="0.0001" class="form-control w-100" min="0" required></td>
|
||||||
<td>
|
<td>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<select name="partidas[0][unidad_comercial_id]" class="form-select searchable">
|
<select name="partidas[0][unidad_comercial_id]" class="form-select searchable" required>
|
||||||
<option value="">-- Unidad --</option>
|
<option value="">-- Unidad --</option>
|
||||||
<?php foreach($unidades_medida as $um): ?>
|
<?php foreach($unidades_medida as $um): ?>
|
||||||
<option value="<?= htmlspecialchars($um['id']) ?>"><?= htmlspecialchars($um['descripcion']) ?></option>
|
<option value="<?= htmlspecialchars($um['id']) ?>"><?= htmlspecialchars($um['descripcion']) ?></option>
|
||||||
@@ -192,11 +196,11 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td><input name="partidas[0][valor_factura]" type="number" step="0.01" class="form-control valor-partida w-100"></td>
|
<td><input name="partidas[0][valor_factura]" type="number" step="0.01" class="form-control valor-partida w-100" min="0" required></td>
|
||||||
<td><input name="partidas[0][peso_bruto]" type="number" step="0.0001" class="form-control w-100"></td>
|
<td><input name="partidas[0][peso_bruto]" type="number" step="0.0001" class="form-control w-100" min="0" required></td>
|
||||||
<td>
|
<td>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<select name="partidas[0][tasa_preferencial]" class="form-select searchable">
|
<select name="partidas[0][tasa_preferencial]" class="form-select searchable" required>
|
||||||
<option value="">-- Selecciona --</option>
|
<option value="">-- Selecciona --</option>
|
||||||
<option>General</option>
|
<option>General</option>
|
||||||
<option>TLC</option>
|
<option>TLC</option>
|
||||||
|
|||||||
@@ -201,8 +201,8 @@
|
|||||||
<?php endforeach; else: ?>
|
<?php endforeach; else: ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td><input name="partidas[0][descripcion]" class="form-control"></td>
|
<td><input name="partidas[0][descripcion]" class="form-control"></td>
|
||||||
<td><input name="partidas[0][cantidad_comercial]" type="number" step="0.0001" class="form-control"></td>
|
<td><input name="partidas[0][cantidad_comercial]" type="number" step="0.0001" class="form-control" min="0"></td>
|
||||||
<td><input name="partidas[0][cantidad_tarifa]" type="number" step="0.0001" class="form-control"></td>
|
<td><input name="partidas[0][cantidad_tarifa]" type="number" step="0.0001" class="form-control" min="0"></td>
|
||||||
<td>
|
<td>
|
||||||
<select name="partidas[0][unidad_comercial_id]" class="form-select searchable">
|
<select name="partidas[0][unidad_comercial_id]" class="form-select searchable">
|
||||||
<option value="">-- Unidad --</option>
|
<option value="">-- Unidad --</option>
|
||||||
@@ -211,8 +211,8 @@
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
<td><input name="partidas[0][valor_factura]" type="number" step="0.01" class="form-control valor-partida"></td>
|
<td><input name="partidas[0][valor_factura]" type="number" step="0.01" class="form-control valor-partida" min="0"></td>
|
||||||
<td><input name="partidas[0][peso_bruto]" type="number" step="0.0001" class="form-control"></td>
|
<td><input name="partidas[0][peso_bruto]" type="number" step="0.0001" class="form-control" min="0"></td>
|
||||||
<td>
|
<td>
|
||||||
<select name="partidas[0][tasa_preferencial]" class="form-select searchable">
|
<select name="partidas[0][tasa_preferencial]" class="form-select searchable">
|
||||||
<option value="">-- Selecciona --</option>
|
<option value="">-- Selecciona --</option>
|
||||||
@@ -249,98 +249,119 @@
|
|||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0/dist/js/select2.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0/dist/js/select2.min.js"></script>
|
||||||
|
|
||||||
<
|
|
||||||
<script>
|
<script>
|
||||||
// 1) Inicializar Choices para todos los selects excepto proveedor_id
|
// add-partida & validation script
|
||||||
document.querySelectorAll('.searchable:not(#proveedor_id)').forEach(el => {
|
document.getElementById('add-partida').addEventListener('click', () => {
|
||||||
|
const tbody = document.querySelector('#tabla-partidas tbody');
|
||||||
|
const idx = tbody.querySelectorAll('tr').length;
|
||||||
|
const row = document.createElement('tr');
|
||||||
|
row.innerHTML = `
|
||||||
|
<td><input name="partidas[${idx}][descripcion]" class="form-control"></td>
|
||||||
|
<td><input name="partidas[${idx}][cantidad_comercial]" type="number" step="0.0001" class="form-control"></td>
|
||||||
|
<td><input name="partidas[${idx}][cantidad_tarifa]" type="number" step="0.0001" class="form-control"></td>
|
||||||
|
<td>
|
||||||
|
<select name="partidas[${idx}][unidad_comercial_id]" class="form-select searchable">
|
||||||
|
<option value="">-- Unidad --</option>
|
||||||
|
<?php foreach($unidades_medida as $um): ?>
|
||||||
|
<option value="<?= htmlspecialchars($um['id']) ?>"><?= htmlspecialchars($um['descripcion']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td><input name="partidas[${idx}][valor_factura]" type="number" step="0.01" class="form-control valor-partida"></td>
|
||||||
|
<td><input name="partidas[${idx}][peso_bruto]" type="number" step="0.0001" class="form-control"></td>
|
||||||
|
<td>
|
||||||
|
<select name="partidas[${idx}][tasa_preferencial]" class="form-select searchable">
|
||||||
|
<option value="">-- Selecciona --</option>
|
||||||
|
<option>General</option><option>TLC</option><option>PROSEC</option><option>ALADI</option><option>COMERCIALIZADORA</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td class="hide"><input name="partidas[${idx}][precio_unitario]" type="number" class="form-control"></td>
|
||||||
|
<td class="hide"><input name="partidas[${idx}][oma_factura]" class="form-control"></td>
|
||||||
|
<td><button type="button" class="btn btn-danger btn-sm remove-row">✖️</button></td>
|
||||||
|
`;
|
||||||
|
tbody.appendChild(row);
|
||||||
|
// Re-inicializar Choices.js en los nuevos selects
|
||||||
|
row.querySelectorAll('.searchable').forEach(el => {
|
||||||
new Choices(el, { searchEnabled: true, itemSelectText: '', shouldSort: false });
|
new Choices(el, { searchEnabled: true, itemSelectText: '', shouldSort: false });
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// 2) Cargar proveedores dinámicamente
|
// Manejador para controlar el overflow al abrir dropdowns
|
||||||
|
document.addEventListener('click', function(e) {
|
||||||
|
const tableContainer = document.querySelector('.table-responsive');
|
||||||
|
if (!tableContainer) return;
|
||||||
|
|
||||||
|
if (e.target.closest('.choices__inner')) {
|
||||||
|
tableContainer.style.overflow = 'visible';
|
||||||
|
} else {
|
||||||
|
tableContainer.style.overflow = 'auto';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelector('#tabla-partidas tbody').addEventListener('click', e => {
|
||||||
|
if (e.target.matches('.remove-row')) e.target.closest('tr').remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
// validate suma partidas == valor_factura
|
||||||
|
$('#solicitudForm').submit(function(e){
|
||||||
|
const total = parseFloat($('#valor_factura').val())||0;
|
||||||
|
let sum = 0;
|
||||||
|
$('.valor-partida').each(function(){ sum += parseFloat($(this).val())||0; });
|
||||||
|
if(Math.abs(sum - total) > 0.001){
|
||||||
|
e.preventDefault();
|
||||||
|
Swal.fire({
|
||||||
|
icon:'error',
|
||||||
|
title:'Error de validación',
|
||||||
|
text:`La suma de partidas (${sum.toFixed(2)}) no coincide con Valor Factura (${total.toFixed(2)}).`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// ✅ DIFERENCIA PRINCIPAL: Inicializar Choices.js en partidas existentes
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// Inicializar Choices.js en selects existentes de partidas (para edición)
|
||||||
|
document.querySelectorAll('#tabla-partidas .searchable').forEach(el => {
|
||||||
|
if (el.id !== 'proveedor_id') {
|
||||||
|
new Choices(el, { searchEnabled: true, itemSelectText: '', shouldSort: false });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Inicializar otros selects searchable (excepto proveedor_id que se maneja aparte)
|
||||||
|
document.querySelectorAll('.searchable').forEach(el => {
|
||||||
|
if (el.id !== 'proveedor_id' && !el.closest('#tabla-partidas')) {
|
||||||
|
new Choices(el, { searchEnabled: true, itemSelectText: '', shouldSort: false });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// proveedores script - ✅ DIFERENCIA: Pre-seleccionar proveedor existente
|
||||||
const proveedorEl = document.getElementById('proveedor_id');
|
const proveedorEl = document.getElementById('proveedor_id');
|
||||||
let proveedorChoices = null;
|
const proveedorActual = '<?= htmlspecialchars($factura['proveedor_clave'] ?? '') ?>'; // ← Proveedor actual
|
||||||
|
|
||||||
fetch('/IMPORTADORES/solicitud_importacion/ajax_proveedores')
|
fetch('/IMPORTADORES/solicitud_importacion/ajax_proveedores')
|
||||||
.then(res => res.ok ? res.json() : Promise.reject(res.status))
|
.then(res => { if (!res.ok) throw new Error(`HTTP ${res.status}`); return res.json(); })
|
||||||
.then(json => {
|
.then(json => {
|
||||||
proveedorEl.innerHTML = '<option value="">-- Selecciona Proveedor --</option>';
|
proveedorEl.innerHTML = '<option value="">-- Selecciona Proveedor --</option>';
|
||||||
json.results.forEach(item => {
|
json.results.forEach(item => {
|
||||||
const opt = document.createElement('option');
|
const opt = document.createElement('option');
|
||||||
opt.value = item.id;
|
opt.value = item.id;
|
||||||
opt.text = item.text;
|
opt.text = item.text;
|
||||||
|
// ✅ Pre-seleccionar si coincide con el proveedor actual
|
||||||
|
if (item.id === proveedorActual) {
|
||||||
|
opt.selected = true;
|
||||||
|
}
|
||||||
proveedorEl.add(opt);
|
proveedorEl.add(opt);
|
||||||
});
|
});
|
||||||
// destruir instancia previa si existe
|
if (proveedorEl._choice) proveedorEl._choice.destroy();
|
||||||
if (proveedorChoices) proveedorChoices.destroy();
|
new Choices(proveedorEl, { searchEnabled: true, itemSelectText: '', shouldSort: false });
|
||||||
proveedorChoices = new Choices(proveedorEl, {
|
|
||||||
searchEnabled: true,
|
|
||||||
itemSelectText: '',
|
|
||||||
shouldSort: false
|
|
||||||
});
|
|
||||||
// seleccionar valor actual
|
|
||||||
const current = '<?= htmlspecialchars($factura['proveedor_id'], ENT_QUOTES) ?>';
|
|
||||||
if (current) {
|
|
||||||
proveedorChoices.setChoiceByValue(current);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.error('Error cargando proveedores:', err);
|
console.error('Error cargando proveedores:', err);
|
||||||
proveedorEl.innerHTML = '<option value="">No fue posible cargar proveedores</option>';
|
proveedorEl.innerHTML = '<option value="">No fue posible cargar proveedores</option>';
|
||||||
});
|
});
|
||||||
|
|
||||||
// 3) Agregar partida dinámica
|
|
||||||
document.getElementById('add-partida').addEventListener('click', () => {
|
|
||||||
const tbody = document.querySelector('#tabla-partidas tbody');
|
|
||||||
const idx = tbody.querySelectorAll('tr').length;
|
|
||||||
const row = document.createElement('tr');
|
|
||||||
row.innerHTML = `
|
|
||||||
<td><input name="partidas[\${idx}][descripcion]" class="form-control"></td>
|
|
||||||
<td><input name="partidas[\${idx}][cantidad_comercial]" type="number" step="0.0001" class="form-control"></td>
|
|
||||||
<td><input name="partidas[\${idx}][cantidad_tarifa]" type="number" step="0.0001" class="form-control"></td>
|
|
||||||
<td><select name="partidas[\${idx}][unidad_comercial_id]" class="form-select searchable"><option value="">-- Unidad --</option>
|
|
||||||
<?php foreach($unidades_medida as $um): ?>
|
|
||||||
<option value="<?= htmlspecialchars($um['id']) ?>"><?= htmlspecialchars($um['descripcion']) ?></option>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</select></td>
|
|
||||||
<td><input name="partidas[\${idx}][valor_factura]" type="number" step="0.01" class="form-control valor-partida"></td>
|
|
||||||
<td><input name="partidas[\${idx}][peso_bruto]" type="number" step="0.0001" class="form-control"></td>
|
|
||||||
<td><select name="partidas[\${idx}][tasa_preferencial]" class="form-select searchable"><option value="">-- Selecciona --</option>
|
|
||||||
<option>General</option><option>TLC</option><option>PROSEC</option><option>ALADI</option><option>COMERCIALIZADORA</option>
|
|
||||||
</select></td>
|
|
||||||
<td class="hide"><input name="partidas[\${idx}][precio_unitario]" type="number" class="form-control"></td>
|
|
||||||
<td class="hide"><input name="partidas[\${idx}][oma_factura]" class="form-control"></td>
|
|
||||||
<td><button type="button" class="btn btn-danger btn-sm remove-row">✖️</button></td>
|
|
||||||
`;
|
|
||||||
tbody.appendChild(row);
|
|
||||||
// re-init Choices para nuevos selects
|
|
||||||
row.querySelectorAll('.searchable').forEach(el => {
|
|
||||||
new Choices(el, { searchEnabled: true, itemSelectText: '', shouldSort: false });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// 4) Remover partida
|
|
||||||
document.querySelector('#tabla-partidas tbody').addEventListener('click', e => {
|
|
||||||
if (e.target.matches('.remove-row')) {
|
|
||||||
e.target.closest('tr').remove();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 5) Validar suma de partidas
|
|
||||||
$('#solicitudForm').submit(function(e) {
|
|
||||||
const total = parseFloat($('.valor-total').val()) || 0;
|
|
||||||
let sum = 0;
|
|
||||||
$('.valor-partida').each(function() {
|
|
||||||
sum += parseFloat($(this).val()) || 0;
|
|
||||||
});
|
|
||||||
if (Math.abs(sum - total) > 0.01) {
|
|
||||||
e.preventDefault();
|
|
||||||
Swal.fire({
|
|
||||||
icon: 'error',
|
|
||||||
title: 'Error de validación',
|
|
||||||
text: `La suma de partidas (${sum.toFixed(2)}) no coincide con Valor Factura (${total.toFixed(2)})`
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
<?php include __DIR__ . '/../partials/sidebar_importador.php'; ?>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="es">
|
<html lang="es">
|
||||||
<head>
|
<head>
|
||||||
@@ -82,7 +84,7 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<?php include __DIR__ . '/../partials/sidebar_importador.php'; ?>
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h4>📄 Solicitudes de Importación</h4>
|
<h4>📄 Solicitudes de Importación</h4>
|
||||||
<a href="/IMPORTADORES/solicitud_importacion/crear" class="btn btn-success mb-3">➕ Nueva Solicitud</a>
|
<a href="/IMPORTADORES/solicitud_importacion/crear" class="btn btn-success mb-3">➕ Nueva Solicitud</a>
|
||||||
@@ -114,7 +116,7 @@
|
|||||||
<td><?= htmlspecialchars($f['fecha_factura']) ?></td>
|
<td><?= htmlspecialchars($f['fecha_factura']) ?></td>
|
||||||
<td><?= htmlspecialchars($f['numero_pedimento']) ?></td>
|
<td><?= htmlspecialchars($f['numero_pedimento']) ?></td>
|
||||||
<td><?= htmlspecialchars($f['incoterm']) ?></td>
|
<td><?= htmlspecialchars($f['incoterm']) ?></td>
|
||||||
<td><?= htmlspecialchars($f['pais_proveedor']) ?></td>
|
<td><?= htmlspecialchars($f['nombre_pais_proveedor']) ?></td>
|
||||||
<td><?= htmlspecialchars($f['tipo_moneda']) ?></td>
|
<td><?= htmlspecialchars($f['tipo_moneda']) ?></td>
|
||||||
<td><?= number_format($f['valor_factura'],2) ?></td>
|
<td><?= number_format($f['valor_factura'],2) ?></td>
|
||||||
<td>
|
<td>
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
<?php include __DIR__ . '/../partials/sidebar_importador.php'; ?>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="es">
|
<html lang="es">
|
||||||
<head>
|
<head>
|
||||||
@@ -77,17 +79,15 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<?php include __DIR__ . '/../partials/sidebar_importador.php'; ?>
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<br> <br>
|
<br> <br>
|
||||||
<h4>➕ Nuevo Transporte</h4>
|
<h4>➕ Nuevo Transporte</h4>
|
||||||
<form id="formTransCrear" action="/IMPORTADORES/transportes/guardar" method="POST" enctype="multipart/form-data" class="card p-4 shadow-sm">
|
<form id="formTransCrear" action="/IMPORTADORES/transportes/guardar" method="POST" enctype="multipart/form-data" class="card p-4 shadow-sm">
|
||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<label class="form-label">Vehículo *</label>
|
<label class="form-label">Contenedor *</label>
|
||||||
<input name="vehiculo" id="vehiculo" class="form-control" required>
|
<input name="vehiculo" id="vehiculo" class="form-control" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
@@ -104,7 +104,7 @@
|
|||||||
<option value="">Selecciona...</option>
|
<option value="">Selecciona...</option>
|
||||||
<?php foreach($transportistas as $tr): ?>
|
<?php foreach($transportistas as $tr): ?>
|
||||||
<option value="<?= $tr['id_transportista'] ?>">
|
<option value="<?= $tr['id_transportista'] ?>">
|
||||||
<?= htmlspecialchars($tr['nombre']) ?>
|
<?= htmlspecialchars(($tr['clave_identificador'] . ' - ' . $tr['nombre'])) ?>
|
||||||
</option>
|
</option>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
@@ -143,6 +143,7 @@
|
|||||||
// Si todas las validaciones pasan, el formulario se envía.
|
// Si todas las validaciones pasan, el formulario se envía.
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ if (!($_SESSION['usuario_id'] ?? false)) {
|
|||||||
<label class="form-label">Archivo CSV *</label>
|
<label class="form-label">Archivo CSV *</label>
|
||||||
<input type="file" name="csv" accept=".csv" class="form-control" required>
|
<input type="file" name="csv" accept=".csv" class="form-control" required>
|
||||||
</div>
|
</div>
|
||||||
<p>Descarga la plantilla y llena las columnas: <code>vehiculo, identificador_fiscal, id_transportista</code>.</p>
|
<p>Descarga la plantilla y llena las columnas: <code>contenedor, identificador_fiscal, id_transportista</code>.</p>
|
||||||
<a href="/IMPORTADORES/public/downloads/transportes_masivo_template.csv" class="btn btn-outline-secondary mb-3">
|
<a href="/IMPORTADORES/public/downloads/transportes_masivo_template.csv" class="btn btn-outline-secondary mb-3">
|
||||||
📥 Descargar plantilla
|
📥 Descargar plantilla
|
||||||
</a><br>
|
</a><br>
|
||||||
@@ -120,8 +120,7 @@ if (!($_SESSION['usuario_id'] ?? false)) {
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
const Toast = Swal.mixin({
|
const Toast = Swal.mixin({
|
||||||
@@ -149,3 +148,6 @@ if (!($_SESSION['usuario_id'] ?? false)) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user