This commit is contained in:
2025-10-21 11:41:30 -06:00
parent ed2ef4e01b
commit b1b9e4a77c
49 changed files with 14632 additions and 1736 deletions

View File

@@ -0,0 +1,558 @@
<?php
require_once __DIR__ . '/../helpers/session.php';
require_once __DIR__ . '/../../config/database.php';
require_once __DIR__ . '/../helpers/crypto.php';
function index()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
include __DIR__ . '/../../views/catalogo_pedimentos/index.php';
}
function lista()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
include __DIR__ . '/../../views/catalogo_pedimentos/lista.php';
}
function crear()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
// Obtener información del importador
$sqlImportador = "SELECT rfc, nombre, correo FROM informacion_general WHERE id_usuario = ?";
$stmtImportador = sqlsrv_query($conn, $sqlImportador, [$id_usuario]);
if ($stmtImportador === false) {
die("❌ Error al consultar información del importador: " . print_r(sqlsrv_errors(), true));
}
$importador = sqlsrv_fetch_array($stmtImportador, SQLSRV_FETCH_ASSOC);
// Obtener claves de pedimentos activas del usuario
$sqlClaves = "SELECT codigo, descripcion FROM claves_pedimentos_usuario
WHERE id_usuario = ? AND activo = 1 AND tipo_operacion = 'importacion'
ORDER BY codigo ASC";
$stmtClaves = sqlsrv_query($conn, $sqlClaves, [$id_usuario]);
$claves_pedimentos = [];
if ($stmtClaves !== false) {
while ($row = sqlsrv_fetch_array($stmtClaves, SQLSRV_FETCH_ASSOC)) {
$claves_pedimentos[] = $row;
}
}
include __DIR__ . '/../../views/catalogo_pedimentos/crear.php';
}
function guardar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado.");
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
// Obtener información del importador automáticamente
$sqlImportador = "SELECT rfc, nombre FROM informacion_general WHERE id_usuario = ?";
$stmtImportador = sqlsrv_query($conn, $sqlImportador, [$id_usuario]);
if ($stmtImportador === false) {
die("❌ Error al consultar información del importador: " . print_r(sqlsrv_errors(), true));
}
$importador = sqlsrv_fetch_array($stmtImportador, SQLSRV_FETCH_ASSOC);
if (!$importador) {
die("❌ Error: No se encontró información del importador. Configure su información general primero.");
}
// Obtener datos del formulario
$pedimento = trim($_POST['pedimento'] ?? '');
$clave_ped = trim($_POST['clave_ped'] ?? '');
$tipo_operacion = $_POST['tipo_operacion'] ?? 1; // Por defecto importación
$tipo_pedimento = $_POST['tipo_pedimento'] ?? 1; // Por defecto normal
$regimen = trim($_POST['regimen'] ?? '');
$destino = trim($_POST['destino'] ?? '');
// Fechas
$fecha_pedimento = $_POST['fecha_pedimento'] ?? null;
$fecha_inicio = $_POST['fecha_inicio'] ?? null;
$fecha_final = $_POST['fecha_final'] ?? null;
// Información adicional
$archivo_final_previo = trim($_POST['archivo_final_previo'] ?? '');
$acuse_cons = trim($_POST['acuse_cons'] ?? '');
$tipo = trim($_POST['tipo'] ?? '');
$status = isset($_POST['status']) ? (int)$_POST['status'] : 1;
// Validaciones
if (empty($pedimento)) {
die("❌ El número de pedimento es obligatorio.");
}
if (empty($clave_ped)) {
die("❌ La clave de pedimento es obligatoria.");
}
// Convertir fechas a formato YYYYMMDD si están presentes
$fecha_pedimento_int = null;
$fecha_inicio_int = null;
$fecha_final_int = null;
if ($fecha_pedimento) {
$fecha_pedimento_int = (int)str_replace('-', '', $fecha_pedimento);
}
if ($fecha_inicio) {
$fecha_inicio_int = (int)str_replace('-', '', $fecha_inicio);
}
if ($fecha_final) {
$fecha_final_int = (int)str_replace('-', '', $fecha_final);
}
$sql = "INSERT INTO PREVIOS_COMPARTIDOS_WS
(Pedimento, ClienteRFC, ClienteNombre, ClavePed, TipoOperacion, TipoPedimento,
Regimen, Destino, FechaPedimento, FechaInicio, FechaFinal,
ArchivoFinalPrevio, AcuseCons, Tipo, Status, Timestamp, id_usuario)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, GETDATE(), ?)";
$params = [
$pedimento,
$importador['rfc'],
$importador['nombre'],
$clave_ped,
$tipo_operacion,
$tipo_pedimento,
$regimen,
$destino,
$fecha_pedimento_int,
$fecha_inicio_int,
$fecha_final_int,
$archivo_final_previo,
$acuse_cons,
$tipo,
$status,
$id_usuario
];
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
die("❌ Error al guardar: " . print_r(sqlsrv_errors(), true));
}
header('Location: /IMPORTADORES/catalogo_pedimentos/lista?created=ok');
exit;
}
function editar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
$id = $_GET['id'] ?? null;
if (!$id || !is_numeric($id)) {
die("❌ ID inválido.");
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
// Obtener información del importador
$sqlImportador = "SELECT rfc, nombre FROM informacion_general WHERE id_usuario = ?";
$stmtImportador = sqlsrv_query($conn, $sqlImportador, [$id_usuario]);
if ($stmtImportador === false) {
die("❌ Error al consultar información del importador: " . print_r(sqlsrv_errors(), true));
}
$importador = sqlsrv_fetch_array($stmtImportador, SQLSRV_FETCH_ASSOC);
// Obtener claves de pedimentos activas del usuario
$sqlClaves = "SELECT codigo, descripcion FROM claves_pedimentos_usuario
WHERE id_usuario = ? AND activo = 1 AND tipo_operacion = 'importacion'
ORDER BY codigo ASC";
$stmtClaves = sqlsrv_query($conn, $sqlClaves, [$id_usuario]);
$claves_pedimentos = [];
if ($stmtClaves !== false) {
while ($row = sqlsrv_fetch_array($stmtClaves, SQLSRV_FETCH_ASSOC)) {
$claves_pedimentos[] = $row;
}
}
// Obtener datos del pedimento
$sql = "SELECT * FROM PREVIOS_COMPARTIDOS_WS WHERE IdPrevio = ?";
$stmt = sqlsrv_query($conn, $sql, [$id]);
if ($stmt === false) {
die("❌ Error en consulta: " . print_r(sqlsrv_errors(), true));
}
$previo = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (!$previo) {
die("❌ Pedimento no encontrado.");
}
include __DIR__ . '/../../views/catalogo_pedimentos/editar.php';
}
function actualizar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado.");
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
// Obtener información del importador automáticamente
$sqlImportador = "SELECT rfc, nombre FROM informacion_general WHERE id_usuario = ?";
$stmtImportador = sqlsrv_query($conn, $sqlImportador, [$id_usuario]);
if ($stmtImportador === false) {
die("❌ Error al consultar información del importador: " . print_r(sqlsrv_errors(), true));
}
$importador = sqlsrv_fetch_array($stmtImportador, SQLSRV_FETCH_ASSOC);
if (!$importador) {
die("❌ Error: No se encontró información del importador.");
}
$id_previo = $_POST['id_previo'] ?? null;
$pedimento = trim($_POST['pedimento'] ?? '');
$clave_ped = trim($_POST['clave_ped'] ?? '');
$tipo_operacion = $_POST['tipo_operacion'] ?? 1;
$tipo_pedimento = $_POST['tipo_pedimento'] ?? 1;
$regimen = trim($_POST['regimen'] ?? '');
$destino = trim($_POST['destino'] ?? '');
// Fechas
$fecha_pedimento = $_POST['fecha_pedimento'] ?? null;
$fecha_inicio = $_POST['fecha_inicio'] ?? null;
$fecha_final = $_POST['fecha_final'] ?? null;
// Información adicional
$archivo_final_previo = trim($_POST['archivo_final_previo'] ?? '');
$acuse_cons = trim($_POST['acuse_cons'] ?? '');
$tipo = trim($_POST['tipo'] ?? '');
$status = isset($_POST['status']) ? (int)$_POST['status'] : 1;
if (!$id_previo || !is_numeric($id_previo)) {
die("❌ ID inválido.");
}
// Validaciones
if (empty($pedimento)) {
die("❌ El número de pedimento es obligatorio.");
}
if (empty($clave_ped)) {
die("❌ La clave de pedimento es obligatoria.");
}
// Convertir fechas a formato YYYYMMDD si están presentes
$fecha_pedimento_int = null;
$fecha_inicio_int = null;
$fecha_final_int = null;
if ($fecha_pedimento) {
$fecha_pedimento_int = (int)str_replace('-', '', $fecha_pedimento);
}
if ($fecha_inicio) {
$fecha_inicio_int = (int)str_replace('-', '', $fecha_inicio);
}
if ($fecha_final) {
$fecha_final_int = (int)str_replace('-', '', $fecha_final);
}
$sql = "UPDATE PREVIOS_COMPARTIDOS_WS SET
Pedimento = ?, ClienteRFC = ?, ClienteNombre = ?, ClavePed = ?,
TipoOperacion = ?, TipoPedimento = ?, Regimen = ?, Destino = ?,
FechaPedimento = ?, FechaInicio = ?, FechaFinal = ?,
ArchivoFinalPrevio = ?, AcuseCons = ?, Tipo = ?, Status = ?
WHERE IdPrevio = ?";
$params = [
$pedimento,
$importador['rfc'],
$importador['nombre'],
$clave_ped,
$tipo_operacion,
$tipo_pedimento,
$regimen,
$destino,
$fecha_pedimento_int,
$fecha_inicio_int,
$fecha_final_int,
$archivo_final_previo,
$acuse_cons,
$tipo,
$status,
$id_previo
];
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
die("❌ Error al actualizar: " . print_r(sqlsrv_errors(), true));
}
header('Location: /IMPORTADORES/catalogo_pedimentos/lista?updated=ok');
exit;
}
function eliminar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
$id = $_GET['id'] ?? null;
if (!$id || !is_numeric($id)) {
die("❌ ID inválido.");
}
$conn = getConnection();
$sql = "DELETE FROM PREVIOS_COMPARTIDOS_WS WHERE IdPrevio = ?";
$stmt = sqlsrv_query($conn, $sql, [$id]);
if ($stmt === false) {
die("❌ Error al eliminar: " . print_r(sqlsrv_errors(), true));
}
header('Location: /IMPORTADORES/catalogo_pedimentos/lista?deleted=ok');
exit;
}
function ajax_lista()
{
if (!($_SESSION['usuario_id'] ?? false)) {
http_response_code(403);
echo json_encode([]);
exit;
}
$id_usuario = $_SESSION['usuario_id'];
$conn = getConnection();
// Obtener RFC del importador para filtrar solo sus pedimentos
$sqlImportador = "SELECT rfc FROM informacion_general WHERE id_usuario = ?";
$stmtImportador = sqlsrv_query($conn, $sqlImportador, [$id_usuario]);
if ($stmtImportador === false) {
echo json_encode([
"draw" => intval($_GET['draw'] ?? 0),
"recordsTotal" => 0,
"recordsFiltered" => 0,
"data" => [],
"error" => "Error al consultar información del importador"
]);
exit;
}
$importador = sqlsrv_fetch_array($stmtImportador, SQLSRV_FETCH_ASSOC);
if (!$importador) {
echo json_encode([
"draw" => intval($_GET['draw'] ?? 0),
"recordsTotal" => 0,
"recordsFiltered" => 0,
"data" => []
]);
exit;
}
// Parámetros de DataTables
$draw = intval($_GET['draw'] ?? 0);
$start = intval($_GET['start'] ?? 0);
$length = intval($_GET['length'] ?? 10);
$search = $_GET['search']['value'] ?? '';
// Total registros sin filtro
$sqlTotal = "SELECT COUNT(*) AS total FROM PREVIOS_COMPARTIDOS_WS WHERE ClienteRFC = ?";
$stmt = sqlsrv_query($conn, $sqlTotal, [$importador['rfc']]);
if ($stmt === false) {
echo json_encode([
"draw" => $draw,
"recordsTotal" => 0,
"recordsFiltered" => 0,
"data" => [],
"error" => "Error al contar registros totales"
]);
exit;
}
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
$recordsTotal = (int)($row['total'] ?? 0);
// Construir condiciones de filtro
$where = "ClienteRFC = ?";
$params = [$importador['rfc']];
if ($search !== '') {
$where .= " AND (Pedimento LIKE ? OR ClienteNombre LIKE ? OR ClavePed LIKE ?)";
$like = "%{$search}%";
$params = array_merge($params, [$like, $like, $like]);
}
// Total registros filtrados
$sqlFiltered = "SELECT COUNT(*) AS total FROM PREVIOS_COMPARTIDOS_WS WHERE $where";
$stmtF = sqlsrv_query($conn, $sqlFiltered, $params);
if ($stmtF === false) {
echo json_encode([
"draw" => $draw,
"recordsTotal" => $recordsTotal,
"recordsFiltered" => 0,
"data" => [],
"error" => "Error al contar registros filtrados"
]);
exit;
}
$rowF = sqlsrv_fetch_array($stmtF, SQLSRV_FETCH_ASSOC);
$recordsFiltered = (int)($rowF['total'] ?? 0);
// Datos de la página
$sqlData = "SELECT IdPrevio, Pedimento, ClienteRFC, ClienteNombre, Timestamp, Status
FROM PREVIOS_COMPARTIDOS_WS
WHERE $where
ORDER BY Timestamp DESC
OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
$params[] = $start;
$params[] = $length;
$stmtD = sqlsrv_query($conn, $sqlData, $params);
$data = [];
if ($stmtD !== false) {
while ($r = sqlsrv_fetch_array($stmtD, SQLSRV_FETCH_ASSOC)) {
$timestamp = $r['Timestamp'] instanceof DateTime ? $r['Timestamp']->format('Y-m-d H:i:s') : '';
$status_text = $r['Status'] == 1 ? 'Activo' : 'Inactivo';
$data[] = [
$r['IdPrevio'],
$r['Pedimento'],
$r['ClienteRFC'],
$r['ClienteNombre'],
$timestamp,
$status_text
];
}
}
$response = [
"draw" => $draw,
"recordsTotal" => $recordsTotal,
"recordsFiltered" => $recordsFiltered,
"data" => $data
];
header('Content-Type: application/json; charset=UTF-8');
echo json_encode($response, JSON_UNESCAPED_UNICODE);
exit;
}
function buscar_pedimentos()
{
if (!($_SESSION['usuario_id'] ?? false)) {
http_response_code(403);
echo json_encode([]);
exit;
}
$id_usuario = $_SESSION['usuario_id'];
$query = trim($_GET['q'] ?? '');
$limit = intval($_GET['limit'] ?? 10); // ✅ NUEVO: Parámetro limit con valor por defecto
// ✅ MODIFICADO: Para el panel de referencia, si no hay query, traer los más recientes
if (empty($query)) {
// Si no hay query, obtener los pedimentos más recientes para el panel de referencia
$whereCondition = "ClienteRFC = ? AND Status = 1";
$searchParams = [];
} else {
// Si hay query, mantener la lógica original de búsqueda
if (strlen($query) < 3) {
echo json_encode([]);
exit;
}
$whereCondition = "ClienteRFC = ? AND (Pedimento LIKE ? OR ClienteNombre LIKE ? OR ClavePed LIKE ?) AND Status = 1";
$like = "%{$query}%";
$searchParams = [$like, $like, $like];
}
$conn = getConnection();
// Obtener RFC del usuario para filtrar solo sus pedimentos
$sqlImportador = "SELECT rfc FROM informacion_general WHERE id_usuario = ?";
$stmtImportador = sqlsrv_query($conn, $sqlImportador, [$id_usuario]);
if ($stmtImportador === false) {
echo json_encode([]);
exit;
}
$importador = sqlsrv_fetch_array($stmtImportador, SQLSRV_FETCH_ASSOC);
if (!$importador) {
echo json_encode([]);
exit;
}
// ✅ MODIFICADO: Query dinámico con límite configurable
$sql = "SELECT TOP {$limit} IdPrevio, Pedimento, ClienteRFC, ClienteNombre, ClavePed, Timestamp
FROM PREVIOS_COMPARTIDOS_WS
WHERE {$whereCondition}
ORDER BY Timestamp DESC";
$params = array_merge([$importador['rfc']], $searchParams);
$stmt = sqlsrv_query($conn, $sql, $params);
$pedimentos = [];
if ($stmt !== false) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$fecha_formateada = '';
if ($row['Timestamp'] instanceof DateTime) {
$fecha_formateada = $row['Timestamp']->format('d/m/Y');
}
$pedimentos[] = [
'IdPrevio' => $row['IdPrevio'],
'Pedimento' => $row['Pedimento'],
'ClienteRFC' => $row['ClienteRFC'],
'ClienteNombre' => $row['ClienteNombre'],
'ClavePed' => $row['ClavePed'],
'fecha_formateada' => $fecha_formateada
];
}
}
header('Content-Type: application/json; charset=UTF-8');
echo json_encode($pedimentos, JSON_UNESCAPED_UNICODE);
exit;
}

