Files
MVE/views/catalogo_pedimentos/index.php

843 lines
30 KiB
PHP
Raw Permalink Blame History

This file contains invisible Unicode characters

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

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php include __DIR__ . '/../partials/sidebar_importador.php'; ?>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Catálogo de Pedimentos</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
:root {
--primary: #2563eb;
--primary-dark: #1d4ed8;
--secondary: #64748b;
--success: #059669;
--warning: #d97706;
--danger: #dc2626;
--info: #0891b2;
--light: #f8fafc;
--dark: #0f172a;
--border-color: #e2e8f0;
--text-muted: #64748b;
--bg-body: #f8fafc;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
background-color: var(--bg-body);
color: var(--dark);
line-height: 1.6;
}
.main-content {
margin-left: 280px;
padding: 2rem;
min-height: 100vh;
transition: margin-left 0.3s ease;
}
@media (max-width: 768px) {
.main-content {
margin-left: 0;
padding: 1rem;
}
}
.page-header {
margin-bottom: 2rem;
}
.page-title {
color: var(--dark);
font-weight: 600;
font-size: 1.75rem;
margin-bottom: 0.5rem;
}
.page-subtitle {
color: var(--text-muted);
font-weight: 400;
font-size: 0.95rem;
}
.feature-card {
background: white;
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 1.5rem;
height: 100%;
transition: all 0.2s ease;
cursor: pointer;
position: relative;
overflow: hidden;
}
.feature-card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
border-color: var(--primary);
}
.feature-icon {
width: 48px;
height: 48px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 1rem;
font-size: 1.25rem;
color: white;
}
.feature-icon.primary { background: var(--primary); }
.feature-icon.success { background: var(--success); }
.feature-icon.info { background: var(--info); }
.feature-title {
font-weight: 600;
font-size: 1.1rem;
color: var(--dark);
margin-bottom: 0.5rem;
}
.feature-description {
color: var(--text-muted);
font-size: 0.9rem;
margin-bottom: 1.5rem;
line-height: 1.5;
}
.btn-feature {
background: var(--primary);
color: white;
border: none;
padding: 0.625rem 1.25rem;
border-radius: 6px;
font-weight: 500;
font-size: 0.875rem;
transition: all 0.2s ease;
width: 100%;
text-decoration: none;
display: inline-block;
text-align: center;
}
.btn-feature:hover {
background: var(--primary-dark);
color: white;
transform: translateY(-1px);
text-decoration: none;
}
.btn-feature.success {
background: var(--success);
}
.btn-feature.success:hover {
background: #047857;
color: white;
}
.btn-feature.info {
background: var(--info);
}
.btn-feature.info:hover {
background: #0e7490;
color: white;
}
.info-card {
background: white;
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 1.5rem;
margin-top: 2rem;
}
.info-card-header {
display: flex;
align-items: center;
margin-bottom: 1rem;
padding-bottom: 0.75rem;
border-bottom: 1px solid var(--border-color);
}
.info-icon {
width: 32px;
height: 32px;
border-radius: 6px;
background: rgba(37, 99, 235, 0.1);
color: var(--primary);
display: flex;
align-items: center;
justify-content: center;
margin-right: 0.75rem;
}
.info-title {
font-weight: 600;
font-size: 1.1rem;
color: var(--dark);
margin: 0;
}
.info-text {
color: var(--text-muted);
font-size: 0.95rem;
margin-bottom: 1rem;
}
.feature-list {
list-style: none;
padding: 0;
}
.feature-list li {
display: flex;
align-items: center;
padding: 0.5rem 0;
color: var(--text-muted);
font-size: 0.9rem;
}
.feature-list li i {
color: var(--success);
margin-right: 0.75rem;
width: 16px;
}
.fade-in {
animation: fadeIn 0.5s ease-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body>
<div class="main-content">
<!-- Page Header -->
<div class="page-header">
<h1 class="page-title">Catálogo de Pedimentos</h1>
<p class="page-subtitle">Gestiona y administra todos los pedimentos de importación del sistema</p>
</div>
<!-- Features Grid -->
<div class="row g-4 mb-4">
<div class="col-lg-4 col-md-6">
<div class="feature-card fade-in" onclick="window.location.href='/IMPORTADORES/catalogo_pedimentos/lista'">
<div class="feature-icon primary">
<i class="fas fa-list"></i>
</div>
<h3 class="feature-title">Lista de Pedimentos</h3>
<p class="feature-description">Visualiza y gestiona todos los pedimentos registrados en el sistema con herramientas de búsqueda y filtrado avanzado.</p>
<a href="/IMPORTADORES/catalogo_pedimentos/lista" class="btn-feature">
Ver Lista
<i class="fas fa-arrow-right ms-2"></i>
</a>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="feature-card fade-in" onclick="window.location.href='/IMPORTADORES/catalogo_pedimentos/crear'">
<div class="feature-icon success">
<i class="fas fa-plus-circle"></i>
</div>
<h3 class="feature-title">Nuevo Pedimento</h3>
<p class="feature-description">Registra un nuevo pedimento con toda la información requerida y documentación necesaria para el proceso de importación.</p>
<a href="/IMPORTADORES/catalogo_pedimentos/crear" class="btn-feature success">
Crear Nuevo
<i class="fas fa-plus ms-2"></i>
</a>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="feature-card fade-in">
<div class="feature-icon info">
<i class="fas fa-upload"></i>
</div>
<h3 class="feature-title">Importar Archivo</h3>
<p class="feature-description">Carga masiva de pedimentos desde archivo de texto con formato específico del sistema aduanero.</p>
<button class="btn-feature info" onclick="importarPedimentos()">
Importar Datos
<i class="fas fa-file-import ms-2"></i>
</button>
<div class="mt-2">
<button class="btn btn-sm btn-outline-secondary" onclick="verificarPedimentosExistentes()" style="border-radius: 6px; font-size: 0.8rem;">
<i class="fas fa-search me-1"></i>Ver Existentes
</button>
<button class="btn btn-sm btn-outline-danger" onclick="limpiarBaseDatos()" style="border-radius: 6px; font-size: 0.8rem;">
<i class="fas fa-trash me-1"></i>Limpiar BD
</button>
</div>
</div>
</div>
<div class="col-lg-4 col-md-6">
<div class="feature-card fade-in">
<div class="feature-icon warning" style="background: var(--warning);">
<i class="fas fa-chart-bar"></i>
</div>
<h3 class="feature-title">Reportes</h3>
<p class="feature-description">Genera reportes detallados y estadísticas de pedimentos para análisis y seguimiento de operaciones.</p>
<button class="btn-feature" style="background: var(--warning);" onclick="proximamente()">
Ver Reportes
<i class="fas fa-chart-line ms-2"></i>
</button>
</div>
</div>
</div>
<!-- Information Card -->
<div class="info-card">
<div class="info-card-header">
<div class="info-icon">
<i class="fas fa-info-circle"></i>
</div>
<h3 class="info-title">Información del Módulo</h3>
</div>
<p class="info-text">
El catálogo de pedimentos te permite gestionar de manera eficiente todos los pedimentos
de importación. Desde aquí puedes realizar las siguientes acciones:
</p>
<ul class="feature-list">
<li>
<i class="fas fa-check"></i>
Registrar nuevos pedimentos con toda la información requerida
</li>
<li>
<i class="fas fa-check"></i>
Consultar y editar pedimentos existentes
</li>
<li>
<i class="fas fa-check"></i>
Realizar búsquedas avanzadas por diversos criterios
</li>
<li>
<i class="fas fa-check"></i>
Exportar información para reportes y análisis
</li>
<li>
<i class="fas fa-check"></i>
Mantener un histórico completo de operaciones
</li>
</ul>
</div>
</div>
<!-- Modal para Importar Archivo -->
<div class="modal fade" id="modalImportarPedimentos" tabindex="-1" aria-labelledby="modalImportarLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content" style="border-radius: 12px; border: none;">
<div class="modal-header" style="background: linear-gradient(135deg, var(--info) 0%, #0e7490 100%); color: white; border-radius: 12px 12px 0 0;">
<h5 class="modal-title" id="modalImportarLabel">
<i class="fas fa-upload me-2"></i>
Importar Pedimentos desde Archivo
</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-4">
<div class="alert alert-info d-flex align-items-start" style="border: none; border-radius: 8px; background: rgba(8, 145, 178, 0.1); border-left: 4px solid var(--info);">
<i class="fas fa-info-circle me-2 mt-1" style="color: var(--info);"></i>
<div>
<strong>Formato del archivo:</strong>
<p class="mb-1">El sistema reconoce archivos con los siguientes códigos:</p>
<ul class="mb-2 small">
<li><strong>501:</strong> Datos del pedimento (número, RFC, fechas)</li>
<li><strong>505:</strong> Información de facturas</li>
<li><strong>551:</strong> Partidas de mercancías</li>
</ul>
<p class="mb-0 small text-muted">
<i class="fas fa-calendar-day me-1"></i>
<strong>Archivos julianos:</strong> Se aceptan extensiones de día del año (.001 a .366)
</p>
</div>
</div>
<form id="formImportarPedimentos" enctype="multipart/form-data">
<div class="mb-3">
<label for="archivoImportar" class="form-label fw-semibold">
<i class="fas fa-file-text me-1"></i>
Seleccionar archivos
</label>
<input type="file" class="form-control" id="archivoImportar" name="archivos[]" multiple required style="border-radius: 8px; border: 1px solid var(--border-color);">
<div class="form-text">Formatos soportados: .txt, .dat, archivos julianos (.001-.366). Puedes seleccionar varios archivos.</div>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="validarDuplicados" name="validar_duplicados" checked>
<label class="form-check-label fw-medium" for="validarDuplicados">
Validar pedimentos duplicados
</label>
<div class="form-text">Evita importar pedimentos que ya existen en el sistema</div>
</div>
</div>
<div id="previewContainer" style="display: none;" class="mb-3">
<h6 class="fw-semibold mb-2">
<i class="fas fa-eye me-1"></i>
Vista previa del archivo
</h6>
<div id="previewContent" class="p-3" style="background: #f8fafc; border-radius: 8px; border: 1px solid var(--border-color); max-height: 200px; overflow-y: auto; font-family: monospace; font-size: 0.85rem;"></div>
</div>
</form>
</div>
<div class="modal-footer" style="border-top: 1px solid var(--border-color); border-radius: 0 0 12px 12px;">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" style="border-radius: 8px;">
<i class="fas fa-times me-1"></i>
Cancelar
</button>
<button type="button" class="btn btn-primary" id="btnProcesarArchivo" style="border-radius: 8px; background: var(--info); border-color: var(--info);" disabled>
<i class="fas fa-cogs me-1"></i>
Procesar Archivos
</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script>
// Toast helper (Bootstrap 5): muestra un toast en la esquina superior derecha
function ensureToastContainer() {
let container = document.getElementById('toastContainer');
if (!container) {
container = document.createElement('div');
container.id = 'toastContainer';
container.className = 'position-fixed';
container.style.top = 'calc(var(--navbar-height, 70px) + 10px)';
container.style.right = '16px';
container.style.zIndex = '11000';
document.body.appendChild(container);
}
return container;
}
function mostrarToastImportacion(estadisticas) {
const ped = Number(estadisticas.pedimentos_procesados || 0);
const fac = Number(estadisticas.facturas_procesadas || 0);
const par = Number(estadisticas.partidas_procesadas || 0);
const dup = Number(estadisticas.duplicados || 0);
const err = Number(estadisticas.errores || 0);
const variant = err > 0 ? 'danger' : (dup > 0 ? 'warning' : 'success');
const title = err > 0 ? 'Importación con advertencias' : 'Importación completada';
const container = ensureToastContainer();
const toast = document.createElement('div');
toast.className = `toast align-items-center text-bg-${variant} border-0 shadow`;
toast.setAttribute('role', 'alert');
toast.setAttribute('aria-live', 'assertive');
toast.setAttribute('aria-atomic', 'true');
toast.innerHTML = `
<div class="d-flex">
<div class="toast-body">
<div class="fw-semibold mb-1"><i class="fas ${variant==='success' ? 'fa-check-circle' : (variant==='warning' ? 'fa-exclamation-triangle' : 'fa-times-circle')} me-1"></i>${title}</div>
<div class="small">
<span class="me-2">Pedimentos <span class="badge bg-light text-dark">${ped}</span></span>
<span class="me-2">Facturas <span class="badge bg-light text-dark">${fac}</span></span>
<span class="me-2">Partidas <span class="badge bg-light text-dark">${par}</span></span>
${dup > 0 ? `<span class=\"me-2\">Duplicados <span class=\"badge bg-dark\">${dup}</span></span>` : ''}
${err > 0 ? `<span class=\"me-2\">Errores <span class=\"badge bg-dark\">${err}</span></span>` : ''}
</div>
</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>`;
container.appendChild(toast);
const bsToast = new bootstrap.Toast(toast, { autohide: true, delay: 7000 });
bsToast.show();
toast.addEventListener('hidden.bs.toast', () => toast.remove());
}
// Base URL del proyecto (generada desde PHP)
const BASE_URL = '<?php echo "http" . (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] === "on" ? "s" : "") . "://" . $_SERVER["HTTP_HOST"] . "/IMPORTADORES"; ?>';
console.log('Base URL:', BASE_URL);
// Initialize page animations
document.addEventListener('DOMContentLoaded', function() {
const fadeElements = document.querySelectorAll('.fade-in');
fadeElements.forEach((element, index) => {
element.style.animationDelay = (index * 0.1) + 's';
});
// Add click handlers for cards
const cards = document.querySelectorAll('.feature-card');
cards.forEach(card => {
card.addEventListener('mouseenter', function() {
this.style.transform = 'translateY(-6px)';
});
card.addEventListener('mouseleave', function() {
this.style.transform = 'translateY(0)';
});
});
// Configurar eventos del modal de importación
configurarModalImportacion();
});
// Funciones para las acciones de las cards
function irListaPedimentos() {
window.location.href = 'lista.php';
}
function irCrearPedimento() {
window.location.href = 'crear.php';
}
function importarPedimentos() {
const modal = new bootstrap.Modal(document.getElementById('modalImportarPedimentos'));
modal.show();
}
function proximamente() {
Swal.fire({
icon: 'info',
title: 'Próximamente',
text: 'Esta función estará disponible próximamente.',
confirmButtonColor: '#2563eb',
customClass: {
popup: 'rounded-3'
}
});
}
// Configuración del modal de importación
function configurarModalImportacion() {
const archivoInput = document.getElementById('archivoImportar');
const previewContainer = document.getElementById('previewContainer');
const previewContent = document.getElementById('previewContent');
const btnProcesar = document.getElementById('btnProcesarArchivo');
if (!archivoInput) return; // Si no existe el elemento, salir
// Manejar selección de archivos (múltiples)
archivoInput.addEventListener('change', function(e) {
const archivos = Array.from(e.target.files || []);
if (archivos.length > 0) {
// Validar extensiones de todos los archivos seleccionados
const extensionesValidas = ['txt', 'dat'];
for (const file of archivos) {
const nombreArchivo = file.name.toLowerCase();
const extension = nombreArchivo.split('.').pop();
const esJuliana = /^\d{3}$/.test(extension); // 3 dígitos exactos
if (!extensionesValidas.includes(extension) && !esJuliana) {
Swal.fire({
icon: 'error',
title: 'Archivo no válido',
text: `"${file.name}" no es válido. Usa .txt, .dat o extensión juliana (.001-.366)`,
confirmButtonColor: '#dc2626',
customClass: { popup: 'rounded-3' }
});
archivoInput.value = '';
previewContainer.style.display = 'none';
btnProcesar.disabled = true;
return;
}
}
// Mostrar vista previa del PRIMER archivo y el total seleccionado
const reader = new FileReader();
reader.onload = function(e) {
const contenido = e.target.result;
mostrarVistaPrevia(contenido, archivos.length);
btnProcesar.disabled = false;
};
reader.readAsText(archivos[0]);
} else {
previewContainer.style.display = 'none';
btnProcesar.disabled = true;
}
});
// Manejar procesamiento del archivo
btnProcesar.addEventListener('click', function() {
procesarArchivoImportacion();
});
}
function mostrarVistaPrevia(contenido, totalArchivos = 1) {
const previewContainer = document.getElementById('previewContainer');
const previewContent = document.getElementById('previewContent');
const lineas = contenido.split('\n').slice(0, 10); // Mostrar solo las primeras 10 líneas
const preview = lineas.map(linea => {
// Resaltar diferentes tipos de registros
let clase = '';
if (linea.startsWith('501')) {
clase = 'style="color: #059669; font-weight: bold;"'; // Verde para pedimentos
} else if (linea.startsWith('505')) {
clase = 'style="color: #d97706; font-weight: bold;"'; // Naranja para facturas
} else if (linea.startsWith('551')) {
clase = 'style="color: #2563eb; font-weight: bold;"'; // Azul para partidas
}
return `<div ${clase}>${linea}</div>`;
}).join('');
let extra = '';
if (contenido.split('\n').length > 10) {
extra += '<div style="color: #6b7280; font-style: italic;">... y más líneas</div>';
}
if (totalArchivos > 1) {
const restantes = totalArchivos - 1;
extra += `<div class="mt-2" style="color: #374151; font-weight: 600;">+ ${restantes} archivo${restantes === 1 ? '' : 's'} más seleccionado${restantes === 1 ? '' : 's'}</div>`;
}
previewContent.innerHTML = preview + extra;
previewContainer.style.display = 'block';
}
function procesarArchivoImportacion() {
const formData = new FormData(document.getElementById('formImportarPedimentos'));
// Mostrar loading en el botón
const btnProcesar = document.getElementById('btnProcesarArchivo');
const textoOriginal = btnProcesar.innerHTML;
btnProcesar.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i>Procesando...';
btnProcesar.disabled = true;
// Llamada AJAX al backend
const url = `${BASE_URL}/public/importar_pedimentos.php`;
console.log('Attempting to fetch:', url);
fetch(url, {
method: 'POST',
body: formData
})
.then(response => {
console.log('Response status:', response.status);
console.log('Response headers:', response.headers);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log('Response data:', data);
// Restaurar botón
btnProcesar.innerHTML = textoOriginal;
btnProcesar.disabled = false;
if (data.success) {
// Verificar si es respuesta de prueba o de importación real
if (data.estadisticas) {
// Respuesta de importación real
const estadisticas = data.estadisticas;
// Mostrar toast superior derecho en lugar del modal
mostrarToastImportacion(estadisticas);
} else if (data.diagnostico) {
// Respuesta de diagnóstico
let mensaje = `🔍 Diagnóstico del Sistema:\n\n`;
// Mostrar checks
if (data.checks) {
mensaje += `📊 Estado de Componentes:\n`;
mensaje += `• Sesión: ${data.checks.sesion ? '✅' : '❌'}\n`;
mensaje += `• Usuario ID: ${data.checks.usuario_id || 'N/A'}\n`;
mensaje += `• Tipo Usuario: ${data.checks.tipo_usuario || 'N/A'}\n`;
mensaje += `• Método POST: ${data.checks.metodo_post ? '✅' : '❌'}\n`;
mensaje += `• Archivo recibido: ${data.checks.archivo_recibido ? '✅' : '❌'}\n`;
mensaje += `• Conexión DB: ${data.checks.conexion_db ? '✅' : '❌'}\n`;
mensaje += `• Dir. temporal: ${data.checks.directorio_temp_existe ? '✅' : '❌'}\n\n`;
}
// Mostrar errores potenciales
if (data.errores_potenciales && data.errores_potenciales.length > 0) {
mensaje += `⚠️ Problemas detectados:\n`;
data.errores_potenciales.forEach(error => {
mensaje += `• ${error}\n`;
});
mensaje += `\n`;
}
// Información del archivo
if (data.checks?.archivo_recibido) {
mensaje += `📁 Archivo: ${data.checks.archivo_nombre}\n`;
if (data.total_lineas) {
mensaje += `📏 Total líneas: ${data.total_lineas}\n`;
}
}
const icono = data.errores_potenciales.length > 0 ? 'warning' : 'success';
const titulo = data.errores_potenciales.length > 0 ? 'Problemas Detectados' : 'Sistema OK';
Swal.fire({
icon: icono,
title: titulo,
text: mensaje,
confirmButtonColor: icono === 'warning' ? '#d97706' : '#059669',
customClass: {
popup: 'rounded-3'
}
});
} else {
// Respuesta de prueba genérica
let mensaje = `✅ Conexión exitosa!\n\n`;
mensaje += `📁 Archivo: ${data.files_data?.nombre || 'No detectado'}\n`;
mensaje += `📏 Tamaño: ${data.files_data?.tamaño || 'N/A'} bytes\n`;
mensaje += `🕒 Timestamp: ${data.timestamp}\n`;
mensaje += `👤 Usuario: ${data.usuario}\n\n`;
mensaje += ` Esto es una prueba de conexión.`;
Swal.fire({
icon: 'info',
title: 'Prueba de Conexión',
text: mensaje,
confirmButtonColor: '#2563eb',
customClass: {
popup: 'rounded-3'
}
});
}
} else {
// Mostrar error
Swal.fire({
icon: 'error',
title: 'Error en la Importación',
text: data.message || 'Ocurrió un error al procesar el archivo',
confirmButtonColor: '#dc2626',
customClass: {
popup: 'rounded-3'
}
});
}
// Cerrar modal solo si fue exitoso
if (data.success) {
const modal = bootstrap.Modal.getInstance(document.getElementById('modalImportarPedimentos'));
modal.hide();
// Limpiar formulario
document.getElementById('formImportarPedimentos').reset();
document.getElementById('previewContainer').style.display = 'none';
}
})
.catch(error => {
// Restaurar botón en caso de error
btnProcesar.innerHTML = textoOriginal;
btnProcesar.disabled = false;
console.error('Error:', error);
Swal.fire({
icon: 'error',
title: 'Error de Conexión',
text: 'No se pudo conectar con el servidor. Verifique su conexión e intente nuevamente.',
confirmButtonColor: '#dc2626',
customClass: {
popup: 'rounded-3'
}
});
});
}
// Funciones para gestión de datos
function verificarPedimentosExistentes() {
fetch(`${BASE_URL}/public/verificar_pedimentos.php`)
.then(response => response.json())
.then(data => {
if (data.success) {
const stats = data.estadisticas;
let mensaje = `📊 Pedimentos en Base de Datos:\n\n`;
mensaje += `• Total: ${stats.total_pedimentos}\n`;
mensaje += `• Usuarios: ${stats.usuarios_distintos}\n`;
if (stats.total_pedimentos > 0) {
mensaje += `• Primer pedimento: ${stats.primer_pedimento?.date || 'N/A'}\n`;
mensaje += `• Último pedimento: ${stats.ultimo_pedimento?.date || 'N/A'}\n\n`;
if (data.pedimentos_existentes.length > 0) {
mensaje += `🔍 Últimos 5 pedimentos:\n`;
data.pedimentos_existentes.slice(0, 5).forEach(p => {
mensaje += `• ${p.numero_pedimento} (${p.fecha_creacion?.date || 'N/A'})\n`;
});
}
}
Swal.fire({
icon: 'info',
title: 'Pedimentos Existentes',
text: mensaje,
confirmButtonColor: '#2563eb'
});
}
})
.catch(error => console.error('Error:', error));
}
function limpiarBaseDatos() {
Swal.fire({
title: '⚠️ Confirmar Limpieza',
text: 'Esto eliminará TODOS los pedimentos, facturas y partidas. ¿Estás seguro?',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#dc2626',
cancelButtonColor: '#6b7280',
confirmButtonText: 'Sí, limpiar',
cancelButtonText: 'Cancelar'
}).then((result) => {
if (result.isConfirmed) {
fetch(`${BASE_URL}/public/limpiar_pedimentos.php`, {
method: 'POST'
})
.then(response => response.json())
.then(data => {
if (data.success) {
Swal.fire({
icon: 'success',
title: 'Base de Datos Limpiada',
text: 'Todos los registros han sido eliminados. Ahora puedes importar pedimentos sin duplicados.',
confirmButtonColor: '#059669'
});
} else {
Swal.fire({
icon: 'error',
title: 'Error al Limpiar',
text: data.message || 'No se pudo limpiar la base de datos',
confirmButtonColor: '#dc2626'
});
}
})
.catch(error => {
Swal.fire({
icon: 'error',
title: 'Error de Conexión',
text: 'No se pudo conectar al servidor para limpiar la BD',
confirmButtonColor: '#dc2626'
});
});
}
});
}
// Limpiar modal al cerrar
const modal = document.getElementById('modalImportarPedimentos');
if (modal) {
modal.addEventListener('hidden.bs.modal', function() {
document.getElementById('formImportarPedimentos').reset();
document.getElementById('previewContainer').style.display = 'none';
document.getElementById('btnProcesarArchivo').disabled = true;
});
}
</script>
</body>
</html>