From d09c99f1a9770da577328e9abb2a37378316dba2 Mon Sep 17 00:00:00 2001 From: Kevin Rosales Date: Sun, 5 Oct 2025 22:48:15 -0600 Subject: [PATCH] auditor --- src/App.jsx | 7 + src/components/Sidebar.jsx | 9 + src/pages/Auditor.jsx | 649 ++++++++++++++++++++++++++++ src/pages/Documents.jsx | 1 - src/pages/PedimentoDetail.jsx | 594 +++++++++++++++++++------ src/pages/TableroAlmacenamiento.jsx | 8 +- 6 files changed, 1136 insertions(+), 132 deletions(-) create mode 100644 src/pages/Auditor.jsx diff --git a/src/App.jsx b/src/App.jsx index a9d5375..3995a63 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -2,6 +2,7 @@ import Documents from './pages/Documents'; import Datastage from './pages/Datastage'; import Agenda from './pages/Agenda'; import Vucem from './pages/Vucem'; +import Auditor from './pages/Auditor'; import { BrowserRouter, Routes, Route, useLocation } from 'react-router-dom'; import { UserProvider } from './context/UserContext'; import Navbar from './components/Navbar'; @@ -122,6 +123,12 @@ function AppContent() { } /> + {/* Ruta para Auditor */} + + + + } /> ); diff --git a/src/components/Sidebar.jsx b/src/components/Sidebar.jsx index 337fd38..4d37f98 100644 --- a/src/components/Sidebar.jsx +++ b/src/components/Sidebar.jsx @@ -100,6 +100,15 @@ export default function Sidebar({ isMobileOpen, onMobileClose }) { ) + }, + { + name: 'Auditor', + path: '/auditor', + icon: ( + + + + ) } ] }, diff --git a/src/pages/Auditor.jsx b/src/pages/Auditor.jsx new file mode 100644 index 0000000..832aac0 --- /dev/null +++ b/src/pages/Auditor.jsx @@ -0,0 +1,649 @@ +import React, { useState, useEffect } from 'react'; +import { getWithAuth, postWithAuth } from '../fetchWithAuth'; +const API_URL = import.meta.env.VITE_EFC_API_URL; + +function Auditor() { + const [loading, setLoading] = useState(false); + const [error, setError] = useState(''); + const [pedimentos, setPedimentos] = useState([]); + const [showInstructions, setShowInstructions] = useState(false); + const [count, setCount] = useState(0); + const [page, setPage] = useState(1); + const [itemsPerPage] = useState(10); + const [auditando, setAuditando] = useState(false); + const [auditandoPartidas, setAuditandoPartidas] = useState(false); + const [auditandoRemesas, setAuditandoRemesas] = useState(false); + const [procesandoPedimento, setProcesandoPedimento] = useState(null); + const [procesandoRemesa, setProcesandoRemesa] = useState(null); + + const handleAuditarRemesaPedimento = async (pedimentoId) => { + if (procesandoRemesa) return; + + try { + setProcesandoRemesa(pedimentoId); + + const response = await postWithAuth(`${API_URL}/customs/auditor/auditar-procesamiento-remesa/pedimento/`, { + pedimento_id: pedimentoId + }); + + if (!response.ok) { + throw new Error('Error al procesar las remesas del pedimento'); + } + + // Mostrar mensaje de éxito + alert('Las remesas del pedimento se están procesando'); + + } catch (error) { + console.error('Error:', error); + alert(error.message); + } finally { + setProcesandoRemesa(null); + } + }; + + const handleAuditarRemesas = async () => { + if (auditandoRemesas) return; + + 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/`, { + organizacion_id: organizacionId + }); + + if (!response.ok) { + 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'); + + } catch (error) { + console.error('Error:', error); + alert(error.message); + } finally { + setAuditandoRemesas(false); + } + }; + + const handleAuditarPartidasPedimento = async (pedimentoId) => { + if (procesandoPedimento) return; + + try { + setProcesandoPedimento(pedimentoId); + + const response = await postWithAuth(`${API_URL}/customs/auditor/crear-partidas/pedimento/`, { + pedimento_id: pedimentoId + }); + + if (!response.ok) { + throw new Error('Error al procesar las partidas del pedimento'); + } + + // Mostrar mensaje de éxito + alert('Las partidas del pedimento se están procesando'); + + } catch (error) { + console.error('Error:', error); + alert(error.message); + } finally { + setProcesandoPedimento(null); + } + }; + + const handleAuditarPartidas = async () => { + if (auditandoPartidas) return; + + try { + setAuditandoPartidas(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/crear-partidas/organizacion/`, { + organizacion_id: organizacionId + }); + + if (!response.ok) { + 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'); + + } catch (error) { + console.error('Error:', error); + alert(error.message); + } finally { + setAuditandoPartidas(false); + } + }; + + const handleAuditarTodos = async () => { + if (auditando) return; + + try { + setAuditando(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-pedimentos/`, { + organizacion_id: organizacionId + }); + + if (!response.ok) { + throw new Error('Error al iniciar la auditoría'); + } + + // Mostrar mensaje de éxito + alert('La auditoría se ha iniciado correctamente'); + + } catch (error) { + console.error('Error:', error); + alert(error.message); + } finally { + setAuditando(false); + } + }; + + useEffect(() => { + const fetchPedimentos = async () => { + setLoading(true); + try { + const response = await getWithAuth(`${API_URL}/customs/pedimentos/?page=${page}&page_size=${itemsPerPage}`); + if (!response.ok) throw new Error('Error al cargar los pedimentos'); + const data = await response.json(); + setPedimentos(data.results); + setCount(data.count); + } catch (err) { + setError(err.message); + } finally { + setLoading(false); + } + }; + fetchPedimentos(); + }, [page, itemsPerPage]); + + return ( +
+
+ {/* Header mejorado y responsivo */} +
+
+ + + +
+
+

+ Panel de Auditoría +

+
+

+ Monitoreo y control de operaciones +

+ +
+
+ {/* Efectos decorativos de fondo */} +
+
+
+
+
+
+ {/* Partículas flotantes */} +
+
+
+
+
+
+ + {/* Contenido principal */} +
+ + {loading ? ( +
+
+
+
+
+

Cargando datos...

+
+ ) : error ? ( +
+
+ + + +
+

Error al cargar

+

{error}

+
+ ) : ( +
+
+
+

+ + + + Servicios de Auditoría +

+ +
+ + + + + +
+
+ + {/* Tabla de pedimentos */} +
+ + + + + + + + + + + + + + + {pedimentos.map((pedimento) => ( + + + {/* PC - Pedimento Completo */} + + {/* RM - Remesas */} + + {/* PT - Partidas */} + + {/* AC - Acuse */} + + {/* COVE */} + + {/* AC_COVE */} + + {/* EDoc */} + + + ))} + +
+ Pedimento + + PC + Pedimento Completo + + RM + Remesas + + PT + Partidas + + AC + Acuse + + COVE + Cove + + AC_COVE + Acuse de Cove + + EDoc + EDocument +
+ {pedimento.pedimento_app} + + + + + + + + + + + + + + +
+
+ + {/* Paginación */} + {count > 0 && ( +
+
+ + +
+
+
+

+ Mostrando {((page - 1) * itemsPerPage) + 1} a{' '} + {Math.min(page * itemsPerPage, count)} de{' '} + {count} resultados +

+
+
+ +
+
+
+ )} +
+
+ )} +
+
+ + {/* Modal de Instrucciones */} + {showInstructions && ( +
+
+
+

+ + + + Instrucciones de Auditoría +

+ +
+
+
+
+

+ + + + Auditar Todos los Pedimentos +

+

Este proceso revisará uno a uno cada XML del pedimento completo y agregará los campos restantes en nuestra tabla de pedimentos. Si el documento tiene COVEs y E-Docs, también los subirá a nuestra base de datos.

+
+
+

+ + + + Auditar Partidas +

+

Creará todas las partidas de cada uno de los pedimentos, extrayendo la información detallada de cada una.

+
+
+

+ + + + Auditar Remesas +

+

Obtendrá y agregará todos los COVEs existentes en el documento a nuestra base de datos.

+
+
+
+
+ +
+
+
+ )} + + {/* Animaciones CSS */} + +
+ ); +} + +export default Auditor; diff --git a/src/pages/Documents.jsx b/src/pages/Documents.jsx index b2c85a8..eb4547b 100644 --- a/src/pages/Documents.jsx +++ b/src/pages/Documents.jsx @@ -511,7 +511,6 @@ export default function Documents() { {doc.extension}