View File

@@ -0,0 +1,553 @@
<?php
require_once __DIR__ . '/../helpers/session.php';
require_once __DIR__ . '/../../config/database.php';
require_once __DIR__ . '/../helpers/crypto.php';
function index()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
include __DIR__ . '/../../views/claves_pedimentos/index.php';
}
function lista()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
include __DIR__ . '/../../views/claves_pedimentos/lista.php';
}
function crear()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
include __DIR__ . '/../../views/claves_pedimentos/crear.php';
}
function guardar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado.");
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
$codigo = strtoupper(trim($_POST['codigo'] ?? ''));
$descripcion = trim($_POST['descripcion'] ?? '');
$tipo_operacion = $_POST['tipo_operacion'] ?? 'importacion';
$activo = isset($_POST['activo']) ? 1 : 0;
// Validaciones
if (empty($codigo) || empty($descripcion)) {
die("❌ El código y descripción son obligatorios.");
}
if (strlen($codigo) > 10) {
die("❌ El código no puede tener más de 10 caracteres.");
}
if (!preg_match('/^[A-Z0-9]+$/', $codigo)) {
die("❌ El código solo puede contener letras y números.");
}
// Verificar que no exista el código para este usuario
$sqlCheck = "SELECT COUNT(*) as count FROM claves_pedimentos_usuario WHERE id_usuario = ? AND codigo = ?";
$stmtCheck = sqlsrv_query($conn, $sqlCheck, [$id_usuario, $codigo]);
if ($stmtCheck === false) {
die("❌ Error al verificar código existente: " . print_r(sqlsrv_errors(), true));
}
$result = sqlsrv_fetch_array($stmtCheck, SQLSRV_FETCH_ASSOC);
if ($result['count'] > 0) {
die("❌ Ya existe una clave con el código '{$codigo}' para este usuario.");
}
$sql = "INSERT INTO claves_pedimentos_usuario
(id_usuario, codigo, descripcion, tipo_operacion, activo, fecha_creacion, fecha_modificacion)
VALUES (?, ?, ?, ?, ?, GETDATE(), GETDATE())";
$params = [$id_usuario, $codigo, $descripcion, $tipo_operacion, $activo];
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
die("❌ Error al guardar: " . print_r(sqlsrv_errors(), true));
}
header('Location: /IMPORTADORES/claves_pedimentos/lista?created=ok');
exit;
}
function editar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
$id = $_GET['id'] ?? null;
$id_usuario = $_SESSION['usuario_id'];
if (!$id || !is_numeric($id)) {
die("❌ ID inválido.");
}
$conn = getConnection();
$sql = "SELECT * FROM claves_pedimentos_usuario WHERE id_clave_pedimento = ? AND id_usuario = ?";
$stmt = sqlsrv_query($conn, $sql, [$id, $id_usuario]);
if ($stmt === false) {
die("❌ Error en consulta: " . print_r(sqlsrv_errors(), true));
}
$clave = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (!$clave) {
die("❌ Clave de pedimento no encontrada.");
}
include __DIR__ . '/../../views/claves_pedimentos/editar.php';
}
function actualizar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado.");
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
$id_clave_pedimento = $_POST['id_clave_pedimento'] ?? null;
$codigo = strtoupper(trim($_POST['codigo'] ?? ''));
$descripcion = trim($_POST['descripcion'] ?? '');
$tipo_operacion = $_POST['tipo_operacion'] ?? 'importacion';
$activo = isset($_POST['activo']) ? 1 : 0;
if (!$id_clave_pedimento || !is_numeric($id_clave_pedimento)) {
die("❌ ID inválido.");
}
// Validaciones
if (empty($codigo) || empty($descripcion)) {
die("❌ El código y descripción son obligatorios.");
}
if (strlen($codigo) > 10) {
die("❌ El código no puede tener más de 10 caracteres.");
}
if (!preg_match('/^[A-Z0-9]+$/', $codigo)) {
die("❌ El código solo puede contener letras y números.");
}
// Verificar que no exista otro código igual (excepto el actual)
$sqlCheck = "SELECT COUNT(*) as count FROM claves_pedimentos_usuario
WHERE id_usuario = ? AND codigo = ? AND id_clave_pedimento != ?";
$stmtCheck = sqlsrv_query($conn, $sqlCheck, [$id_usuario, $codigo, $id_clave_pedimento]);
if ($stmtCheck === false) {
die("❌ Error al verificar código existente: " . print_r(sqlsrv_errors(), true));
}
$result = sqlsrv_fetch_array($stmtCheck, SQLSRV_FETCH_ASSOC);
if ($result['count'] > 0) {
die("❌ Ya existe otra clave con el código '{$codigo}' para este usuario.");
}
$sql = "UPDATE claves_pedimentos_usuario SET
codigo = ?, descripcion = ?, tipo_operacion = ?, activo = ?, fecha_modificacion = GETDATE()
WHERE id_clave_pedimento = ? AND id_usuario = ?";
$params = [$codigo, $descripcion, $tipo_operacion, $activo, $id_clave_pedimento, $id_usuario];
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
die("❌ Error al actualizar: " . print_r(sqlsrv_errors(), true));
}
header('Location: /IMPORTADORES/claves_pedimentos/lista?updated=ok');
exit;
}
function eliminar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
$id = $_GET['id'] ?? null;
$id_usuario = $_SESSION['usuario_id'];
if (!$id || !is_numeric($id)) {
die("❌ ID inválido.");
}
$conn = getConnection();
$sql = "DELETE FROM claves_pedimentos_usuario WHERE id_clave_pedimento = ? AND id_usuario = ?";
$stmt = sqlsrv_query($conn, $sql, [$id, $id_usuario]);
if ($stmt === false) {
die("❌ Error al eliminar: " . print_r(sqlsrv_errors(), true));
}
header('Location: /IMPORTADORES/claves_pedimentos/lista?deleted=ok');
exit;
}
function ajax_lista()
{
if (!($_SESSION['usuario_id'] ?? false)) {
http_response_code(403);
echo json_encode([]);
exit;
}
$id_usuario = $_SESSION['usuario_id'];
$conn = getConnection();
// Parámetros de DataTables
$draw = intval($_GET['draw'] ?? 0);
$start = intval($_GET['start'] ?? 0);
$length = intval($_GET['length'] ?? 10);
$search = $_GET['search']['value'] ?? '';
// Total registros sin filtro
$sqlTotal = "SELECT COUNT(*) AS total FROM claves_pedimentos_usuario WHERE id_usuario = ?";
$stmt = sqlsrv_query($conn, $sqlTotal, [$id_usuario]);
if ($stmt === false) {
echo json_encode([
"draw" => $draw,
"recordsTotal" => 0,
"recordsFiltered" => 0,
"data" => [],
"error" => "Error al contar registros totales"
]);
exit;
}
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
$recordsTotal = (int)($row['total'] ?? 0);
// Construir condiciones de filtro
$where = "id_usuario = ?";
$params = [$id_usuario];
if ($search !== '') {
$where .= " AND (codigo LIKE ? OR descripcion LIKE ? OR tipo_operacion LIKE ?)";
$like = "%{$search}%";
$params = array_merge($params, [$like, $like, $like]);
}
// Total registros filtrados
$sqlFiltered = "SELECT COUNT(*) AS total FROM claves_pedimentos_usuario WHERE $where";
$stmtF = sqlsrv_query($conn, $sqlFiltered, $params);
if ($stmtF === false) {
echo json_encode([
"draw" => $draw,
"recordsTotal" => $recordsTotal,
"recordsFiltered" => 0,
"data" => [],
"error" => "Error al contar registros filtrados"
]);
exit;
}
$rowF = sqlsrv_fetch_array($stmtF, SQLSRV_FETCH_ASSOC);
$recordsFiltered = (int)($rowF['total'] ?? 0);
// Datos de la página
$sqlData = "SELECT id_clave_pedimento, codigo, descripcion, tipo_operacion,
CASE WHEN activo = 1 THEN 'Activo' ELSE 'Inactivo' END as estado,
FORMAT(fecha_creacion, 'dd/MM/yyyy HH:mm') as fecha_creacion
FROM claves_pedimentos_usuario
WHERE $where
ORDER BY codigo ASC
OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
$params[] = $start;
$params[] = $length;
$stmtD = sqlsrv_query($conn, $sqlData, $params);
$data = [];
if ($stmtD !== false) {
while ($r = sqlsrv_fetch_array($stmtD, SQLSRV_FETCH_ASSOC)) {
$data[] = [
$r['id_clave_pedimento'],
$r['codigo'],
$r['descripcion'],
ucfirst($r['tipo_operacion']),
$r['estado'],
$r['fecha_creacion']
];
}
}
$response = [
"draw" => $draw,
"recordsTotal" => $recordsTotal,
"recordsFiltered" => $recordsFiltered,
"data" => $data
];
header('Content-Type: application/json; charset=UTF-8');
echo json_encode($response, JSON_UNESCAPED_UNICODE);
exit;
}
function inicializar_claves_usuario()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
// Verificar si ya tiene claves configuradas
$sqlCheck = "SELECT COUNT(*) as count FROM claves_pedimentos_usuario WHERE id_usuario = ?";
$stmtCheck = sqlsrv_query($conn, $sqlCheck, [$id_usuario]);
if ($stmtCheck === false) {
die("❌ Error al verificar claves existentes: " . print_r(sqlsrv_errors(), true));
}
$result = sqlsrv_fetch_array($stmtCheck, SQLSRV_FETCH_ASSOC);
if ($result['count'] > 0) {
header('Location: /IMPORTADORES/claves_pedimentos/lista?info=already_initialized');
exit;
}
// Claves de pedimentos por defecto para importación
$claves_default = [
['A1', 'Importación definitiva de mercancías', 'importacion'],
['A3', 'Importación definitiva de vehículos usados', 'importacion'],
['A4', 'Importación definitiva de vehículos nuevos', 'importacion'],
['B1', 'Importación temporal para elaborar, transformar o reparar', 'importacion'],
['C1', 'Importación definitiva de mercancías donadas', 'importacion'],
['G1', 'Importación de mercancías con Programa IMMEX', 'importacion'],
['I1', 'Importación definitiva exenta', 'importacion'],
['J1', 'Importación temporal para reexportación en el mismo estado', 'importacion'],
['L1', 'Importación definitiva con franquicia arancelaria con TLC', 'importacion'],
['M1', 'Importación de menajes de casa', 'importacion'],
['N1', 'Importación de equipaje', 'importacion'],
['P1', 'Importación temporal de remolques y semirremolques', 'importacion'],
['R1', 'Importación temporal de contenedores', 'importacion'],
['S1', 'Importación temporal de vehículos', 'importacion'],
['T1', 'Importación temporal de enseres de tripulantes', 'importacion'],
['V1', 'Importación temporal de mercancías para exposición', 'importacion']
];
$sql = "INSERT INTO claves_pedimentos_usuario
(id_usuario, codigo, descripcion, tipo_operacion, activo, fecha_creacion, fecha_modificacion)
VALUES (?, ?, ?, ?, 1, GETDATE(), GETDATE())";
$insertadas = 0;
foreach ($claves_default as $clave) {
$params = [$id_usuario, $clave[0], $clave[1], $clave[2]];
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt !== false) {
$insertadas++;
}
}
if ($insertadas > 0) {
header('Location: /IMPORTADORES/claves_pedimentos/lista?created=initialized');
} else {
die("❌ Error al inicializar las claves de pedimentos.");
}
exit;
}
function importar_csv()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
include __DIR__ . '/../../views/claves_pedimentos/importar_csv.php';
}
function procesar_csv()
{
if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado.");
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
// Verificar que se subió un archivo
if (!isset($_FILES['csv_file']) || $_FILES['csv_file']['error'] !== UPLOAD_ERR_OK) {
die("❌ Error: No se pudo cargar el archivo CSV.");
}
$archivo_csv = $_FILES['csv_file']['tmp_name'];
$nombre_archivo = $_FILES['csv_file']['name'];
// Validar extensión
if (!str_ends_with(strtolower($nombre_archivo), '.csv')) {
die("❌ Error: El archivo debe tener extensión .csv");
}
// Opciones de importación
$omitir_duplicados = isset($_POST['omitir_duplicados']);
$activar_todas = isset($_POST['activar_todas']);
try {
// Leer archivo CSV
$archivo = fopen($archivo_csv, 'r');
if (!$archivo) {
die("❌ Error: No se pudo abrir el archivo CSV.");
}
// Leer encabezados
$encabezados = fgetcsv($archivo, 1000, ',');
if (!$encabezados) {
fclose($archivo);
die("❌ Error: El archivo CSV está vacío o no tiene el formato correcto.");
}
// Validar encabezados requeridos
$encabezados_requeridos = ['codigo', 'descripcion', 'tipo_operacion', 'activo'];
$encabezados_faltantes = array_diff($encabezados_requeridos, $encabezados);
if (!empty($encabezados_faltantes)) {
fclose($archivo);
die("❌ Error: Faltan las siguientes columnas: " . implode(', ', $encabezados_faltantes));
}
$insertadas = 0;
$omitidas = 0;
$errores = [];
$fila_numero = 1;
// SQL para verificar códigos existentes
$sqlCheck = "SELECT COUNT(*) as count FROM claves_pedimentos_usuario WHERE id_usuario = ? AND codigo = ?";
// SQL para insertar
$sqlInsert = "INSERT INTO claves_pedimentos_usuario
(id_usuario, codigo, descripcion, tipo_operacion, activo, fecha_creacion, fecha_modificacion)
VALUES (?, ?, ?, ?, ?, GETDATE(), GETDATE())";
// Procesar cada fila
while (($fila = fgetcsv($archivo, 1000, ',')) !== FALSE) {
$fila_numero++;
if (count($fila) < count($encabezados_requeridos)) {
$errores[] = "Fila $fila_numero: Datos insuficientes";
continue;
}
// Crear array asociativo
$datos = array_combine($encabezados, $fila);
// Validar datos
$codigo = strtoupper(trim($datos['codigo']));
$descripcion = trim($datos['descripcion']);
$tipo_operacion = trim($datos['tipo_operacion']);
$activo = $activar_todas ? 1 : (int)($datos['activo'] ?? 1);
// Validaciones
if (empty($codigo)) {
$errores[] = "Fila $fila_numero: Código vacío";
continue;
}
if (empty($descripcion)) {
$errores[] = "Fila $fila_numero: Descripción vacía";
continue;
}
if (!in_array($tipo_operacion, ['importacion', 'exportacion'])) {
$errores[] = "Fila $fila_numero: Tipo de operación inválido ($tipo_operacion)";
continue;
}
if (strlen($codigo) > 10) {
$errores[] = "Fila $fila_numero: Código muy largo (máximo 10 caracteres)";
continue;
}
if (!preg_match('/^[A-Z0-9]+$/', $codigo)) {
$errores[] = "Fila $fila_numero: Código inválido (solo letras y números)";
continue;
}
// Verificar si ya existe
if ($omitir_duplicados) {
$stmtCheck = sqlsrv_query($conn, $sqlCheck, [$id_usuario, $codigo]);
if ($stmtCheck === false) {
$errores[] = "Fila $fila_numero: Error al verificar código existente";
continue;
}
$result = sqlsrv_fetch_array($stmtCheck, SQLSRV_FETCH_ASSOC);
if ($result['count'] > 0) {
$omitidas++;
continue;
}
}
// Insertar registro
$params = [$id_usuario, $codigo, $descripcion, $tipo_operacion, $activo];
$stmt = sqlsrv_query($conn, $sqlInsert, $params);
if ($stmt === false) {
$sql_errors = sqlsrv_errors();
$errores[] = "Fila $fila_numero: Error al insertar - " . $sql_errors[0]['message'];
} else {
$insertadas++;
}
}
fclose($archivo);
// Preparar mensaje de resultado
$mensaje = "✅ Proceso completado:";
$mensaje .= "<br>• Registros insertados: $insertadas";
if ($omitidas > 0) {
$mensaje .= "<br>• Registros omitidos (duplicados): $omitidas";
}
if (!empty($errores)) {
$mensaje .= "<br>• Errores encontrados: " . count($errores);
$mensaje .= "<br><br>Detalle de errores:<br>" . implode("<br>", array_slice($errores, 0, 10));
if (count($errores) > 10) {
$mensaje .= "<br>... y " . (count($errores) - 10) . " errores más.";
}
}
// Redirigir con resultado
$encoded_message = urlencode($mensaje);
header("Location: /IMPORTADORES/claves_pedimentos/lista?imported=ok&message=" . $encoded_message);
exit;
} catch (Exception $e) {
die("❌ Error inesperado: " . $e->getMessage());
}
}

