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