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 .= "
• Registros insertados: $insertadas";
if ($omitidas > 0) {
$mensaje .= "
• Registros omitidos (duplicados): $omitidas";
}
if (!empty($errores)) {
$mensaje .= "
• Errores encontrados: " . count($errores);
$mensaje .= "
Detalle de errores:
" . implode("
", array_slice($errores, 0, 10));
if (count($errores) > 10) {
$mensaje .= "
... 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());
}
}