View File

@@ -1112,4 +1112,38 @@ function cambiarPassword()
<script>
setTimeout(() => { window.location.href = '/IMPORTADORES/login'; }, 4000);
</script>";
}
}
// MÉTODOS ADICIONALES CON NOMBRES DE RUTA COMPATIBLES
function enviar_codigo()
{
// Redirigir al método camelCase existente
return enviarCodigo();
}
function verificar_codigo_recuperacion()
{
// Redirigir al método camelCase existente
return verificarCodigo();
}
function reenviar_codigo()
{
// Redirigir al método camelCase existente
return reenviarCodigo();
}
function actualizar_password()
{
// Redirigir al método camelCase existente
return cambiarPassword();
}
function verificar_codigo()
{
// Mostrar vista de verificar código
return verificarCodigoVista();
}
?>

190
app/controllers/mve.php Normal file
View File

@@ -0,0 +1,190 @@
<?php
require_once __DIR__ . '/../../config/database.php';
require_once __DIR__ . '/../helpers/session.php';
function index() {
include __DIR__ . '/../../views/mve/lista.php';
}
function ajax_guardar_datos_factura() {
try {
// Validar que el usuario esté autenticado
if (!isset($_SESSION['user_id'])) {
echo json_encode(['success' => false, 'message' => 'Usuario no autenticado']);
return;
}
$id_factura = $_POST['id_factura'] ?? null;
$id_pedimento = $_POST['id_pedimento'] ?? null;
$datos_art65 = json_decode($_POST['datos_art65'] ?? '{}', true);
$datos_art66 = json_decode($_POST['datos_art66'] ?? '{}', true);
if (!$id_factura || !$id_pedimento) {
echo json_encode(['success' => false, 'message' => 'Faltan datos requeridos']);
return;
}
$db = getDB();
// Verificar si ya existen datos para esta factura
$stmt = $db->prepare("SELECT id FROM mve_facturas_datos WHERE id_pedimento = ? AND id_factura = ?");
$stmt->execute([$id_pedimento, $id_factura]);
$existe = $stmt->fetch();
if ($existe) {
// Actualizar registro existente
$sql = "UPDATE mve_facturas_datos SET
art65_fecha_transporte = ?, art65_importe_transporte = ?,
art65_fecha_descuentos = ?, art65_importe_descuentos = ?,
art65_fecha_posteriores = ?, art65_importe_posteriores = ?,
art65_fecha_contribuciones = ?, art65_importe_contribuciones = ?,
art65_fecha_pagos_vendedor = ?, art65_importe_pagos_vendedor = ?,
art66_fecha_comisiones = ?, art66_importe_comisiones = ?, art66_cargo_comisiones = ?,
art66_fecha_envases = ?, art66_importe_envases = ?, art66_cargo_envases = ?,
art66_fecha_embalaje = ?, art66_importe_embalaje = ?, art66_cargo_embalaje = ?,
art66_fecha_transporte_dec = ?, art66_importe_transporte_dec = ?, art66_cargo_transporte_dec = ?,
art66_fecha_ingenieria = ?, art66_importe_ingenieria = ?, art66_cargo_ingenieria = ?,
art66_fecha_regalias = ?, art66_importe_regalias = ?, art66_cargo_regalias = ?,
art66_fecha_producto = ?, art66_importe_producto = ?, art66_cargo_producto = ?,
fecha_actualizacion = NOW()
WHERE id_pedimento = ? AND id_factura = ?";
$params = [
$datos_art65['fecha_transporte'] ?: null, $datos_art65['importe_transporte'] ?: null,
$datos_art65['fecha_descuentos'] ?: null, $datos_art65['importe_descuentos'] ?: null,
$datos_art65['fecha_posteriores'] ?: null, $datos_art65['importe_posteriores'] ?: null,
$datos_art65['fecha_contribuciones'] ?: null, $datos_art65['importe_contribuciones'] ?: null,
$datos_art65['fecha_pagos_vendedor'] ?: null, $datos_art65['importe_pagos_vendedor'] ?: null,
$datos_art66['fecha_comisiones'] ?: null, $datos_art66['importe_comisiones'] ?: null, $datos_art66['cargo_comisiones'] ?: null,
$datos_art66['fecha_envases'] ?: null, $datos_art66['importe_envases'] ?: null, $datos_art66['cargo_envases'] ?: null,
$datos_art66['fecha_embalaje'] ?: null, $datos_art66['importe_embalaje'] ?: null, $datos_art66['cargo_embalaje'] ?: null,
$datos_art66['fecha_transporte_dec'] ?: null, $datos_art66['importe_transporte_dec'] ?: null, $datos_art66['cargo_transporte_dec'] ?: null,
$datos_art66['fecha_ingenieria'] ?: null, $datos_art66['importe_ingenieria'] ?: null, $datos_art66['cargo_ingenieria'] ?: null,
$datos_art66['fecha_regalias'] ?: null, $datos_art66['importe_regalias'] ?: null, $datos_art66['cargo_regalias'] ?: null,
$datos_art66['fecha_producto'] ?: null, $datos_art66['importe_producto'] ?: null, $datos_art66['cargo_producto'] ?: null,
$id_pedimento, $id_factura
];
} else {
// Crear nuevo registro
$sql = "INSERT INTO mve_facturas_datos (
id_pedimento, id_factura, numero_factura,
art65_fecha_transporte, art65_importe_transporte,
art65_fecha_descuentos, art65_importe_descuentos,
art65_fecha_posteriores, art65_importe_posteriores,
art65_fecha_contribuciones, art65_importe_contribuciones,
art65_fecha_pagos_vendedor, art65_importe_pagos_vendedor,
art66_fecha_comisiones, art66_importe_comisiones, art66_cargo_comisiones,
art66_fecha_envases, art66_importe_envases, art66_cargo_envases,
art66_fecha_embalaje, art66_importe_embalaje, art66_cargo_embalaje,
art66_fecha_transporte_dec, art66_importe_transporte_dec, art66_cargo_transporte_dec,
art66_fecha_ingenieria, art66_importe_ingenieria, art66_cargo_ingenieria,
art66_fecha_regalias, art66_importe_regalias, art66_cargo_regalias,
art66_fecha_producto, art66_importe_producto, art66_cargo_producto,
usuario_creacion
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$params = [
$id_pedimento, $id_factura, "FACTURA-$id_factura",
$datos_art65['fecha_transporte'] ?: null, $datos_art65['importe_transporte'] ?: null,
$datos_art65['fecha_descuentos'] ?: null, $datos_art65['importe_descuentos'] ?: null,
$datos_art65['fecha_posteriores'] ?: null, $datos_art65['importe_posteriores'] ?: null,
$datos_art65['fecha_contribuciones'] ?: null, $datos_art65['importe_contribuciones'] ?: null,
$datos_art65['fecha_pagos_vendedor'] ?: null, $datos_art65['importe_pagos_vendedor'] ?: null,
$datos_art66['fecha_comisiones'] ?: null, $datos_art66['importe_comisiones'] ?: null, $datos_art66['cargo_comisiones'] ?: null,
$datos_art66['fecha_envases'] ?: null, $datos_art66['importe_envases'] ?: null, $datos_art66['cargo_envases'] ?: null,
$datos_art66['fecha_embalaje'] ?: null, $datos_art66['importe_embalaje'] ?: null, $datos_art66['cargo_embalaje'] ?: null,
$datos_art66['fecha_transporte_dec'] ?: null, $datos_art66['importe_transporte_dec'] ?: null, $datos_art66['cargo_transporte_dec'] ?: null,
$datos_art66['fecha_ingenieria'] ?: null, $datos_art66['importe_ingenieria'] ?: null, $datos_art66['cargo_ingenieria'] ?: null,
$datos_art66['fecha_regalias'] ?: null, $datos_art66['importe_regalias'] ?: null, $datos_art66['cargo_regalias'] ?: null,
$datos_art66['fecha_producto'] ?: null, $datos_art66['importe_producto'] ?: null, $datos_art66['cargo_producto'] ?: null,
$_SESSION['user_id']
];
}
$stmt = $db->prepare($sql);
$resultado = $stmt->execute($params);
if ($resultado) {
echo json_encode(['success' => true, 'message' => 'Datos guardados correctamente']);
} else {
echo json_encode(['success' => false, 'message' => 'Error al guardar los datos']);
}
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => 'Error interno: ' . $e->getMessage()]);
}
}
function ajax_obtener_datos_factura() {
try {
$id_factura = $_GET['id_factura'] ?? null;
if (!$id_factura) {
echo json_encode(['success' => false, 'message' => 'ID de factura requerido']);
return;
}
$db = getDB();
$stmt = $db->prepare("SELECT * FROM mve_facturas_datos WHERE id_factura = ?");
$stmt->execute([$id_factura]);
$datos = $stmt->fetch(PDO::FETCH_ASSOC);
if ($datos) {
// Estructurar datos para el frontend
$datosEstructurados = [
'art65' => [
'fecha_transporte' => $datos['art65_fecha_transporte'],
'importe_transporte' => $datos['art65_importe_transporte'],
'fecha_descuentos' => $datos['art65_fecha_descuentos'],
'importe_descuentos' => $datos['art65_importe_descuentos'],
'fecha_posteriores' => $datos['art65_fecha_posteriores'],
'importe_posteriores' => $datos['art65_importe_posteriores'],
'fecha_contribuciones' => $datos['art65_fecha_contribuciones'],
'importe_contribuciones' => $datos['art65_importe_contribuciones'],
'fecha_pagos_vendedor' => $datos['art65_fecha_pagos_vendedor'],
'importe_pagos_vendedor' => $datos['art65_importe_pagos_vendedor']
],
'art66' => [
'fecha_comisiones' => $datos['art66_fecha_comisiones'],
'importe_comisiones' => $datos['art66_importe_comisiones'],
'cargo_comisiones' => $datos['art66_cargo_comisiones'],
'fecha_envases' => $datos['art66_fecha_envases'],
'importe_envases' => $datos['art66_importe_envases'],
'cargo_envases' => $datos['art66_cargo_envases'],
'fecha_embalaje' => $datos['art66_fecha_embalaje'],
'importe_embalaje' => $datos['art66_importe_embalaje'],
'cargo_embalaje' => $datos['art66_cargo_embalaje'],
'fecha_transporte_dec' => $datos['art66_fecha_transporte_dec'],
'importe_transporte_dec' => $datos['art66_importe_transporte_dec'],
'cargo_transporte_dec' => $datos['art66_cargo_transporte_dec'],
'fecha_ingenieria' => $datos['art66_fecha_ingenieria'],
'importe_ingenieria' => $datos['art66_importe_ingenieria'],
'cargo_ingenieria' => $datos['art66_cargo_ingenieria'],
'fecha_regalias' => $datos['art66_fecha_regalias'],
'importe_regalias' => $datos['art66_importe_regalias'],
'cargo_regalias' => $datos['art66_cargo_regalias'],
'fecha_producto' => $datos['art66_fecha_producto'],
'importe_producto' => $datos['art66_importe_producto'],
'cargo_producto' => $datos['art66_cargo_producto']
]
];
echo json_encode(['success' => true, 'datos' => $datosEstructurados]);
} else {
echo json_encode(['success' => true, 'datos' => null]);
}
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => 'Error interno: ' . $e->getMessage()]);
}
}

