Nuevos Ajustes en la vista de modal de Peticiones y Respuestas

This commit is contained in:
2026-01-02 07:39:28 -07:00
parent a78ed6f51b
commit 4414923d04

View File

@@ -509,11 +509,19 @@ const handleAuditarEDocumentPedimento = async (pedimentoId) => {
let endpoint = `${API_URL}/customs/auditor/peticion-respuesta/pedimento-vu/`;
const response = await postWithAuth(endpoint, {
pedimento_id: pedimento.id
pedimento_id: pedimento.id,
vista: vista_auditar
});
if (!response.ok) {
showMessage(`Error al obtener datos para vista ${vista_auditar}`, 'error');
// Obtener el JSON de error que devuelve Django
const errorData = await response.json();
const errorMessage = errorData.error ||
`Error ${response.status}: ${response.statusText}`;
showMessage(`No se encontró datos para auditoría: ${getVistaNombre(vista_auditar)}. Detalle: ${errorMessage}`, 'warning');
// showMessage(`Error al obtener datos para vista ${vista_auditar}`, 'error');
setDetalleModalXml(null);
return;
}
@@ -625,7 +633,14 @@ const handleAuditarEDocumentPedimento = async (pedimentoId) => {
}
};
const handleSwitchPeticion = (vista_auditar, pedimentoId) => {
const handleSwitchPeticion = (vista_auditar, pedimentoId, doc = null) => {
// Si se pasa un documento específico, úsalo
if (doc) {
previewDocument(doc);
return;
}
switch (vista_auditar) {
case 'pc':
handlePreviewPeticionPedimentoVU(pedimentoId);
@@ -655,7 +670,13 @@ const handleAuditarEDocumentPedimento = async (pedimentoId) => {
}
};
const handleSwitchRespuesta= (vista_auditar, pedimentoId) => {
const handleSwitchRespuesta= (vista_auditar, pedimentoId, doc = null) => {
if (doc) {
previewDocument(doc);
return;
}
switch (vista_auditar) {
case 'pc':
handlePreviewRespuestaPedimentoVU(pedimentoId);
@@ -1879,63 +1900,229 @@ function formatXml(xml) {
{/* Modal de Vista Previa XML */}
{showXmlModal && xmlData && (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-40">
<div className="flex flex-col w-full max-w-md p-8 bg-white border border-blue-200 shadow-2xl rounded-xl animate-fade-in">
<h3 className="mb-4 text-lg font-bold text-blue-900">{getVistaNombre(xmlData.vista)} - {xmlData.pedimento_app}</h3>
<div className="flex flex-col w-full max-w-4xl p-8 bg-white border border-blue-200 shadow-2xl rounded-xl animate-fade-in max-h-[80vh]">
<h3 className="mb-4 text-lg font-bold text-blue-900">
{getVistaNombre(xmlData.vista)} - {xmlData.pedimento_app}
</h3>
<div className="space-y-4">
<div>
<div className="space-y-4 overflow-y-auto pr-2 max-h-[60vh]">
<div className="mb-4">
<div className="mb-2"><b>Contribuyente:</b> {xmlData.contribuyente || 'N/A'}</div>
<div className="mb-2"><b>Organización:</b> {xmlData.organizacion || 'N/A'}</div>
<div className="mb-4"><b>Creado:</b> {new Date(xmlData.creado).toLocaleString('es-MX') || 'N/A'}</div>
</div>
{/* Enlace para Archivo de Petición */}
<div className="p-3 border border-gray-200 rounded-lg hover:bg-gray-50">
<div className="flex items-center justify-between">
<div>
<div className="font-medium text-gray-900">Archivo de Petición</div>
<div className="text-sm text-gray-500">XML enviado a VU</div>
{/* Si hay múltiples documentos - nueva funcionalidad para manejar listado */}
{(xmlData.documentos_peticiones || xmlData.documentos_respuestas) ? (
<>
{/* Mostrar documentos de peticiones si existen */}
{xmlData.documentos_peticiones && xmlData.documentos_peticiones.length > 0 && (
<div className="mb-6">
<details className="group">
<summary className="flex items-center justify-between p-3 font-semibold text-gray-800 list-none bg-gray-100 rounded-lg cursor-pointer hover:bg-gray-200">
<div className="flex items-center gap-2">
<svg className="w-5 h-5 text-blue-600 transition-transform group-open:rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 9l-7 7-7-7" />
</svg>
<span>Peticiones ({xmlData.total_documentos_peticiones || 0})</span>
</div>
<div className="flex items-center gap-2 text-sm font-normal text-gray-600">
<svg className="w-5 h-5 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
</svg>
<span>Click para expandir/colapsar</span>
</div>
</summary>
<div className="p-4 mt-2 space-y-3 border border-gray-200 rounded-lg">
{xmlData.documentos_peticiones.map((doc, index) => (
<div key={doc.id || index} className="p-4 transition-colors border border-gray-200 rounded-lg hover:bg-gray-50">
<div className="flex items-center justify-between mb-2">
<div className="flex-1 min-w-0">
<div className="font-medium text-gray-900 truncate">
{doc.archivo_original || `Documento ${index + 1}`}
</div>
<div className="flex items-center gap-3 mt-1 text-sm text-gray-500">
{doc.tipo && (
<span className="bg-blue-100 text-blue-800 px-2 py-0.5 rounded text-xs">
{doc.tipo}
</span>
)}
{doc.size && (
<span className="text-xs text-gray-600">
{formatFileSize(doc.size)}
</span>
)}
{doc.extension && (
<span className="text-xs text-gray-600">
{doc.extension.toUpperCase()}
</span>
)}
</div>
</div>
<div className="flex flex-col gap-2 ml-4">
<button
onClick={() => previewDocument(doc)}
className="px-3 py-1.5 text-blue-600 transition-colors rounded bg-blue-50 hover:bg-blue-100 hover:text-blue-800 text-sm whitespace-nowrap"
title="Vista previa del documento"
>
Vista Previa
</button>
</div>
</div>
{/* Información adicional del documento */}
<div className="mt-2 text-xs text-gray-500">
<div className="grid grid-cols-2 gap-2">
{doc.creado_en && (
<div>
<span className="font-medium">Creado:</span> {new Date(doc.creado_en).toLocaleString('es-MX')}
</div>
)}
{doc.actualizado_en && (
<div>
<span className="font-medium">Actualizado:</span> {new Date(doc.actualizado_en).toLocaleString('es-MX')}
</div>
)}
</div>
</div>
</div>
))}
</div>
</details>
</div>
)}
{/* Mostrar documentos de respuestas si existen */}
{xmlData.documentos_respuestas && xmlData.documentos_respuestas.length > 0 && (
<div className="mb-6">
<details className="group" >
<summary className="flex items-center justify-between p-3 font-semibold text-gray-800 list-none bg-gray-100 rounded-lg cursor-pointer hover:bg-gray-200">
<div className="flex items-center gap-2">
<svg className="w-5 h-5 text-green-600 transition-transform group-open:rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 9l-7 7-7-7" />
</svg>
<span>Respuestas ({xmlData.total_documentos_respuestas || 0})</span>
</div>
<div className="flex items-center gap-2 text-sm font-normal text-gray-600">
<svg className="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span>Click para expandir/colapsar</span>
</div>
</summary>
<div className="p-4 mt-2 space-y-3 border border-gray-200 rounded-lg">
{xmlData.documentos_respuestas.map((doc, index) => (
<div key={doc.id || index} className="p-4 transition-colors border border-gray-200 rounded-lg hover:bg-gray-50">
<div className="flex items-center justify-between mb-2">
<div className="flex-1 min-w-0">
<div className="font-medium text-gray-900 truncate">
{doc.archivo_original || `Documento ${index + 1}`}
</div>
<div className="flex items-center gap-3 mt-1 text-sm text-gray-500">
{doc.tipo && (
<span className="bg-green-100 text-green-800 px-2 py-0.5 rounded text-xs">
{doc.tipo}
</span>
)}
{doc.size && (
<span className="text-xs text-gray-600">
{formatFileSize(doc.size)}
</span>
)}
{doc.extension && (
<span className="text-xs text-gray-600">
{doc.extension.toUpperCase()}
</span>
)}
</div>
</div>
<div className="flex flex-col gap-2 ml-4">
<button
onClick={() => previewDocument(doc)}
className="px-3 py-1.5 text-green-600 transition-colors rounded bg-green-50 hover:bg-green-100 hover:text-green-800 text-sm whitespace-nowrap"
title="Vista previa del documento"
>
Vista Previa
</button>
</div>
</div>
{/* Información adicional del documento */}
<div className="mt-2 text-xs text-gray-500">
<div className="grid grid-cols-2 gap-2">
{doc.creado_en && (
<div>
<span className="font-medium">Creado:</span> {new Date(doc.creado_en).toLocaleString('es-MX')}
</div>
)}
{doc.actualizado_en && (
<div>
<span className="font-medium">Actualizado:</span> {new Date(doc.actualizado_en).toLocaleString('es-MX')}
</div>
)}
</div>
</div>
</div>
))}
</div>
</details>
</div>
)}
</>
) : (
/* Para compatibilidad hacia atrás - caso de un solo documento */
<>
{/* Enlace para Archivo de Petición */}
<div className="p-3 border border-gray-200 rounded-lg hover:bg-gray-50">
<div className="flex items-center justify-between">
<div>
<div className="font-medium text-gray-900">Archivo de Petición</div>
<div className="text-sm text-gray-500">XML enviado a VU</div>
</div>
<button
onClick={() => handleSwitchPeticion(xmlData.vista, xmlData.id)}
className="px-3 py-1 text-blue-600 transition-colors rounded bg-blue-50 hover:bg-blue-100 hover:text-blue-800"
>
Vista Previa
</button>
</div>
</div>
<button
onClick={() => handleSwitchPeticion(xmlData.vista,xmlData.id)}
className="px-3 py-1 text-blue-600 transition-colors rounded bg-blue-50 hover:bg-blue-100 hover:text-blue-800"
>
Vista Previa
</button>
</div>
</div>
{/* Enlace para Archivo de Respuesta */}
<div className="p-3 border border-gray-200 rounded-lg hover:bg-gray-50">
<div className="flex items-center justify-between">
<div>
<div className="font-medium text-gray-900">Archivo de Respuesta</div>
<div className="text-sm text-gray-500">XML recibido de VU</div>
{/* Enlace para Archivo de Respuesta */}
<div className="p-3 border border-gray-200 rounded-lg hover:bg-gray-50">
<div className="flex items-center justify-between">
<div>
<div className="font-medium text-gray-900">Archivo de Respuesta</div>
<div className="text-sm text-gray-500">XML recibido de VU</div>
</div>
<button
onClick={() => handleSwitchRespuesta(xmlData.vista, xmlData.id)}
className="px-3 py-1 text-green-600 transition-colors rounded bg-green-50 hover:bg-green-100 hover:text-green-800"
>
Vista Previa
</button>
</div>
</div>
<button
onClick={() => handleSwitchRespuesta(xmlData.vista, xmlData.id)}
className="px-3 py-1 text-green-600 transition-colors rounded bg-green-50 hover:bg-green-100 hover:text-green-800"
>
Vista Previa
</button>
</div>
</div>
</>
)}
{/* Botón para ver datos crudos (opcional) */}
<details className="mt-4">
{/* <details className="mt-4">
<summary className="px-3 py-2 text-sm text-gray-600 bg-gray-100 rounded cursor-pointer hover:bg-gray-200">
Ver datos completos
</summary>
<pre className="p-3 mt-2 overflow-auto text-xs bg-gray-100 border border-gray-300 rounded max-h-60">
{JSON.stringify(xmlData, null, 2)}
</pre>
</details>
</details> */}
</div>
<div className="flex justify-end gap-2 mt-6">
<button
onClick={() => setShowXmlModal(false)}
className="px-4 py-2 text-gray-700 transition-colors bg-gray-100 rounded hover:bg-gray-200"
className="w-full px-4 py-3 font-medium text-gray-700 transition-colors bg-gray-100 rounded-lg hover:bg-gray-200"
>
Cerrar
</button>
@@ -1943,6 +2130,7 @@ function formatXml(xml) {
</div>
</div>
)}
{/* Modal de vista previa mejorado */}
{previewOpen && (