diff --git a/src/pages/Auditor.jsx b/src/pages/Auditor.jsx index 2599046..452a463 100644 --- a/src/pages/Auditor.jsx +++ b/src/pages/Auditor.jsx @@ -11,6 +11,489 @@ import { downloadFile } from '../utils/downloadUtils'; const API_URL = import.meta.env.VITE_EFC_API_URL; +const TIPO_LABELS = { + pc: 'Pedimento Completo', + rm: 'Remesas', + pt: 'Partidas', + ac: 'Acuse de EDocument', + cove: 'COVE', + ac_cove: 'Acuse de COVE', + edoc: 'EDocument', +}; + +// Mapeo tipo auditoría → url_path del endpoint de procesamiento individual +const PROCESAMIENTO_URL_MAP = { + rm: 'procesar-remesas', + pt: 'procesar-partidas', + cove: 'procesar-coves', + ac_cove: 'procesar-acuse-coves', + edoc: 'procesar-edocuments', + ac: 'procesar-acuses', +}; + +function AuditResultModal({ modal, iniciandoProcesamiento, onClose, onIniciarProcesamiento }) { + const { tipo, pedimento_app, data } = modal; + // si el backend no retorna 'estado' (ej. pedimento completo), tratamos como no completado + const esCompletado = data?.estado === 'completado' || data?.auditoria_completa == true; + // remesa sin remesas: no tiene nada que procesar, ocultar botón + const sinNadaQueHacer = tipo === 'rm' && data?.tiene_remesas === false; + const mostrarBotonProcesar = !esCompletado && !sinNadaQueHacer; + + const tituloTipo = TIPO_LABELS[tipo] || tipo; + + const iconoEstado = esCompletado ? ( +
+ + + +
+ ) : ( +
+ + + +
+ ); + + return ( +
+
+ {/* Header */} +
+
+
+

{tituloTipo}

+

{pedimento_app}

+
+ + + {esCompletado ? 'Completado' : 'En proceso'} + +
+
+ + {/* Cuerpo */} +
+ {iconoEstado} + + {/* Mensaje principal */} +

{data?.mensaje}

+ + {/* Resumen numérico */} + {data?.resumen && ( +
+ {Object.entries(data.resumen).map(([key, val]) => ( +
+ {val} + + {key.replace(/_/g, ' ')} + +
+ ))} +
+ )} + + {/* Resumen de XMLs analizados — solo muestra lo relevante */} + {data?.xmls_analizados && (() => { + const total = data.xmls_analizados.length; + const conError = data.xmls_analizados.filter(x => x.informacion_extraida?.tiene_error === true); + const auditOk = data.auditoria_completa !== false; + + return ( +
+ {/* Contadores compactos */} +
+
+ {data.archivos_xml_encontrados ?? total} + Encontrados +
+
+ {total} + Analizados +
+
0 ? 'bg-red-50 border-red-100' : 'bg-green-50 border-green-100'}`}> + 0 ? 'text-red-700' : 'text-green-700'}`}>{conError.length} + 0 ? 'text-red-500' : 'text-green-500'}`}>Con error +
+
+ + {/* Advertencia si auditoría incompleta */} + {!auditOk && ( +
+ + + + Auditoría incompleta — algunos documentos no pudieron verificarse +
+ )} + + {/* Detalle de XMLs con error */} + {conError.length > 0 && ( +
+ + XMLs con error ({conError.length}) + + + + +
+ {conError.map((xml) => ( +
+

{xml.nombre_archivo}

+

{xml.tipo_documento}

+
+ ))} +
+
+ )} + + {/* Todo bien */} + {conError.length === 0 && auditOk && ( +

Todos los XMLs analizados están correctos

+ )} +
+ ); + })()} + + {/* Pendientes */} + {data?.pendientes && data.pendientes.length > 0 && ( +
+

Pendientes ({data.pendientes.length})

+
+ {data.pendientes.map((item, i) => ( +
+ + + + {item} +
+ ))} +
+
+ )} + + {/* COVEs para remesa */} + {tipo === 'rm' && data?.coves && data.coves.length > 0 && ( +
+

COVEs registrados ({data.coves.length})

+
+ {data.coves.map((cove, i) => ( + + {cove} + + ))} +
+
+ )} +
+ + {/* Footer */} +
+ {mostrarBotonProcesar && ( + + )} + +
+
+
+ ); +} + +// Modal para auditorías globales (tareas en background) +function GlobalAuditModal({ modal, onClose, onConsultar, consultando, onIniciarProceso, iniciandoProceso }) { + const { label, task_id, resultado } = modal; + + const hayPendientes = resultado && (resultado.result?.con_pendientes > 0 || resultado.result?.con_errores > 0); + const esCompletado = resultado && !hayPendientes; + + const headerBg = !resultado + ? 'bg-slate-50 border-b border-slate-100' + : esCompletado + ? 'bg-green-50 border-b border-green-100' + : 'bg-amber-50 border-b border-amber-100'; + + const badge = !resultado ? ( + + + En cola + + ) : esCompletado ? ( + + + Completado + + ) : ( + + + Pendientes + + ); + + const handleIniciarCorreccion = () => { + setIniciandoCorreccion(true); + setTimeout(() => { + setIniciandoCorreccion(false); + }, 1500); + }; + + return ( +
+
+ {/* Header */} +
+
+
+

Auditoría Global

+

{label}

+
+ {badge} +
+
+ + {/* Cuerpo scrolleable */} +
+ {!resultado ? ( + /* Fase: tarea lanzada, esperando resultado */ + <> +
+ + + +
+

La tarea fue enviada al worker. Consulta el resultado cuando haya finalizado.

+
+ Task ID: + {task_id} +
+ + ) : ( + /* Fase: resultado disponible */ + <> + {/* Icono de estado */} + {esCompletado ? ( +
+ + + +
+ ) : ( +
+ + + +
+ )} + +

{resultado.mensaje}

+ + {/* Grid de cifras */} +
+
+ {resultado.result?.total_pedimentos ?? '—'} + Total +
+
+ {resultado.result?.completados ?? '—'} + Completos +
+
+ {resultado.result?.con_pendientes ?? '—'} + Pendientes +
+
+ {resultado.result?.con_errores ?? '—'} + Errores +
+
+ + {/* Tabla de pedimentos con pendientes */} + {resultado.detalle_pendientes && resultado.detalle_pendientes.length > 0 && ( +
+ + Pedimentos con pendientes ({resultado.detalle_pendientes.length}) + + + + +
+ + + + + + + + + + {resultado.detalle_pendientes.map((item, i) => { + const faltantesEntries = Object.entries(item).filter(([k]) => k.startsWith('faltantes_')); + const todosLosIds = faltantesEntries.flatMap(([, v]) => Array.isArray(v) ? v : []); + return ( + + + + + + ); + })} + +
PedimentoDocumentos faltantesProgreso
+ {item.pedimento} + +
+ {todosLosIds.map((id, j) => ( + + {id} + + ))} + {todosLosIds.length === 0 && ( + sin detalle + )} +
+
+ {item.descargados ?? '?'}/{item.total ?? '?'} +
+
+
+ )} + + {/* Tabla de errores */} + {resultado.detalle_errores && resultado.detalle_errores.length > 0 && ( +
+ + Errores ({resultado.detalle_errores.length}) + + + + +
+ + + + + + + + + {resultado.detalle_errores.map((item, i) => ( + + + + + ))} + +
PedimentoError
{item.pedimento}{item.error || '—'}
+
+
+ )} + + )} +
+ + {/* Footer */} +
+ {/* Botón "Consultar estado" cuando aún no hay resultado */} + {!resultado && ( + + )} + + {/* Botón "Iniciar Proceso" cuando hay resultado con pendientes/errores */} + {hayPendientes && ( + + )} + + +
+
+
+ ); +} + function Auditor() { const { showMessage } = useNotification(); const [loading, setLoading] = useState(false); @@ -48,6 +531,7 @@ function Auditor() { const [previewDoc, setPreviewDoc] = useState(null); const [previewContent, setPreviewContent] = useState(''); const [imageZoom, setImageZoom] = useState(1); + const [previewIframeLoaded, setPreviewIframeLoaded] = useState(false); // === Estados Peticiones a VU === // const [peticionPedimentoVU, setPeticionPedimentoVU] = useState(null); // ID del pedimento en procesamiento @@ -58,7 +542,81 @@ function Auditor() { // Agrega este estado cerca de los otros estados const [activeVista, setActiveVista] = useState(null); // 'pc', 'rm', 'pt', 'ac', 'cove', 'ac_cove', 'edoc' - + // Modal de resultado de auditoría individual + const [auditResultModal, setAuditResultModal] = useState(null); // { tipo, pedimento_app, data } + const [iniciandoProcesamiento, setIniciandoProcesamiento] = useState(false); + + // Modal de auditoría global (tareas en background) + const [globalAuditModal, setGlobalAuditModal] = useState(null); // { label, procesamiento, organizacion_id, task_id, resultado } + const [consultandoTask, setConsultandoTask] = useState(false); + const [iniciandoProcesoGlobal, setIniciandoProcesoGlobal] = useState(false); + + const handleIniciarProcesoGlobal = async () => { + if (!globalAuditModal?.procesamiento || !globalAuditModal?.organizacion_id || iniciandoProcesoGlobal) return; + try { + setIniciandoProcesoGlobal(true); + const response = await postWithAuth(`${API_URL}/customs/procesamientopedimentos-ejecutar-comando/`, { + procesamiento: globalAuditModal.procesamiento, + organizacionid: globalAuditModal.organizacion_id, + }); + if (!response.ok) { + const errorData = await response.json().catch(() => ({})); + throw new Error(errorData.message || errorData.error || `Error ${response.status}`); + } + const data = await response.json(); + showMessage(data.message || 'Proceso iniciado correctamente', 'success'); + setGlobalAuditModal(null); + } catch (error) { + showMessage(error.message || 'Error al iniciar el proceso', 'error'); + } finally { + setIniciandoProcesoGlobal(false); + } + }; + + const handleIniciarProcesamiento = async () => { + if (!auditResultModal || iniciandoProcesamiento) return; + const { tipo, pedimento_id } = auditResultModal; + const urlPath = PROCESAMIENTO_URL_MAP[tipo]; + if (!urlPath) { + showMessage('No hay endpoint de procesamiento disponible para este tipo', 'info'); + return; + } + try { + setIniciandoProcesamiento(true); + const response = await postWithAuth(`${API_URL}/customs/pedimentos/${pedimento_id}/${urlPath}/`); + if (!response.ok) { + const errorData = await response.json().catch(() => ({})); + throw new Error(errorData.message || errorData.error || `Error ${response.status}`); + } + const data = await response.json(); + showMessage(data.status || 'Procesamiento iniciado correctamente', 'success'); + setAuditResultModal(null); + } catch (error) { + showMessage(error.message || 'Error al iniciar el procesamiento', 'error'); + } finally { + setIniciandoProcesamiento(false); + } + }; + + const handleConsultarTask = async () => { + if (!globalAuditModal?.task_id || consultandoTask) return; + try { + setConsultandoTask(true); + const response = await getWithAuth(`${API_URL}/tasks/status/${globalAuditModal.task_id}/`); + if (!response.ok) throw new Error('Error al consultar el estado de la tarea'); + const data = await response.json(); + if (data.ready) { + setGlobalAuditModal(prev => ({ ...prev, resultado: data })); + } else { + showMessage('La tarea aún no ha finalizado, intenta nuevamente en unos segundos', 'info'); + } + } catch (error) { + showMessage(error.message || 'Error al consultar tarea', 'error'); + } finally { + setConsultandoTask(false); + } + }; + // Handler para auditar acuses (general) const handleAuditarAcuses = async () => { if (auditandoAcuses) return; @@ -74,10 +632,10 @@ function Auditor() { if (!response.ok) { throw new Error('Error al iniciar la auditoría de acuses'); } - alert('La auditoría de acuses se ha iniciado correctamente'); + const data = await response.json(); + setGlobalAuditModal({ label: 'Acuses', procesamiento: 'acuses', organizacion_id: organizacionId, task_id: data.task_id, resultado: null }); } catch (error) { - console.error('Error:', error); - alert(error.message); + showMessage(error.message || 'Error al iniciar la auditoría de acuses', 'error'); } finally { setAuditandoAcuses(false); } @@ -98,10 +656,10 @@ function Auditor() { if (!response.ok) { throw new Error('Error al iniciar la auditoría de EDocuments'); } - alert('La auditoría de EDocuments se ha iniciado correctamente'); + const data = await response.json(); + setGlobalAuditModal({ label: 'EDocuments', procesamiento: 'edocs', organizacion_id: organizacionId, task_id: data.task_id, resultado: null }); } catch (error) { - console.error('Error:', error); - alert(error.message); + showMessage(error.message || 'Error al iniciar la auditoría de EDocuments', 'error'); } finally { setAuditandoEDocuments(false); } @@ -112,7 +670,6 @@ function Auditor() { if (auditandoAcusesCove) return; try { setAuditandoAcusesCove(true); - // Obtener el organizacion_id del primer pedimento const organizacionId = pedimentos[0]?.organizacion; if (!organizacionId) { throw new Error('No hay organización disponible para auditar'); @@ -123,10 +680,10 @@ function Auditor() { if (!response.ok) { throw new Error('Error al iniciar la auditoría de acuses cove'); } - alert('La auditoría de acuses cove se ha iniciado correctamente'); + const data = await response.json(); + setGlobalAuditModal({ label: 'Acuses de COVE', procesamiento: 'acuse_coves', organizacion_id: organizacionId, task_id: data.task_id, resultado: null }); } catch (error) { - console.error('Error:', error); - alert(error.message); + showMessage(error.message || 'Error al iniciar la auditoría de acuses cove', 'error'); } finally { setAuditandoAcusesCove(false); } @@ -135,6 +692,7 @@ function Auditor() { // Handler para auditar un pedimento específico const handleAuditarPedimento = async (pedimentoId) => { if (procesandoPedimento) return; + const pedimento = pedimentos.find(p => p.id === pedimentoId); try { setProcesandoPedimento(pedimentoId); const response = await postWithAuth(`${API_URL}/customs/auditor/auditar-pedimento/`, { @@ -143,11 +701,9 @@ function Auditor() { if (!response.ok) { throw new Error('Error al auditar el pedimento'); } - // alert('El pedimento se ha auditado correctamente'); - showMessage('El pedimento se ha auditado correctamente', 'success'); + const data = await response.json(); + setAuditResultModal({ tipo: 'pc', pedimento_id: pedimentoId, pedimento_app: pedimento?.pedimento_app, data }); } catch (error) { - // console.error('Error:', error); - // alert(error.message); showMessage(error.message || 'Error al auditar el pedimento', 'error'); } finally { setProcesandoPedimento(null); @@ -157,7 +713,7 @@ function Auditor() { // Handler para auditar remesas de un pedimento específico const handleAuditarRemesaPedimento = async (pedimentoId) => { if (procesandoRemesa) return; - + const pedimento = pedimentos.find(p => p.id === pedimentoId); try { setProcesandoRemesa(pedimentoId); @@ -169,11 +725,9 @@ function Auditor() { throw new Error('Error al procesar las remesas del pedimento'); } - // Mostrar mensaje de éxito - showMessage('Las remesas del pedimento se están procesando', 'success'); + const data = await response.json(); + setAuditResultModal({ tipo: 'rm', pedimento_id: pedimentoId, pedimento_app: pedimento?.pedimento_app, data }); } catch (error) { - // console.error('Error:', error); - //alert(error.message); showMessage(error.message || 'Error al procesar las remesas del pedimento', 'error'); } finally { setProcesandoRemesa(null); @@ -185,14 +739,13 @@ function Auditor() { try { setAuditandoRemesas(true); - // Obtener el organizacion_id del primer pedimento const organizacionId = pedimentos[0]?.organizacion; if (!organizacionId) { throw new Error('No hay organización disponible para auditar'); } - const response = await postWithAuth(`${API_URL}/customs/auditor/auditar-procesamiento-remesas/`, { + const response = await postWithAuth(`${API_URL}/customs/auditor/auditar-remesas/`, { organizacion_id: organizacionId }); @@ -200,23 +753,21 @@ function Auditor() { throw new Error('Error al iniciar la auditoría de remesas'); } - // Mostrar mensaje de éxito - alert('La auditoría de remesas se ha iniciado correctamente'); + const data = await response.json(); + setGlobalAuditModal({ label: 'Remesas', procesamiento: 'remesas', organizacion_id: organizacionId, task_id: data.task_id, resultado: null }); } catch (error) { - console.error('Error:', error); - alert(error.message); + showMessage(error.message || 'Error al iniciar la auditoría de remesas', 'error'); } finally { setAuditandoRemesas(false); } }; const handleAuditarPartidasPedimento = async (pedimentoId) => { - // if (procesandoPedimento) return; if (procesandoPartida) return; - + const pedimento = pedimentos.find(p => p.id === pedimentoId); + try { - // setProcesandoPedimento(pedimentoId); setProcesandoPartida(pedimentoId); const response = await postWithAuth(`${API_URL}/customs/auditor/crear-partidas/pedimento/`, { pedimento_id: pedimentoId @@ -226,14 +777,11 @@ function Auditor() { throw new Error('Error al procesar las partidas del pedimento'); } - // Mostrar mensaje de éxito - showMessage('Las partidas del pedimento se están procesando', 'success'); + const data = await response.json(); + setAuditResultModal({ tipo: 'pt', pedimento_id: pedimentoId, pedimento_app: pedimento?.pedimento_app, data }); } catch (error) { - //console.error('Error:', error); - // alert(error.message); showMessage(error.message || 'Error al procesar las partidas del pedimento', 'error'); } finally { - // setProcesandoPedimento(null); setProcesandoPartida(null); } }; @@ -243,7 +791,6 @@ function Auditor() { try { setAuditandoPartidas(true); - // Obtener el organizacion_id del primer pedimento const organizacionId = pedimentos[0]?.organizacion; if (!organizacionId) { @@ -258,12 +805,11 @@ function Auditor() { throw new Error('Error al iniciar la auditoría de partidas'); } - // Mostrar mensaje de éxito - alert('La auditoría de partidas se ha iniciado correctamente'); + const data = await response.json(); + setGlobalAuditModal({ label: 'Partidas', procesamiento: 'partidas', organizacion_id: organizacionId, task_id: data.task_id, resultado: null }); } catch (error) { - console.error('Error:', error); - alert(error.message); + showMessage(error.message || 'Error al iniciar la auditoría de partidas', 'error'); } finally { setAuditandoPartidas(false); } @@ -274,7 +820,6 @@ function Auditor() { try { setAuditando(true); - // Obtener el organizacion_id del primer pedimento const organizacionId = pedimentos[0]?.organizacion; if (!organizacionId) { @@ -289,12 +834,11 @@ function Auditor() { throw new Error('Error al iniciar la auditoría'); } - // Mostrar mensaje de éxito - alert('La auditoría se ha iniciado correctamente'); + const data = await response.json(); + setGlobalAuditModal({ label: 'Pedimentos', organizacion_id: organizacionId, task_id: data.task_id, resultado: null }); } catch (error) { - console.error('Error:', error); - alert(error.message); + showMessage(error.message || 'Error al iniciar la auditoría', 'error'); } finally { setAuditando(false); } @@ -302,6 +846,7 @@ function Auditor() { const handleAuditarAcusePedimento = async (pedimentoId) => { if (procesandoAcuse) return; + const pedimento = pedimentos.find(p => p.id === pedimentoId); try { setProcesandoAcuse(pedimentoId); const response = await postWithAuth(`${API_URL}/customs/auditor/auditar-acuse/pedimento/`, { @@ -310,11 +855,9 @@ function Auditor() { if (!response.ok) { throw new Error('Error al auditar acuse del pedimento'); } - // alert('El acuse del pedimento se está auditando'); - showMessage('El acuse del pedimento se está auditando', 'success'); + const data = await response.json(); + setAuditResultModal({ tipo: 'ac', pedimento_id: pedimentoId, pedimento_app: pedimento?.pedimento_app, data }); } catch (error) { - // console.error('Error:', error); - // alert(error.message); showMessage(error.message || 'Error al auditar acuse del pedimento', 'error'); } finally { setProcesandoAcuse(null); @@ -323,6 +866,7 @@ function Auditor() { const handleAuditarAcusesCovePedimento = async (pedimentoId) => { if (procesandoAcuseCove) return; + const pedimento = pedimentos.find(p => p.id === pedimentoId); try { setProcesandoAcuseCove(pedimentoId); const response = await postWithAuth(`${API_URL}/customs/auditor/auditar-acuse-cove/pedimento/`, { @@ -331,20 +875,19 @@ function Auditor() { if (!response.ok) { throw new Error('Error al auditar acuse cove del pedimento'); } - // alert('El acuse del pedimento se está auditando'); - showMessage('El acuse cove del pedimento se está auditando', 'success'); + const data = await response.json(); + setAuditResultModal({ tipo: 'ac_cove', pedimento_id: pedimentoId, pedimento_app: pedimento?.pedimento_app, data }); } catch (error) { - // console.error('Error:', error); - // alert(error.message); showMessage(error.message || 'Error al auditar acuse cove del pedimento', 'error'); } finally { setProcesandoAcuseCove(null); } - }; + }; const handleAuditarEDocumentPedimento = async (pedimentoId) => { if (procesandoEdocumento) return; + const pedimento = pedimentos.find(p => p.id === pedimentoId); try { setProcesandoEdocumento(pedimentoId); const response = await postWithAuth(`${API_URL}/customs/auditor/auditar-edocument/pedimento/`, { @@ -353,11 +896,9 @@ const handleAuditarEDocumentPedimento = async (pedimentoId) => { if (!response.ok) { throw new Error('Error al auditar eDocument del pedimento'); } - // alert('El eDocument del pedimento se está auditando'); - showMessage('El eDocument del pedimento se está auditando', 'success'); + const data = await response.json(); + setAuditResultModal({ tipo: 'edoc', pedimento_id: pedimentoId, pedimento_app: pedimento?.pedimento_app, data }); } catch (error) { - // console.error('Error:', error); - // alert(error.message); showMessage(error.message || 'Error al auditar eDocument del pedimento', 'error'); } finally { setProcesandoEdocumento(null); @@ -366,6 +907,7 @@ const handleAuditarEDocumentPedimento = async (pedimentoId) => { const handleAuditarCovePedimento = async (pedimentoId) => { if (procesandoCove) return; + const pedimento = pedimentos.find(p => p.id === pedimentoId); try { setProcesandoCove(pedimentoId); const response = await postWithAuth(`${API_URL}/customs/auditor/auditar-cove/pedimento/`, { @@ -374,11 +916,9 @@ const handleAuditarEDocumentPedimento = async (pedimentoId) => { if (!response.ok) { throw new Error('Error al auditar COVE del pedimento'); } - // alert('El COVE del pedimento se está auditando'); - showMessage('El COVE del pedimento se está auditando', 'success'); + const data = await response.json(); + setAuditResultModal({ tipo: 'cove', pedimento_id: pedimentoId, pedimento_app: pedimento?.pedimento_app, data }); } catch (error) { - // console.error('Error:', error); - // alert(error.message); showMessage(error.message || 'Error al auditar COVE del pedimento', 'error'); } finally { setProcesandoCove(null); @@ -579,6 +1119,7 @@ const handleAuditarEDocumentPedimento = async (pedimentoId) => { setPreviewDoc(doc); setImageZoom(1); setPreviewContent(''); + setPreviewIframeLoaded(false); setPreviewOpen(true); try { const res = await fetchWithAuth(`${API_URL}/record/documents/descargar/${doc.id}/`); @@ -618,12 +1159,17 @@ const handleAuditarEDocumentPedimento = async (pedimentoId) => { setPreviewLoading(false); } else { const blob = await res.blob(); + if (blob.size === 0) { + setPreviewError('El archivo está vacío o no está disponible en el servidor.'); + setPreviewLoading(false); + return; + } const url = window.URL.createObjectURL(blob); setPreviewUrl(url); setPreviewLoading(false); } } catch (err) { - console.error('Error in preview:', err); + console.error('Error en vista previa:', err); if (err.message === 'SESSION_EXPIRED') { setPreviewError('Tu sesión ha expirado, por favor inicia sesión de nuevo.'); } else { @@ -1145,8 +1691,9 @@ const handleAuditarEDocumentPedimento = async (pedimentoId) => { setPreviewDoc(null); setPreviewContent(''); setImageZoom(1); + setPreviewIframeLoaded(false); }; - + // Función para formatear XML (pretty print) function formatXml(xml) { const PADDING = ' '; @@ -1176,7 +1723,7 @@ function formatXml(xml) { const queryParams = new URLSearchParams({ page: page.toString(), page_size: itemsPerPage.toString(), - ...(pedimentoFilter && { pedimento_app: pedimentoFilter }) + ...(pedimentoFilter && { search: pedimentoFilter }) }); const response = await getWithAuth(`${API_URL}/customs/pedimentos/?${queryParams}`); if (!response.ok) throw new Error('Error al cargar los pedimentos'); @@ -1276,31 +1823,31 @@ function formatXml(xml) { Servicios de Auditoría -
+
@@ -1308,27 +1855,27 @@ function formatXml(xml) { @@ -1336,27 +1883,27 @@ function formatXml(xml) { @@ -1364,16 +1911,16 @@ function formatXml(xml) { @@ -1392,27 +1939,27 @@ function formatXml(xml) { @@ -1420,27 +1967,27 @@ function formatXml(xml) { @@ -1881,6 +2428,28 @@ function formatXml(xml) {
)} + {/* Modal de auditoría global */} + {globalAuditModal && ( + setGlobalAuditModal(null)} + onConsultar={handleConsultarTask} + consultando={consultandoTask} + onIniciarProceso={handleIniciarProcesoGlobal} + iniciandoProceso={iniciandoProcesoGlobal} + /> + )} + + {/* Modal de resultado de auditoría individual */} + {auditResultModal && ( + setAuditResultModal(null)} + onIniciarProcesamiento={handleIniciarProcesamiento} + /> + )} + {/* Modal de Vista Previa XML */} {/* {showXmlModal && xmlData && (
@@ -2253,20 +2822,42 @@ function formatXml(xml) {

Error al cargar documento

{previewError}

) : previewType === 'pdf' ? ( -
-