View File

@@ -342,4 +342,281 @@ function obtenerCorreos($conn, $id_usuario)
}
return $correos;
}
function ventanillaUnica()
{
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'] ?? null;
// Asegúrate de que el usuario está autenticado
if (!$id_usuario || ($_SESSION['pendiente_confirmacion'] ?? false)) {
die("Usuario no autenticado.");
}
// Obtener configuración actual de ventanilla única
$configuracion_vu = obtenerConfiguracionVU($conn, $id_usuario);
include __DIR__ . '/../../views/seguridad/ventanilla_unica.php';
}
function guardarConfiguracionVU()
{
// Solo ejecutar si es una petición POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: /IMPORTADORES/seguridad/ventanillaUnica');
exit;
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'] ?? null;
if (!$id_usuario || ($_SESSION['pendiente_confirmacion'] ?? false)) {
die("No autorizado - Sesión inválida");
}
// Obtener datos del formulario (sin ruta_ejecutable)
$clave_fiel = trim($_POST['clave_fiel'] ?? '');
$rfc_usuario_vu = trim($_POST['rfc_usuario_vu'] ?? '');
$clave_webservice = trim($_POST['clave_webservice'] ?? '');
// Validar campos obligatorios (sin ruta_ejecutable)
if (empty($clave_fiel) || empty($rfc_usuario_vu)) {
$_SESSION['config_error'] = 'Los campos Clave FIEL y RFC Usuario VU son obligatorios.';
header('Location: /IMPORTADORES/seguridad/ventanillaUnica');
exit;
}
// Obtener configuración actual para conservar archivos existentes
$configuracion_actual = obtenerConfiguracionVU($conn, $id_usuario);
$ruta_archivo_key = $configuracion_actual['ruta_archivo_key'];
$ruta_archivo_cer = $configuracion_actual['ruta_archivo_cer'];
// Directorio para archivos de certificados
$upload_dir = __DIR__ . '/../../storage/certificados/';
if (!is_dir($upload_dir)) {
mkdir($upload_dir, 0755, true);
}
// Procesar archivo KEY
if (!empty($_FILES['archivo_key']['tmp_name']) && $_FILES['archivo_key']['error'] === UPLOAD_ERR_OK) {
$key_extension = pathinfo($_FILES['archivo_key']['name'], PATHINFO_EXTENSION);
if (strtolower($key_extension) !== 'key') {
$_SESSION['config_error'] = 'El archivo KEY debe tener extensión .key';
header('Location: /IMPORTADORES/seguridad/ventanillaUnica');
exit;
}
$key_filename = 'key_' . $id_usuario . '_' . time() . '.key';
$key_destination = $upload_dir . $key_filename;
if (move_uploaded_file($_FILES['archivo_key']['tmp_name'], $key_destination)) {
// Eliminar archivo anterior si existe
if ($ruta_archivo_key && file_exists($ruta_archivo_key)) {
unlink($ruta_archivo_key);
}
$ruta_archivo_key = $key_destination;
} else {
$_SESSION['config_error'] = 'Error al subir el archivo KEY.';
header('Location: /IMPORTADORES/seguridad/ventanillaUnica');
exit;
}
}
// Procesar archivo CER
if (!empty($_FILES['archivo_cer']['tmp_name']) && $_FILES['archivo_cer']['error'] === UPLOAD_ERR_OK) {
$cer_extension = pathinfo($_FILES['archivo_cer']['name'], PATHINFO_EXTENSION);
if (strtolower($cer_extension) !== 'cer') {
$_SESSION['config_error'] = 'El archivo CER debe tener extensión .cer';
header('Location: /IMPORTADORES/seguridad/ventanillaUnica');
exit;
}
$cer_filename = 'cer_' . $id_usuario . '_' . time() . '.cer';
$cer_destination = $upload_dir . $cer_filename;
if (move_uploaded_file($_FILES['archivo_cer']['tmp_name'], $cer_destination)) {
// Eliminar archivo anterior si existe
if ($ruta_archivo_cer && file_exists($ruta_archivo_cer)) {
unlink($ruta_archivo_cer);
}
$ruta_archivo_cer = $cer_destination;
} else {
$_SESSION['config_error'] = 'Error al subir el archivo CER.';
header('Location: /IMPORTADORES/seguridad/ventanillaUnica');
exit;
}
}
// Validar que se hayan subido los certificados (obligatorios para nueva configuración)
if (empty($ruta_archivo_key) || empty($ruta_archivo_cer)) {
$_SESSION['config_error'] = 'Los archivos CER y KEY son obligatorios.';
header('Location: /IMPORTADORES/seguridad/ventanillaUnica');
exit;
}
// Encriptar las contraseñas sensibles
$clave_fiel_encrypted = encrypt($clave_fiel);
$clave_webservice_encrypted = !empty($clave_webservice) ? encrypt($clave_webservice) : '';
// Verificar si ya existe configuración - CORREGIR ERROR SQL
$sql_check = "SELECT COUNT(*) as total FROM configuracion_ventanilla_unica WHERE id_usuario = ?";
$stmt_check = sqlsrv_query($conn, $sql_check, [$id_usuario]);
if ($stmt_check === false) {
$_SESSION['config_error'] = 'Error en la consulta de configuración: ' . print_r(sqlsrv_errors(), true);
header('Location: /IMPORTADORES/seguridad/ventanillaUnica');
exit;
}
$row = sqlsrv_fetch_array($stmt_check, SQLSRV_FETCH_ASSOC);
if ($row['total'] > 0) {
// Actualizar configuración existente (sin ruta_ejecutable)
$sql = "UPDATE configuracion_ventanilla_unica SET
ruta_archivo_key = ?,
ruta_archivo_cer = ?,
clave_fiel = ?,
rfc_usuario_vu = ?,
clave_webservice = ?,
fecha_actualizacion = GETDATE()
WHERE id_usuario = ?";
$params = [
$ruta_archivo_key,
$ruta_archivo_cer,
$clave_fiel_encrypted,
$rfc_usuario_vu,
$clave_webservice_encrypted,
$id_usuario
];
} else {
// Insertar nueva configuración (sin ruta_ejecutable)
$sql = "INSERT INTO configuracion_ventanilla_unica
(id_usuario, ruta_archivo_key, ruta_archivo_cer,
clave_fiel, rfc_usuario_vu, clave_webservice, fecha_creacion)
VALUES (?, ?, ?, ?, ?, ?, GETDATE())";
$params = [
$id_usuario,
$ruta_archivo_key,
$ruta_archivo_cer,
$clave_fiel_encrypted,
$rfc_usuario_vu,
$clave_webservice_encrypted
];
}
$stmt = sqlsrv_prepare($conn, $sql, $params);
if (!$stmt) {
$_SESSION['config_error'] = "Error en la preparación: " . print_r(sqlsrv_errors(), true);
header('Location: /IMPORTADORES/seguridad/ventanillaUnica');
exit;
}
$result = sqlsrv_execute($stmt);
if ($result === false) {
$_SESSION['config_error'] = "Error al guardar configuración: " . print_r(sqlsrv_errors(), true);
header('Location: /IMPORTADORES/seguridad/ventanillaUnica');
exit;
}
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);
$_SESSION['config_success'] = 'Configuración de Ventanilla Única guardada correctamente.';
header('Location: /IMPORTADORES/seguridad/ventanillaUnica');
exit;
}
function probarConexionVU()
{
header('Content-Type: application/json');
$id_usuario = $_SESSION['usuario_id'] ?? null;
if (!$id_usuario || ($_SESSION['pendiente_confirmacion'] ?? false)) {
echo json_encode(['success' => false, 'message' => 'Usuario no autenticado']);
exit;
}
$conn = getConnection();
$configuracion = obtenerConfiguracionVU($conn, $id_usuario);
// Verificar que todos los campos requeridos estén configurados (sin ruta_ejecutable)
if (empty($configuracion['rfc_usuario_vu']) || empty($configuracion['clave_fiel'])) {
echo json_encode([
'success' => false,
'message' => 'Configuración incompleta. Verifica que RFC Usuario VU y Clave FIEL estén configurados.'
]);
exit;
}
// Verificar archivos de certificados
if (!empty($configuracion['ruta_archivo_cer']) && !file_exists($configuracion['ruta_archivo_cer'])) {
echo json_encode([
'success' => false,
'message' => 'El archivo CER no existe en la ruta especificada.'
]);
exit;
}
if (!empty($configuracion['ruta_archivo_key']) && !file_exists($configuracion['ruta_archivo_key'])) {
echo json_encode([
'success' => false,
'message' => 'El archivo KEY no existe en la ruta especificada.'
]);
exit;
}
// Verificar que existan ambos archivos de certificados
if (empty($configuracion['ruta_archivo_cer']) || empty($configuracion['ruta_archivo_key'])) {
echo json_encode([
'success' => false,
'message' => 'Los archivos CER y KEY son obligatorios para la configuración.'
]);
exit;
}
// Si llegamos aquí, la configuración es válida
echo json_encode([
'success' => true,
'message' => 'Configuración válida. Los archivos de certificados existen y todos los campos obligatorios están completos.'
]);
exit;
}
function obtenerConfiguracionVU($conn, $id_usuario)
{
$configuracion = [
'ruta_archivo_key' => '',
'ruta_archivo_cer' => '',
'clave_fiel' => '',
'rfc_usuario_vu' => '',
'clave_webservice' => '',
'fecha_creacion' => null,
'fecha_actualizacion' => null
];
$sql = "SELECT * FROM configuracion_ventanilla_unica WHERE id_usuario = ?";
$stmt = sqlsrv_prepare($conn, $sql, [$id_usuario]);
if ($stmt && sqlsrv_execute($stmt)) {
if ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$configuracion['ruta_archivo_key'] = $row['ruta_archivo_key'] ?? '';
$configuracion['ruta_archivo_cer'] = $row['ruta_archivo_cer'] ?? '';
$configuracion['rfc_usuario_vu'] = $row['rfc_usuario_vu'] ?? '';
// Desencriptar contraseñas
$configuracion['clave_fiel'] = !empty($row['clave_fiel']) ? decrypt($row['clave_fiel']) : '';
$configuracion['clave_webservice'] = !empty($row['clave_webservice']) ? decrypt($row['clave_webservice']) : '';
$configuracion['fecha_creacion'] = $row['fecha_creacion'];
$configuracion['fecha_actualizacion'] = $row['fecha_actualizacion'];
}
}
return $configuracion;
}

