feature/csv-expo

This commit is contained in:
hreyes
2026-03-05 12:01:24 -07:00
parent 9c3e6827da
commit 0dfb7d2237
10 changed files with 477 additions and 5 deletions

View File

@@ -360,6 +360,40 @@ export const api = {
api.post(`/v1/a76/imports/${jobId}/commit`, { model_target: modelTarget })
},
// CSV import for Operaciones de Exportación (encabezado y partidas).
// Backend: layouts_csv/exportacion — rutas /v1/a76/imports/exportacion/
exportacionImports: {
upload: (
file: File,
modelTarget: string,
footerConfig: any,
companyId: number,
templateId?: string
) => {
const formData = new FormData();
formData.append('file', file);
if (footerConfig) {
formData.append('footer_config', JSON.stringify(footerConfig));
}
if (templateId) {
formData.append('template_id', templateId);
}
const queryParams = new URLSearchParams({
company_id: String(companyId),
operation_type: 'exp'
}).toString();
return fetchApi(`/v1/a76/imports/exportacion/upload/${modelTarget}?${queryParams}`, {
method: 'POST',
body: formData
});
},
status: (jobId: string) => api.get(`/v1/a76/imports/exportacion/${jobId}/status`),
commit: (jobId: string, modelTarget: string) =>
api.post(`/v1/a76/imports/exportacion/${jobId}/commit`, { model_target: modelTarget })
},
// CSV import for Agentes Aduanales (flujo propio en customs_brokers/imports)
customsBrokerImports: {
upload: (file: File, companyId: number) => {

View File

@@ -412,7 +412,7 @@ export const importacionConfig: CsvUploadItem[] = [
];
// --- Operaciones de Exportación (facturas: encabezados y partidas)
// Backend: layouts_csv/facturas — mismas rutas /v1/a76/imports/ con operation_type=exp.
// Backend: layouts_csv/exportacion — rutas /v1/a76/imports/exportacion/
export const exportacionConfig: CsvUploadItem[] = [
// Expo Def / Cam. Reg.
{
@@ -422,7 +422,7 @@ export const exportacionConfig: CsvUploadItem[] = [
group: 'Expo. Def./Cam. Reg.',
modelTarget: 'invoice_header',
templateId: 'exp_def_header',
layoutModule: 'layouts_csv/facturas'
layoutModule: 'layouts_csv/exportacion'
},
{
id: 'exp_def_details',
@@ -431,7 +431,7 @@ export const exportacionConfig: CsvUploadItem[] = [
group: 'Expo. Def./Cam. Reg.',
modelTarget: 'invoice_details',
templateId: 'exp_def_details',
layoutModule: 'layouts_csv/facturas'
layoutModule: 'layouts_csv/exportacion'
},
{
id: 'exp_def_series',

View File

@@ -81,6 +81,8 @@
let usePartNumbersImport = $state(false);
// Cuando es true, usamos API de importación de BOMs (boms/imports)
let useBomImport = $state(false);
// Cuando es true, usamos API de importación de Exportación (layouts_csv/exportacion)
let useExportacionImport = $state(false);
// Initialize settings for all tabs upfront to avoid reactivity loops (sync init so child never receives undefined)
const _initialSettings: Record<string, any> = {};
@@ -135,6 +137,7 @@
useTransporterImport = config.id === 'transporters';
usePartNumbersImport = config.id === 'part_numbers';
useBomImport = config.id === 'boms';
useExportacionImport = activeTab === 'exportacion';
const companyId = companyStore.activeCompany?.id || 1;
@@ -388,6 +391,31 @@
if (activeTab === 'importacion') {
footerConfig.invoice_type = config.id?.startsWith('imp_def_') ? 'DEF' : 'TEM';
}
if (useExportacionImport) {
try {
const res = await api.exportacionImports.upload(
file,
config.modelTarget || '',
footerConfig,
companyId,
config.templateId || config.id
);
if (res.data?.job_id) {
currentJobId = res.data.job_id;
pollStatus();
} else {
toast.error(res.error || 'Error al subir el archivo');
isUploading = false;
}
} catch (e) {
console.error('Upload exception', e);
toast.error('Error inesperado al subir el archivo');
isUploading = false;
}
return;
}
const opType = activeTab === 'exportacion' ? 'exp' : 'imp';
try {
@@ -441,7 +469,9 @@
? await api.partNumberImports.status(currentJobId)
: useBomImport
? await api.bomImports.status(currentJobId)
: await api.imports.status(currentJobId);
: useExportacionImport
? await api.exportacionImports.status(currentJobId)
: await api.imports.status(currentJobId);
console.log('Poll response', res);
if (res.error && !res.data) {
toast.error(res.error || 'Error al consultar el estado');
@@ -660,7 +690,9 @@
? await api.partNumberImports.commit(currentJobId)
: useBomImport
? await api.bomImports.commit(currentJobId)
: await api.imports.commit(currentJobId, activeModelTarget || '');
: useExportacionImport
? await api.exportacionImports.commit(currentJobId, activeModelTarget || '')
: await api.imports.commit(currentJobId, activeModelTarget || '');
if (res.data?.commit_job_id) {
currentJobId = res.data.commit_job_id;
pollStatus();