Merge pull request 'fix/generacion-xml-nuevos' (#472) from fix/generacion-xml-nuevos into development

Reviewed-on: ADUANASOFT/anexo76#472
This commit is contained in:
2026-06-02 17:17:09 +00:00
4 changed files with 43 additions and 224 deletions

1
.gitignore vendored
View File

@@ -82,3 +82,4 @@ backend/celerybeat-schedule
celerybeat-schedule celerybeat-schedule
celerybeat-schedule.* celerybeat-schedule.*
celerybeat.pid celerybeat.pid
backend/api/v1/modules/reports/generated/

View File

@@ -1,247 +1,64 @@
import { api } from '$lib/api';
const BASE_URL = import.meta.env.VITE_API_URL || '';
export const reportsTransmissionApi = { export const reportsTransmissionApi = {
triggerGeneration: async (request: any) => { triggerGeneration: async (request: any) => {
const endpoint = `${BASE_URL}/v1/a76/reports/exportacion/transmission/generate`; const result = await api.post('/v1/a76/reports/exportacion/transmission/generate', request);
if (result.error || !result.data) throw new Error(result.error || 'Error al iniciar la generación del archivo de transmisión');
const token = localStorage.getItem('access_token'); return result.data;
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
});
if (!response.ok) {
let errorMessage = 'Error al iniciar la generación del archivo de transmisión';
try {
const errorData = await response.json();
errorMessage = errorData.detail || errorData.message || errorMessage;
} catch (e) {
try {
const text = await response.text();
if (text) errorMessage = text;
} catch (e2) {}
}
throw new Error(errorMessage);
}
return await response.json();
}, },
getTaskStatus: async (taskId: string) => { getTaskStatus: async (taskId: string) => {
const endpoint = `${BASE_URL}/v1/a76/reports/exportacion/transmission/tasks/${taskId}`; const result = await api.get(`/v1/a76/reports/exportacion/transmission/tasks/${taskId}`);
if (result.error || !result.data) throw new Error(result.error || 'Error al consultar estado de la transmisión');
const token = localStorage.getItem('access_token'); return result.data;
const response = await fetch(endpoint, {
method: 'GET',
headers: { 'Authorization': `Bearer ${token}` }
});
if (!response.ok) {
let errorMessage = 'Error al consultar estado de la transmisión';
try {
const errorData = await response.json();
errorMessage = errorData.detail || errorData.message || errorMessage;
} catch (e) {
try {
const text = await response.text();
if (text) errorMessage = text;
} catch (e2) {}
}
throw new Error(errorMessage);
}
return await response.json();
}, },
triggerTemporalGeneration: async (request: any) => { triggerTemporalGeneration: async (request: any) => {
const endpoint = `${BASE_URL}/v1/a76/reports/importacion/transmission/temporal/generate`; const result = await api.post('/v1/a76/reports/importacion/transmission/temporal/generate', request);
if (result.error || !result.data) throw new Error(result.error || 'Error al iniciar la generación temporal');
const token = localStorage.getItem('access_token'); return result.data;
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
});
if (!response.ok) {
let errorMessage = 'Error al iniciar la generación temporal';
try {
const errorData = await response.json();
errorMessage = errorData.detail || errorData.message || errorMessage;
} catch (e) {
try {
const text = await response.text();
if (text) errorMessage = text;
} catch (e2) {}
}
throw new Error(errorMessage);
}
return await response.json();
}, },
getTemporalTaskStatus: async (taskId: string) => { getTemporalTaskStatus: async (taskId: string) => {
const endpoint = `${BASE_URL}/v1/a76/reports/importacion/transmission/temporal/tasks/${taskId}`; const result = await api.get(`/v1/a76/reports/importacion/transmission/temporal/tasks/${taskId}`);
if (result.error || !result.data) throw new Error(result.error || 'Error al consultar estado de la transmisión temporal');
const token = localStorage.getItem('access_token'); return result.data;
const response = await fetch(endpoint, {
method: 'GET',
headers: { 'Authorization': `Bearer ${token}` }
});
if (!response.ok) {
let errorMessage = 'Error al consultar estado de la transmisión temporal';
try {
const errorData = await response.json();
errorMessage = errorData.detail || errorData.message || errorMessage;
} catch (e) {
try {
const text = await response.text();
if (text) errorMessage = text;
} catch (e2) {}
}
throw new Error(errorMessage);
}
return await response.json();
}, },
triggerDefinitiveGeneration: async (request: any) => { triggerDefinitiveGeneration: async (request: any) => {
const endpoint = `${BASE_URL}/v1/a76/reports/importacion/transmission/definitive/generate`; const result = await api.post('/v1/a76/reports/importacion/transmission/definitive/generate', request);
if (result.error || !result.data) throw new Error(result.error || 'Error al iniciar la generación definitiva');
const token = localStorage.getItem('access_token'); return result.data;
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
});
if (!response.ok) {
let errorMessage = 'Error al iniciar la generación definitiva';
try {
const errorData = await response.json();
errorMessage = errorData.detail || errorData.message || errorMessage;
} catch (e) {
try {
const text = await response.text();
if (text) errorMessage = text;
} catch (e2) {}
}
throw new Error(errorMessage);
}
return await response.json();
}, },
getDefinitiveTaskStatus: async (taskId: string) => { getDefinitiveTaskStatus: async (taskId: string) => {
const endpoint = `${BASE_URL}/v1/a76/reports/importacion/transmission/definitive/tasks/${taskId}`; const result = await api.get(`/v1/a76/reports/importacion/transmission/definitive/tasks/${taskId}`);
if (result.error || !result.data) throw new Error(result.error || 'Error al consultar estado de la transmisión definitiva');
const token = localStorage.getItem('access_token'); return result.data;
const response = await fetch(endpoint, {
method: 'GET',
headers: { 'Authorization': `Bearer ${token}` }
});
if (!response.ok) {
let errorMessage = 'Error al consultar estado de la transmisión definitiva';
try {
const errorData = await response.json();
errorMessage = errorData.detail || errorData.message || errorMessage;
} catch (e) {
try {
const text = await response.text();
if (text) errorMessage = text;
} catch (e2) {}
}
throw new Error(errorMessage);
}
return await response.json();
}, },
triggerXmlRbSystemsImpoTemp: async (request: { invoice_numbers: string[]; entry_port?: string; exit_port?: string }) => { triggerXmlRbSystemsImpoTemp: async (request: { invoice_numbers: string[]; entry_port?: string; exit_port?: string }) => {
const endpoint = `${BASE_URL}/v1/a76/reports/xml-rb-systems/importacion-temporal/generate`; const result = await api.post('/v1/a76/reports/xml-rb-systems/importacion-temporal/generate', request);
const token = localStorage.getItem('access_token'); if (result.error || !result.data) throw new Error(result.error || 'Error al generar XML RB Systems (importación temporal)');
const response = await fetch(endpoint, { return result.data;
method: 'POST',
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify(request)
});
if (!response.ok) {
let errorMessage = 'Error al generar XML RB Systems (importación temporal)';
try { errorMessage = (await response.json()).detail || errorMessage; } catch (e) {}
throw new Error(errorMessage);
}
return await response.json();
}, },
triggerXmlRbSystemsImpoDef: async (request: { invoice_numbers: string[]; entry_port?: string; exit_port?: string }) => { triggerXmlRbSystemsImpoDef: async (request: { invoice_numbers: string[]; entry_port?: string; exit_port?: string }) => {
const endpoint = `${BASE_URL}/v1/a76/reports/xml-rb-systems/importacion-definitiva/generate`; const result = await api.post('/v1/a76/reports/xml-rb-systems/importacion-definitiva/generate', request);
const token = localStorage.getItem('access_token'); if (result.error || !result.data) throw new Error(result.error || 'Error al generar XML RB Systems (importación definitiva)');
const response = await fetch(endpoint, { return result.data;
method: 'POST',
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify(request)
});
if (!response.ok) {
let errorMessage = 'Error al generar XML RB Systems (importación definitiva)';
try { errorMessage = (await response.json()).detail || errorMessage; } catch (e) {}
throw new Error(errorMessage);
}
return await response.json();
}, },
triggerXmlRbSystemsImpo: async (request: { invoice_numbers: string[]; entry_port?: string; exit_port?: string }) => { triggerXmlRbSystemsExpo: async (request: { manifest_numbers: string[]; include_emanifest?: boolean }) => {
const endpoint = `${BASE_URL}/v1/a76/reports/xml-rb-systems/importacion/generate`; const result = await api.post('/v1/a76/reports/xml-rb-systems/exportacion/generate', request);
const token = localStorage.getItem('access_token'); if (result.error || !result.data) throw new Error(result.error || 'Error al generar XML RB Systems (exportación)');
const response = await fetch(endpoint, { return result.data;
method: 'POST',
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify(request)
});
if (!response.ok) {
let errorMessage = 'Error al generar XML RB Systems (importación)';
try { errorMessage = (await response.json()).detail || errorMessage; } catch (e) {}
throw new Error(errorMessage);
}
return await response.json();
},
triggerXmlRbSystemsExpo: async (request: { manifest_numbers: string[]; entry_port?: string; exit_port?: string; include_emanifest?: boolean }) => {
const endpoint = `${BASE_URL}/v1/a76/reports/xml-rb-systems/exportacion/generate`;
const token = localStorage.getItem('access_token');
const response = await fetch(endpoint, {
method: 'POST',
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify(request)
});
if (!response.ok) {
let errorMessage = 'Error al generar XML RB Systems (exportación)';
try { errorMessage = (await response.json()).detail || errorMessage; } catch (e) {}
throw new Error(errorMessage);
}
return await response.json();
}, },
triggerXmlOptimaExpo: async (request: { manifest_numbers: string[]; consolidar_partidas?: boolean }) => { triggerXmlOptimaExpo: async (request: { manifest_numbers: string[]; consolidar_partidas?: boolean }) => {
const endpoint = `${BASE_URL}/v1/a76/reports/xml-optima/exportacion/generate`; const result = await api.post('/v1/a76/reports/xml-optima/exportacion/generate', request);
const token = localStorage.getItem('access_token'); if (result.error || !result.data) throw new Error(result.error || 'Error al generar XML Optima (exportación)');
const response = await fetch(endpoint, { return result.data;
method: 'POST',
headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' },
body: JSON.stringify(request)
});
if (!response.ok) {
let errorMessage = 'Error al generar XML Optima (exportación)';
try { errorMessage = (await response.json()).detail || errorMessage; } catch (e) {}
throw new Error(errorMessage);
}
return await response.json();
} }
}; };