View File

@@ -410,6 +410,7 @@ function guardar()
$aduana_seccion = $_POST['anexo22_apendice'] ?? null;
$num_factura = trim($_POST['numero_factura'] ?? '');
$fecha = $_POST['fecha_factura'] ?? null;
$pedimento = trim($_POST['pedimento'] ?? ''); // ✅ NUEVO CAMPO
$incoterm = $_POST['incoterm'] ?? null;
$pais_proveedor = $_POST['pais_proveedor'] ?? null;
$tipo_moneda = $_POST['tipo_moneda'] ?? null;
@@ -462,15 +463,16 @@ function guardar()
$fotoUrl,
$status,
$proveedor_clave,
$patente_id ? (int)$patente_id : null
$patente_id ? (int)$patente_id : null,
$pedimento ?: null // ✅ CORREGIDO: Campo pedimento_vinculado al final
];
$sql = "INSERT INTO dbo.solicitud_importacion_factura
(id_importador, id_agencia, aduana, anexo22_apendice, numero_factura,
fecha_factura, numero_pedimento, incoterm, pais_proveedor, tipo_moneda,
fecha_factura, incoterm, pais_proveedor, tipo_moneda,
valor_factura, vinculacion, transportista_id, chofer_id,
foto_solicitud_url, status, proveedor_clave, patente_id)
foto_solicitud_url, status, proveedor_clave, patente_id, pedimento_vinculado)
OUTPUT INSERTED.id_solicitud
VALUES(?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
";
$stmt = sqlsrv_query($conn, $sql, $params, ['Scrollable' => SQLSRV_CURSOR_KEYSET]);
@@ -947,8 +949,8 @@ function actualizar()
} else {
// INSERTAR nueva partida (asegurarse que no tenga id_partida o sea 0)
$sql = "INSERT INTO dbo.solicitud_importacion_partidas
(id_solicitud, descripcion, cantidad_comercial, cantidad_tarifa,
valor_factura, peso_bruto, unidad_comercial_id, tasa_preferencial)
(id_solicitud, descripcion, cantidad_comercial, cantidad_tarifa, valor_factura,
peso_bruto, unidad_comercial_id, tasa_preferencial)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
";
$params = [ $id_solicitud, $desc, $cantCom, $cantTar, $valPart, $peso, $umId, $tasaPref ];
@@ -1968,7 +1970,7 @@ function generarHTMLPDF($solicitud, $partidas, $configuracion, $proveedor_info =
$unidades = ['', 'uno', 'dos', 'tres', 'cuatro', 'cinco', 'seis', 'siete', 'ocho', 'nueve'];
$decenas = ['', '', 'veinte', 'treinta', 'cuarenta', 'cincuenta', 'sesenta', 'setenta', 'ochenta', 'noventa'];
$especiales = ['diez', 'once', 'doce', 'trece', 'catorce', 'quince', 'dieciséis', 'diecisiete', 'dieciocho', 'diecinueve'];
$centenas = ['', 'ciento', 'doscientos', 'trescientos', 'cuatrocientos', 'quinientos', 'seiscientos', 'setecientos', 'ochocientos', 'novecientos'];
$centenas = ['', 'ciento', 'doscientos', 'trescientos', 'cuatrocientos', 'quinientos', 'seiscientos', 'setecientos', 'ochocientos'];
if ($numero == 0) return 'cero';
if ($numero == 100) return 'cien';
@@ -2212,4 +2214,89 @@ function generarHTMLPDF($solicitud, $partidas, $configuracion, $proveedor_info =
';
return $html;
}
// NUEVO ENDPOINT: Pedimentos de catálogo activos del importador para panel de referencia
function ajax_pedimentos_catalogo()
{
header('Content-Type: application/json; charset=utf-8');
if (!($_SESSION['usuario_id'] ?? false)) {
http_response_code(401);
echo json_encode(['data' => []]);
exit;
}
$id_usuario = $_SESSION['usuario_id'];
$limit = isset($_GET['limit']) ? intval($_GET['limit']) : 10;
$conn = getConnection();
// Obtener RFC del importador
$sqlImportador = "SELECT rfc FROM informacion_general WHERE id_usuario = ?";
$stmtImportador = sqlsrv_query($conn, $sqlImportador, [$id_usuario]);
if ($stmtImportador === false) {
echo json_encode(['data' => []]);
exit;
}
$importador = sqlsrv_fetch_array($stmtImportador, SQLSRV_FETCH_ASSOC);
if (!$importador) {
echo json_encode(['data' => []]);
exit;
}
// Obtener pedimentos activos del catálogo
$sql = "SELECT TOP {$limit} IdPrevio, Pedimento, ClienteNombre, ClavePed, Timestamp
FROM PREVIOS_COMPARTIDOS_WS
WHERE ClienteRFC = ? AND Status = 1
ORDER BY Timestamp DESC";
$stmt = sqlsrv_query($conn, $sql, [$importador['rfc']]);
$pedimentos = [];
if ($stmt !== false) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$fecha = '';
if ($row['Timestamp'] instanceof DateTime) {
$fecha = $row['Timestamp']->format('d/m/Y');
}
$pedimentos[] = [
'numero' => $row['Pedimento'],
'cliente' => $row['ClienteNombre'],
'clave' => $row['ClavePed'],
'fecha' => $fecha
];
}
}
echo json_encode(['data' => $pedimentos]);
exit;
}
function ajax_facturas_por_pedimento() {
header('Content-Type: application/json');
$id_previo = isset($_GET['id_pedimento']) ? trim($_GET['id_pedimento']) : '';
if (!$id_previo) {
echo json_encode(['success' => false, 'error' => 'ID de pedimento no válido']);
return;
}
$conn = getConnection();
// 1. Buscar el número de pedimento real en PREVIOS_COMPARTIDOS_WS
$stmt = sqlsrv_query($conn, "SELECT Pedimento FROM PREVIOS_COMPARTIDOS_WS WHERE IdPrevio = ?", [$id_previo]);
if ($stmt === false || !($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC))) {
echo json_encode(['success' => false, 'error' => 'No se encontró el pedimento en PREVIOS_COMPARTIDOS_WS']);
return;
}
$numero_pedimento = $row['Pedimento'];
// 2. Buscar las facturas en solicitud_importacion_factura usando el número de pedimento
// ✅ CORREGIDO: Incluir id_solicitud como id_factura
$stmt2 = sqlsrv_query($conn, "SELECT id_solicitud, numero_factura, fecha_factura, valor_factura FROM solicitud_importacion_factura WHERE numero_pedimento = ?", [$numero_pedimento]);
if ($stmt2 === false) {
echo json_encode(['success' => false, 'error' => 'Error en la consulta de facturas']);
return;
}
$facturas = [];
while ($row2 = sqlsrv_fetch_array($stmt2, SQLSRV_FETCH_ASSOC)) {
$facturas[] = [
'id_factura' => $row2['id_solicitud'], // ✅ AGREGADO: Usar id_solicitud como id_factura
'numero_factura' => $row2['numero_factura'],
'fecha' => ($row2['fecha_factura'] instanceof DateTime) ? $row2['fecha_factura']->format('Y-m-d') : $row2['fecha_factura'],
'monto' => $row2['valor_factura']
];
}
echo json_encode(['success' => true, 'facturas' => $facturas]);
}

