Nuevos Ajustes en la vista de modal de Peticiones y Respuestas
This commit is contained in:
@@ -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 && (
|
||||
|
||||
Reference in New Issue
Block a user