View File

@@ -1,5 +1,6 @@
<script lang="ts"> <script lang="ts">
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { browser } from '$app/environment';
import { companyStore } from '$lib/stores/company.svelte'; import { companyStore } from '$lib/stores/company.svelte';
import { uiStore } from '$lib/stores/ui.svelte'; import { uiStore } from '$lib/stores/ui.svelte';
import { getExchangeRates } from '$lib/api/dashboard/a76/general_catalogs/exchange-rate'; import { getExchangeRates } from '$lib/api/dashboard/a76/general_catalogs/exchange-rate';
@@ -69,4 +70,6 @@
}); });
</script> </script>
<CreateEditDialog bind:open onSuccess={handleSuccess} {overlayClass} /> {#if browser}
<CreateEditDialog bind:open onSuccess={handleSuccess} {overlayClass} />
{/if}

View File

@@ -129,13 +129,13 @@
// --- XML_RB_SYSTEMS --- // --- XML_RB_SYSTEMS ---
if (interfaceType === 'XML_RB_SYSTEMS') { if (interfaceType === 'XML_RB_SYSTEMS') {
if (!entryPort || !exitPort) {
toast.error('Debe seleccionar tanto el puerto de entrada como el de salida');
return;
}
try { try {
let res; let res;
if (movementType === 'Importacion') { if (movementType === 'Importacion') {
if (!entryPort || !exitPort) {
toast.error('Debe seleccionar tanto el puerto de entrada como el de salida');
return;
}
const validInvoices = manualInvoices.filter((i) => i && i.trim() !== ''); const validInvoices = manualInvoices.filter((i) => i && i.trim() !== '');
if (validInvoices.length === 0) { if (validInvoices.length === 0) {
toast.error('Debe seleccionar al menos una factura'); toast.error('Debe seleccionar al menos una factura');
@@ -156,8 +156,6 @@
} }
res = await reportsTransmissionApi.triggerXmlRbSystemsExpo({ res = await reportsTransmissionApi.triggerXmlRbSystemsExpo({
manifest_numbers: validManifests, manifest_numbers: validManifests,
entry_port: entryPort,
exit_port: exitPort,
include_emanifest: !checks.no_enviar_emanifest include_emanifest: !checks.no_enviar_emanifest
}); });
} }
@@ -494,8 +492,8 @@
{/if} {/if}
</div> </div>
<!-- Ports Selection (Importacion y XML_RB_SYSTEMS) --> <!-- Ports Selection: solo para Importacion (expo XML_RB_SYSTEMS toma puertos del manifiesto) -->
{#if movementType === 'Importacion' || interfaceType === 'XML_RB_SYSTEMS'} {#if movementType === 'Importacion'}
<div class="mt-2 grid grid-cols-2 gap-4"> <div class="mt-2 grid grid-cols-2 gap-4">
<div class="space-y-2"> <div class="space-y-2">
<Label>Puerto Entrada</Label> <Label>Puerto Entrada</Label>