View File

@@ -0,0 +1,913 @@
<?php
require_once __DIR__ . '/../helpers/session.php';
require_once __DIR__ . '/../../config/database.php';
function index()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
include __DIR__ . '/../../views/templates_rapidos/index.php';
}
function lista()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
include __DIR__ . '/../../views/templates_rapidos/lista.php';
}
function crear()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
$conn = getConnection();
// Obtener datos para los selects
$aduanas = obtenerAduanas($conn);
$patentes = obtenerPatentes($conn);
$incoterms = obtenerIncoterms($conn);
$paises = obtenerPaises($conn);
$transportistas = obtenerTransportistas($conn);
$choferes = obtenerChoferes($conn);
$unidades_medida = obtenerUnidadesMedida($conn);
include __DIR__ . '/../../views/templates_rapidos/crear.php';
}
function guardar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado.");
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
// Obtener datos del formulario
$nombre = trim($_POST['nombre'] ?? '');
$descripcion = trim($_POST['descripcion'] ?? '');
$icono = trim($_POST['icono'] ?? '🏢');
// Configuración del template
$config = [
'tipo_moneda' => $_POST['tipo_moneda'] ?? '',
'incoterm' => $_POST['incoterm'] ?? '',
'vinculacion' => $_POST['vinculacion'] ?? '',
'pais_proveedor' => $_POST['pais_proveedor'] ?? '',
'pais_proveedor_texto' => $_POST['pais_proveedor_texto'] ?? '',
'anexo22_apendice' => $_POST['anexo22_apendice'] ?? '',
'patente' => $_POST['patente'] ?? '',
'transportista_id' => $_POST['transportista_id'] ?? '',
'chofer_id' => $_POST['chofer_id'] ?? '',
'tasa_preferencial' => $_POST['tasa_preferencial'] ?? '',
'unidad_comercial_id' => $_POST['unidad_comercial_id'] ?? ''
];
$config_json = json_encode($config, JSON_UNESCAPED_UNICODE);
// Validaciones
if (empty($nombre)) {
die("❌ El nombre del template es obligatorio.");
}
if (strlen($nombre) > 100) {
die("❌ El nombre del template es muy largo (máximo 100 caracteres).");
}
$sql = "INSERT INTO dbo.templates_rapidos
(nombre, descripcion, icono, config_json, tipo_moneda, incoterm,
vinculacion, pais_proveedor, tasa_preferencial, id_agencia, id_usuario_creador)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$params = [
$nombre,
$descripcion,
$icono,
$config_json,
$config['tipo_moneda'],
$config['incoterm'],
$config['vinculacion'] ?: null,
$config['pais_proveedor'],
$config['tasa_preferencial'],
$id_agencia,
$id_usuario
];
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
die("❌ Error al guardar template: " . print_r(sqlsrv_errors(), true));
}
header('Location: /IMPORTADORES/templates_rapidos/lista?created=ok');
exit;
}
function editar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
$id = $_GET['id'] ?? null;
if (!$id || !is_numeric($id)) {
die("❌ ID inválido.");
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
// Obtener el template
$sql = "SELECT * FROM dbo.templates_rapidos
WHERE id = ? AND (id_usuario_creador = ? OR id_agencia = ? OR id_agencia IS NULL)";
$stmt = sqlsrv_query($conn, $sql, [$id, $id_usuario, $id_agencia]);
if ($stmt === false) {
die("❌ Error en consulta: " . print_r(sqlsrv_errors(), true));
}
$template = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (!$template) {
die("❌ Template no encontrado o sin permisos.");
}
// Decodificar configuración JSON
$template['config'] = json_decode($template['config_json'], true) ?: [];
// Obtener datos para los selects
$conn = getConnection();
$aduanas = obtenerAduanas($conn);
$patentes = obtenerPatentes($conn);
$incoterms = obtenerIncoterms($conn);
$paises = obtenerPaises($conn);
$transportistas = obtenerTransportistas($conn);
$choferes = obtenerChoferes($conn);
$unidades_medida = obtenerUnidadesMedida($conn);
include __DIR__ . '/../../views/templates_rapidos/editar.php';
}
function actualizar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado.");
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
$id = $_POST['id'] ?? null;
$nombre = trim($_POST['nombre'] ?? '');
$descripcion = trim($_POST['descripcion'] ?? '');
$icono = trim($_POST['icono'] ?? '🏢');
if (!$id || !is_numeric($id)) {
die("❌ ID inválido.");
}
// Configuración del template
$config = [
'tipo_moneda' => $_POST['tipo_moneda'] ?? '',
'incoterm' => $_POST['incoterm'] ?? '',
'vinculacion' => $_POST['vinculacion'] ?? '',
'pais_proveedor' => $_POST['pais_proveedor'] ?? '',
'pais_proveedor_texto' => $_POST['pais_proveedor_texto'] ?? '',
'anexo22_apendice' => $_POST['anexo22_apendice'] ?? '',
'patente' => $_POST['patente'] ?? '',
'transportista_id' => $_POST['transportista_id'] ?? '',
'chofer_id' => $_POST['chofer_id'] ?? '',
'tasa_preferencial' => $_POST['tasa_preferencial'] ?? '',
'unidad_comercial_id' => $_POST['unidad_comercial_id'] ?? ''
];
$config_json = json_encode($config, JSON_UNESCAPED_UNICODE);
// Validaciones
if (empty($nombre)) {
die("❌ El nombre del template es obligatorio.");
}
// Verificar permisos
$sqlCheck = "SELECT id FROM dbo.templates_rapidos
WHERE id = ? AND (id_usuario_creador = ? OR id_agencia = ?)";
$stmtCheck = sqlsrv_query($conn, $sqlCheck, [$id, $id_usuario, $id_agencia]);
$exists = sqlsrv_fetch_array($stmtCheck, SQLSRV_FETCH_ASSOC);
if (!$exists) {
die("❌ Template no encontrado o sin permisos para editarlo.");
}
$sql = "UPDATE dbo.templates_rapidos SET
nombre = ?, descripcion = ?, icono = ?, config_json = ?,
tipo_moneda = ?, incoterm = ?, vinculacion = ?,
pais_proveedor = ?, tasa_preferencial = ?, fecha_modificacion = GETDATE()
WHERE id = ?";
$params = [
$nombre,
$descripcion,
$icono,
$config_json,
$config['tipo_moneda'],
$config['incoterm'],
$config['vinculacion'] ?: null,
$config['pais_proveedor'],
$config['tasa_preferencial'],
$id
];
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
die("❌ Error al actualizar template: " . print_r(sqlsrv_errors(), true));
}
header('Location: /IMPORTADORES/templates_rapidos/lista?updated=ok');
exit;
}
function eliminar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
header('Location: /IMPORTADORES/login');
exit;
}
$id = $_GET['id'] ?? null;
if (!$id || !is_numeric($id)) {
die("❌ ID inválido.");
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
// Verificar permisos
$sqlCheck = "SELECT id FROM dbo.templates_rapidos
WHERE id = ? AND (id_usuario_creador = ? OR id_agencia = ?)";
$stmtCheck = sqlsrv_query($conn, $sqlCheck, [$id, $id_usuario, $id_agencia]);
$exists = sqlsrv_fetch_array($stmtCheck, SQLSRV_FETCH_ASSOC);
if (!$exists) {
die("❌ Template no encontrado o sin permisos para eliminarlo.");
}
$sql = "UPDATE dbo.templates_rapidos SET activo = 0 WHERE id = ?";
$stmt = sqlsrv_query($conn, $sql, [$id]);
if ($stmt === false) {
die("❌ Error al eliminar template: " . print_r(sqlsrv_errors(), true));
}
header('Location: /IMPORTADORES/templates_rapidos/lista?deleted=ok');
exit;
}
function ajax_lista()
{
if (!($_SESSION['usuario_id'] ?? false)) {
http_response_code(403);
echo json_encode([]);
exit;
}
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
$conn = getConnection();
// Parámetros de DataTables
$draw = intval($_GET['draw'] ?? 0);
$start = intval($_GET['start'] ?? 0);
$length = intval($_GET['length'] ?? 10);
$search = $_GET['search']['value'] ?? '';
// Construir condiciones de filtro
$where = "activo = 1 AND (id_agencia IS NULL OR id_agencia = ? OR id_usuario_creador = ?)";
$params = [$id_agencia, $id_usuario];
if ($search !== '') {
$where .= " AND (nombre LIKE ? OR descripcion LIKE ?)";
$like = "%{$search}%";
$params = array_merge($params, [$like, $like]);
}
// Total registros filtrados
$sqlFiltered = "SELECT COUNT(*) AS total FROM dbo.templates_rapidos WHERE $where";
$stmtF = sqlsrv_query($conn, $sqlFiltered, $params);
$rowF = sqlsrv_fetch_array($stmtF, SQLSRV_FETCH_ASSOC);
$recordsFiltered = (int)($rowF['total'] ?? 0);
// Total registros sin filtro
$sqlTotal = "SELECT COUNT(*) AS total FROM dbo.templates_rapidos WHERE activo = 1 AND (id_agencia IS NULL OR id_agencia = ? OR id_usuario_creador = ?)";
$stmtT = sqlsrv_query($conn, $sqlTotal, [$id_agencia, $id_usuario]);
$rowT = sqlsrv_fetch_array($stmtT, SQLSRV_FETCH_ASSOC);
$recordsTotal = (int)($rowT['total'] ?? 0);
// Consulta principal con paginación
$sql = "SELECT t.id, t.nombre, t.descripcion, t.icono, t.tipo_moneda, t.incoterm,
t.vinculacion, t.pais_proveedor, t.tasa_preferencial, t.fecha_creacion,
u.nombre_usuario AS usuario_creador,
CASE WHEN t.id_agencia IS NULL THEN 'Sistema' ELSE a.nombre END AS ambito
FROM dbo.templates_rapidos t
LEFT JOIN dbo.usuarios u ON t.id_usuario_creador = u.id
LEFT JOIN dbo.agencias a ON t.id_agencia = a.id
WHERE $where
ORDER BY t.fecha_creacion DESC
OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
$paramsData = array_merge($params, [$start, $length]);
$stmt = sqlsrv_query($conn, $sql, $paramsData);
$data = [];
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$fecha = $row['fecha_creacion'] instanceof DateTime
? $row['fecha_creacion']->format('d/m/Y H:i')
: 'N/A';
$data[] = [
'id' => $row['id'],
'icono' => htmlspecialchars($row['icono'] ?? '🏢'),
'nombre' => htmlspecialchars($row['nombre']),
'descripcion' => htmlspecialchars($row['descripcion'] ?? ''),
'tipo_moneda' => htmlspecialchars($row['tipo_moneda'] ?? ''),
'incoterm' => htmlspecialchars($row['incoterm'] ?? ''),
'pais_proveedor' => htmlspecialchars($row['pais_proveedor'] ?? ''),
'ambito' => htmlspecialchars($row['ambito'] ?? ''),
'usuario_creador' => htmlspecialchars($row['usuario_creador'] ?? ''),
'fecha_creacion' => $fecha
];
}
echo json_encode([
'draw' => $draw,
'recordsTotal' => $recordsTotal,
'recordsFiltered' => $recordsFiltered,
'data' => $data
]);
}
function ajax_obtener_templates_debug()
{
header('Content-Type: application/json; charset=UTF-8');
if (!($_SESSION['usuario_id'] ?? false)) {
echo json_encode(['error' => 'Usuario no autenticado']);
exit;
}
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
try {
$conn = getConnection();
// ✅ CONSULTA SIN FILTROS para debug
$sql = "SELECT id, nombre, descripcion, icono, config_json,
ISNULL(veces_usado, 0) as veces_usado,
id_usuario_creador, id_agencia, activo,
fecha_creacion
FROM dbo.templates_rapidos
ORDER BY fecha_creacion DESC";
$stmt = sqlsrv_query($conn, $sql);
if ($stmt === false) {
$errors = sqlsrv_errors();
echo json_encode([
'error' => 'Error en consulta SQL',
'message' => $errors[0]['message'] ?? 'Error desconocido',
'sql_errors' => $errors
]);
exit;
}
$templates = [];
$debug_info = [
'usuario_actual' => $id_usuario,
'agencia_actual' => $id_agencia,
'todos_los_templates' => []
];
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
// Info completa para debug
$template_debug = [
'id' => $row['id'],
'nombre' => $row['nombre'],
'id_usuario_creador' => $row['id_usuario_creador'],
'id_agencia' => $row['id_agencia'],
'activo' => $row['activo'],
'fecha_creacion' => $row['fecha_creacion'] instanceof DateTime
? $row['fecha_creacion']->format('Y-m-d H:i:s')
: $row['fecha_creacion'],
'es_del_usuario_actual' => ($row['id_usuario_creador'] == $id_usuario),
'es_de_la_agencia' => ($row['id_agencia'] == $id_agencia),
'deberia_mostrarse' => (
$row['activo'] == 1 && (
$row['id_agencia'] === null ||
$row['id_agencia'] == $id_agencia ||
$row['id_usuario_creador'] == $id_usuario
)
)
];
$debug_info['todos_los_templates'][] = $template_debug;
// Solo agregar a templates para mostrar si cumple condiciones
if ($template_debug['deberia_mostrarse']) {
$config = [];
if (!empty($row['config_json'])) {
$decoded = json_decode($row['config_json'], true);
$config = is_array($decoded) ? $decoded : [];
}
$templates[] = [
'id' => (int)$row['id'],
'nombre' => $row['nombre'],
'descripcion' => $row['descripcion'] ?? '',
'icono' => $row['icono'] ?? '📋',
'config' => $config,
'veces_usado' => (int)$row['veces_usado'],
'id_usuario_creador' => $row['id_usuario_creador'],
'es_mio' => ($row['id_usuario_creador'] == $id_usuario)
];
}
}
echo json_encode([
'success' => true,
'count' => count($templates),
'templates' => $templates,
'debug_info' => $debug_info
], JSON_UNESCAPED_UNICODE);
} catch (Exception $e) {
echo json_encode([
'error' => 'Error interno del servidor',
'message' => $e->getMessage()
]);
}
exit;
}
function ajax_obtener_templates()
{
// ✅ VERSIÓN CORREGIDA: Función simplificada sin filtros complejos
header('Content-Type: application/json; charset=UTF-8');
if (!($_SESSION['usuario_id'] ?? false)) {
http_response_code(403);
echo json_encode(['error' => 'Usuario no autenticado', 'templates' => []]);
exit;
}
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
try {
$conn = getConnection();
// ✅ CONSULTA SIMPLIFICADA: Mostrar todos los templates activos del usuario o agencia
$sql = "SELECT id, nombre, descripcion, icono, config_json,
ISNULL(veces_usado, 0) as veces_usado,
id_usuario_creador, id_agencia
FROM dbo.templates_rapidos
WHERE activo = 1
AND (id_usuario_creador = ? OR id_agencia = ? OR id_agencia IS NULL)
ORDER BY
CASE WHEN id_usuario_creador = ? THEN 0 ELSE 1 END,
veces_usado DESC,
nombre ASC";
$params = [$id_usuario, $id_agencia, $id_usuario];
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
$errors = sqlsrv_errors();
echo json_encode([
'error' => 'Error en consulta SQL',
'message' => $errors[0]['message'] ?? 'Error desconocido',
'templates' => []
]);
exit;
}
$templates = [];
$templates_personales = [];
$templates_otros = [];
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
// Decodificar JSON con manejo de errores
$config = [];
if (!empty($row['config_json'])) {
$decoded = json_decode($row['config_json'], true);
$config = is_array($decoded) ? $decoded : [];
}
$template = [
'id' => (int)$row['id'],
'nombre' => $row['nombre'],
'descripcion' => $row['descripcion'] ?? '',
'icono' => $row['icono'] ?? '📋',
'config' => $config,
'veces_usado' => (int)$row['veces_usado'],
'id_usuario_creador' => $row['id_usuario_creador'],
'id_agencia' => $row['id_agencia'],
'es_mio' => ($row['id_usuario_creador'] == $id_usuario),
'ambito' => ($row['id_usuario_creador'] == $id_usuario) ? 'personal' :
(($row['id_agencia'] == $id_agencia) ? 'agencia' : 'sistema')
];
// Separar templates personales de otros
if ($template['es_mio']) {
$templates_personales[] = $template;
} else {
$templates_otros[] = $template;
}
$templates[] = $template;
}
// Respuesta con información detallada
echo json_encode([
'success' => true,
'count' => count($templates),
'count_personales' => count($templates_personales),
'count_otros' => count($templates_otros),
'usuario_id' => $id_usuario,
'agencia_id' => $id_agencia,
'templates' => $templates,
'templates_personales' => $templates_personales,
'templates_otros' => $templates_otros
], JSON_UNESCAPED_UNICODE);
} catch (Exception $e) {
echo json_encode([
'error' => 'Error interno del servidor',
'message' => $e->getMessage(),
'templates' => []
]);
}
exit;
}
function ajax_lista_por_seccion()
{
if (!($_SESSION['usuario_id'] ?? false)) {
die(json_encode(['error' => 'No autorizado']));
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
$seccion = $_GET['seccion'] ?? 'personal';
$data = [];
try {
switch($seccion) {
case 'personal':
// Solo templates creados por el usuario actual
$sql = "SELECT id, nombre, descripcion, icono, config_json,
veces_usado, fecha_creacion, id_usuario_creador
FROM dbo.templates_rapidos
WHERE id_usuario_creador = ? AND estado = 1
ORDER BY veces_usado DESC, fecha_creacion DESC";
$params = [$id_usuario];
break;
case 'agencia':
// Templates de la agencia (excluyendo los personales ya mostrados)
$sql = "SELECT id, nombre, descripcion, icono, config_json,
veces_usado, fecha_creacion, id_usuario_creador
FROM dbo.templates_rapidos
WHERE id_agencia = ? AND id_usuario_creador != ? AND estado = 1
ORDER BY veces_usado DESC, fecha_creacion DESC";
$params = [$id_agencia, $id_usuario];
break;
case 'global':
// Templates globales del sistema (solo si se solicitan explícitamente)
$sql = "SELECT id, nombre, descripcion, icono, config_json,
veces_usado, fecha_creacion, id_usuario_creador
FROM dbo.templates_rapidos
WHERE id_agencia IS NULL AND id_usuario_creador IS NULL AND estado = 1
ORDER BY veces_usado DESC, fecha_creacion DESC";
$params = [];
break;
default:
throw new Exception('Sección inválida');
}
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
throw new Exception('Error en consulta: ' . print_r(sqlsrv_errors(), true));
}
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
// Formatear fecha
$fecha = $row['fecha_creacion'] instanceof DateTime
? $row['fecha_creacion']->format('d/m/Y')
: date('d/m/Y', strtotime($row['fecha_creacion']));
// Determinar acciones según el tipo de template
$acciones = '';
$esPropio = ($row['id_usuario_creador'] == $id_usuario);
$esAgencia = ($seccion === 'agencia');
$esGlobal = ($seccion === 'global');
if ($esPropio) {
$acciones = '
<div class="btn-group" role="group">
<a href="/IMPORTADORES/templates_rapidos/editar?id=' . $row['id'] . '"
class="btn btn-sm btn-outline-primary" title="Editar">
<i class="fas fa-edit"></i>
</a>
<button onclick="duplicarTemplate(' . $row['id'] . ')"
class="btn btn-sm btn-outline-info" title="Duplicar">
<i class="fas fa-copy"></i>
</button>
<button onclick="eliminarTemplate(' . $row['id'] . ')"
class="btn btn-sm btn-outline-danger" title="Eliminar">
<i class="fas fa-trash"></i>
</button>
</div>';
} elseif ($esAgencia) {
$acciones = '
<div class="btn-group" role="group">
<button onclick="mostrarVistaPrevia(' . $row['id'] . ')"
class="btn btn-sm btn-outline-info" title="Ver">
<i class="fas fa-eye"></i>
</button>
<button onclick="duplicarTemplate(' . $row['id'] . ')"
class="btn btn-sm btn-outline-success" title="Duplicar">
<i class="fas fa-copy"></i>
</button>
</div>';
} else { // Global
$acciones = '
<button onclick="mostrarVistaPrevia(' . $row['id'] . ')"
class="btn btn-sm btn-outline-info" title="Ver detalles">
<i class="fas fa-eye"></i>
</button>';
}
// Construir nombre con icono
$nombreConIcono = '<span class="d-flex align-items-center">
<span class="me-2" style="font-size: 18px;">' . htmlspecialchars($row['icono']) . '</span>
<div>
<strong>' . htmlspecialchars($row['nombre']) . '</strong>';
// Agregar badge según el tipo
if ($esPropio) {
$nombreConIcono .= ' <span class="badge bg-primary scope-badge ms-2">Mío</span>';
} elseif ($esAgencia) {
$nombreConIcono .= ' <span class="badge bg-info scope-badge ms-2">Agencia</span>';
} else {
$nombreConIcono .= ' <span class="badge bg-secondary scope-badge ms-2">Global</span>';
}
$nombreConIcono .= '</div></span>';
$data[] = [
$row['id'],
$nombreConIcono,
htmlspecialchars($row['descripcion'] ?? 'Sin descripción'),
'<span class="badge bg-success">' . ($row['veces_usado'] ?? 0) . '</span>',
$fecha,
$acciones
];
}
echo json_encode([
'success' => true,
'data' => $data,
'count' => count($data)
]);
} catch (Exception $e) {
echo json_encode([
'success' => false,
'error' => $e->getMessage(),
'data' => []
]);
}
}
function duplicar()
{
if (!($_SESSION['usuario_id'] ?? false)) {
die("⚠️ No autorizado.");
}
$conn = getConnection();
$id_usuario = $_SESSION['usuario_id'];
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
$template_id = $_POST['template_id'] ?? null;
if (!$template_id || !is_numeric($template_id)) {
die("❌ ID de template inválido.");
}
// Obtener template original
$sql = "SELECT * FROM dbo.templates_rapidos WHERE id = ?";
$stmt = sqlsrv_query($conn, $sql, [$template_id]);
if ($stmt === false) {
die("❌ Error al buscar template: " . print_r(sqlsrv_errors(), true));
}
$original = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (!$original) {
die("❌ Template no encontrado.");
}
// Crear duplicado con nuevo nombre
$nuevo_nombre = $original['nombre'] . ' (Copia)';
$sql_insert = "INSERT INTO dbo.templates_rapidos
(nombre, descripcion, icono, config_json, tipo_moneda, incoterm,
vinculacion, pais_proveedor, tasa_preferencial, id_agencia, id_usuario_creador)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$params_insert = [
$nuevo_nombre,
$original['descripcion'],
$original['icono'],
$original['config_json'],
$original['tipo_moneda'],
$original['incoterm'],
$original['vinculacion'],
$original['pais_proveedor'],
$original['tasa_preferencial'],
$id_agencia,
$id_usuario
];
$stmt_insert = sqlsrv_query($conn, $sql_insert, $params_insert);
if ($stmt_insert === false) {
die("❌ Error al duplicar: " . print_r(sqlsrv_errors(), true));
}
echo "✅ Template duplicado correctamente como '{$nuevo_nombre}'.";
}
function ajax_usar_template()
{
if (!($_SESSION['usuario_id'] ?? false)) {
http_response_code(403);
echo json_encode(['success' => false, 'message' => 'No autorizado']);
exit;
}
$id_template = intval($_POST['id_template'] ?? 0);
$id_usuario = $_SESSION['usuario_id'];
if ($id_template <= 0) {
echo json_encode(['success' => false, 'message' => 'ID de template inválido']);
exit;
}
$conn = getConnection();
// Incrementar contador de uso
$sql = "UPDATE dbo.templates_rapidos
SET veces_usado = veces_usado + 1, ultima_vez_usado = GETDATE()
WHERE id = ? AND activo = 1";
$stmt = sqlsrv_query($conn, $sql, [$id_template]);
if ($stmt === false) {
echo json_encode(['success' => false, 'message' => 'Error al actualizar estadísticas']);
exit;
}
echo json_encode(['success' => true]);
exit;
}
// Funciones auxiliares
function obtenerAduanas($conn) {
$sql = "SELECT DISTINCT RIGHT(REPLICATE('0', 3) + CAST(aduana_seccion AS VARCHAR), 3) AS aduana_seccion, nombre FROM dbo.aduanas ORDER BY aduana_seccion";
$stmt = sqlsrv_query($conn, $sql);
$result = [];
if ($stmt !== false) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
return $result;
}
function obtenerPatentes($conn) {
$id_agencia = $_SESSION['id_agencia_en_uso'] ?? null;
if (!$id_agencia) {
return [];
}
$sql = "SELECT id_agente, patente, agente_aduanal FROM dbo.agentes_aduanales WHERE id_agencia = ? AND activo = 1 ORDER BY patente";
$stmt = sqlsrv_query($conn, $sql, [$id_agencia]);
$result = [];
if ($stmt !== false) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
return $result;
}
function obtenerIncoterms($conn) {
$sql = "SELECT INCOTERM, DESCESPANOL FROM dbo.gIncoterms ORDER BY INCOTERM";
$stmt = sqlsrv_query($conn, $sql);
$result = [];
if ($stmt !== false) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
return $result;
}
function obtenerPaises($conn) {
$sql = "SELECT id_pais, nombre FROM dbo.paises ORDER BY nombre";
$stmt = sqlsrv_query($conn, $sql);
$result = [];
if ($stmt !== false) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
return $result;
}
function obtenerTransportistas($conn) {
$id_usuario = $_SESSION['usuario_id'] ?? null;
if (!$id_usuario) {
return [];
}
$sql = "SELECT id_transportista, clave_identificador, nombre FROM dbo.transportistas WHERE id_usuario = ? AND activo = 1 ORDER BY nombre";
$stmt = sqlsrv_query($conn, $sql, [$id_usuario]);
$result = [];
if ($stmt !== false) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
return $result;
}
function obtenerChoferes($conn) {
$id_usuario = $_SESSION['usuario_id'] ?? null;
if (!$id_usuario) {
return [];
}
$sql = "SELECT c.id_chofer, c.nombre+' '+c.apellido AS nombre, c.transportista_id
FROM dbo.choferes c
JOIN dbo.transportistas t ON c.transportista_id = t.id_transportista
WHERE t.id_usuario = ? AND c.status = 1
ORDER BY c.nombre";
$stmt = sqlsrv_query($conn, $sql, [$id_usuario]);
$result = [];
if ($stmt !== false) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
return $result;
}
function obtenerUnidadesMedida($conn) {
$sql = "SELECT id, descripcion FROM dbo.unidades_medida_apendice7 ORDER BY id";
$stmt = sqlsrv_query($conn, $sql);
$result = [];
if ($stmt !== false) {
while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) {
$result[] = $row;
}
}
return $result;
}

237
app/controllers/winsaai.php Normal file
View File

@@ -0,0 +1,237 @@
<?php
require_once __DIR__ . '/../helpers/session.php';
require_once __DIR__ . '/../../config/database.php';
require_once __DIR__ . '/../helpers/crypto.php';
require_once __DIR__ . '/../helpers/env.php';
loadEnv();
function save_config() {
$conn = getConnection();
$userId = $_SESSION['usuario_id'] ?? null;
if (!$userId) {
http_response_code(401);
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'Sesión expirada']);
exit;
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'Método no permitido']);
exit;
}
$input = json_decode(file_get_contents('php://input'), true);
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400);
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'JSON inválido']);
exit;
}
$host = trim($input['host'] ?? '');
$port = intval($input['port'] ?? 80);
$protocol = $input['protocol'] ?? 'https';
$usuario = trim($input['usuario'] ?? '');
$password = $input['password'] ?? '';
$sync_pedimentos = $input['sync_pedimentos'] ?? true;
$sync_coves = $input['sync_coves'] ?? true;
// Validaciones
if (empty($host) || empty($usuario) || empty($password)) {
http_response_code(400);
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'Todos los campos son obligatorios']);
exit;
}
// Encriptar contraseña
$encryptedPassword = encrypt($password);
// Verificar si existe configuración
$sqlCheck = "SELECT id FROM winsaai_config WHERE id_usuario = ?";
$stmtCheck = sqlsrv_query($conn, $sqlCheck, [$userId]);
if ($stmtCheck === false) {
http_response_code(500);
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'Error en base de datos']);
exit;
}
$existingConfig = sqlsrv_fetch_array($stmtCheck, SQLSRV_FETCH_ASSOC);
sqlsrv_free_stmt($stmtCheck);
if ($existingConfig) {
// Actualizar
$sql = "UPDATE winsaai_config
SET host = ?, port = ?, protocol = ?, usuario = ?, password = ?,
sync_pedimentos = ?, sync_coves = ?, updated_at = GETDATE()
WHERE id_usuario = ?";
$params = [$host, $port, $protocol, $usuario, $encryptedPassword,
$sync_pedimentos ? 1 : 0, $sync_coves ? 1 : 0, $userId];
} else {
// Insertar
$sql = "INSERT INTO winsaai_config (id_usuario, host, port, protocol, usuario, password, sync_pedimentos, sync_coves)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
$params = [$userId, $host, $port, $protocol, $usuario, $encryptedPassword,
$sync_pedimentos ? 1 : 0, $sync_coves ? 1 : 0];
}
$stmt = sqlsrv_query($conn, $sql, $params);
if ($stmt === false) {
http_response_code(500);
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'Error al guardar configuración']);
exit;
}
sqlsrv_free_stmt($stmt);
header('Content-Type: application/json');
echo json_encode(['success' => true, 'message' => 'Configuración guardada correctamente']);
}
function get_config() {
$conn = getConnection();
$userId = $_SESSION['usuario_id'] ?? null;
if (!$userId) {
http_response_code(401);
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'Sesión expirada']);
exit;
}
$sql = "SELECT * FROM winsaai_config WHERE id_usuario = ?";
$stmt = sqlsrv_query($conn, $sql, [$userId]);
if ($stmt === false) {
http_response_code(500);
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'Error en base de datos']);
exit;
}
$config = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
sqlsrv_free_stmt($stmt);
if ($config) {
// No enviar contraseña por seguridad
unset($config['password']);
// Convertir BIT a boolean
$config['sync_pedimentos'] = (bool)$config['sync_pedimentos'];
$config['sync_coves'] = (bool)$config['sync_coves'];
header('Content-Type: application/json');
echo json_encode(['success' => true, 'data' => $config]);
} else {
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'No hay configuración']);
}
}
function test_connection() {
$conn = getConnection();
$userId = $_SESSION['usuario_id'] ?? null;
if (!$userId) {
http_response_code(401);
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'Sesión expirada']);
exit;
}
$input = json_decode(file_get_contents('php://input'), true);
$host = trim($input['host'] ?? '');
$port = intval($input['port'] ?? 80);
$protocol = $input['protocol'] ?? 'https';
$usuario = trim($input['usuario'] ?? '');
$password = $input['password'] ?? '';
if (empty($host) || empty($usuario) || empty($password)) {
http_response_code(400);
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'Faltan datos para probar conexión']);
exit;
}
$url = "{$protocol}://{$host}:{$port}/api/test";
// Simular prueba de conexión (aquí pondrías la lógica real)
header('Content-Type: application/json');
echo json_encode(['success' => true, 'message' => "Conexión exitosa con {$protocol}://{$host}:{$port}"]);
}
function sync_data() {
$conn = getConnection();
$userId = $_SESSION['usuario_id'] ?? null;
if (!$userId) {
http_response_code(401);
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'Sesión expirada']);
exit;
}
// Obtener configuración del usuario
$sql = "SELECT * FROM winsaai_config WHERE id_usuario = ?";
$stmt = sqlsrv_query($conn, $sql, [$userId]);
if ($stmt === false) {
http_response_code(500);
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'Error en base de datos']);
exit;
}
$config = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
sqlsrv_free_stmt($stmt);
if (!$config) {
http_response_code(400);
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'No hay configuración de WINSAAI']);
exit;
}
$input = json_decode(file_get_contents('php://input'), true);
$syncType = $input['sync_type'] ?? 'both';
// Simular sincronización
$results = [];
if ($syncType === 'pedimentos' || $syncType === 'both') {
$results['pedimentos'] = ['total' => 10, 'processed' => 10];
}
if ($syncType === 'coves' || $syncType === 'both') {
$results['coves'] = ['total' => 5, 'processed' => 5];
}
// Actualizar última sincronización
$sqlUpdate = "UPDATE winsaai_config SET last_sync = GETDATE() WHERE id_usuario = ?";
sqlsrv_query($conn, $sqlUpdate, [$userId]);
header('Content-Type: application/json');
echo json_encode(['success' => true, 'message' => 'Sincronización completada', 'data' => $results]);
}
function index() {
header('Content-Type: application/json');
echo json_encode([
'success' => true,
'message' => 'API WINSAAI disponible',
'endpoints' => [
'save_config' => '/IMPORTADORES/winsaai/save_config',
'test_connection' => '/IMPORTADORES/winsaai/test_connection',
'sync_data' => '/IMPORTADORES/winsaai/sync_data',
'get_config' => '/IMPORTADORES/winsaai/get_config'
]
]);
}
?>