From e73309edb6f75394872b435be0063e8f0d5cb6ab Mon Sep 17 00:00:00 2001 From: acazares Date: Tue, 18 Nov 2025 16:20:39 -0600 Subject: [PATCH] feat: Add sub-resource interfaces for Pedimento and unify API calls in edit page --- .../src/lib/api/dashboard/a76/pedimentos.ts | 38 ++++ .../pedimentos/edit/[id]/+page.svelte | 175 ++++++++---------- 2 files changed, 115 insertions(+), 98 deletions(-) diff --git a/frontend/src/lib/api/dashboard/a76/pedimentos.ts b/frontend/src/lib/api/dashboard/a76/pedimentos.ts index 875a3d56..4532022a 100644 --- a/frontend/src/lib/api/dashboard/a76/pedimentos.ts +++ b/frontend/src/lib/api/dashboard/a76/pedimentos.ts @@ -4,6 +4,29 @@ */ import { api } from '$lib/api'; +// Sub-resource interfaces +export interface PedimentoDates { + entry_date?: string | null; + pedimento_date?: string | null; + payment_date?: string | null; +} + +export interface PedimentoPayments { + payment_form?: string | null; + bank_identifier?: string | null; +} + +export interface PedimentoTransportMeans { + arrival_key?: string | null; + arrival_data?: string | null; + departure_key?: string | null; + departure_data?: string | null; +} + +export interface PedimentoValidation { + document?: string | null; +} + export interface Pedimento { id: number; tenant_id: number; @@ -22,6 +45,11 @@ export interface Pedimento { gross_weight?: number | null; exchange_rate?: number | null; created_at: string; + // Sub-resources + pedimento_dates?: PedimentoDates | null; + pedimento_payments?: PedimentoPayments | null; + pedimento_transport_means?: PedimentoTransportMeans | null; + pedimento_validation?: PedimentoValidation | null; } export interface PedimentoListResponse { @@ -46,6 +74,11 @@ export interface CreatePedimentoData { paid_price?: number | null; gross_weight?: number | null; exchange_rate?: number | null; + // Sub-resources + pedimento_dates?: PedimentoDates | null; + pedimento_payments?: PedimentoPayments | null; + pedimento_transport_means?: PedimentoTransportMeans | null; + pedimento_validation?: PedimentoValidation | null; } export interface UpdatePedimentoData { @@ -63,6 +96,11 @@ export interface UpdatePedimentoData { paid_price?: number | null; gross_weight?: number | null; exchange_rate?: number | null; + // Sub-resources + pedimento_dates?: PedimentoDates | null; + pedimento_payments?: PedimentoPayments | null; + pedimento_transport_means?: PedimentoTransportMeans | null; + pedimento_validation?: PedimentoValidation | null; } export interface PedimentoFilters { diff --git a/frontend/src/routes/dashboard/pedimentos/edit/[id]/+page.svelte b/frontend/src/routes/dashboard/pedimentos/edit/[id]/+page.svelte index 03dead17..7d30ef2c 100644 --- a/frontend/src/routes/dashboard/pedimentos/edit/[id]/+page.svelte +++ b/frontend/src/routes/dashboard/pedimentos/edit/[id]/+page.svelte @@ -16,12 +16,8 @@ import TransportTabForm from '$lib/components/dashboard/pedimentos/edit/transport-tab-form.svelte'; import ValidationTabForm from '$lib/components/dashboard/pedimentos/edit/validation-tab-form.svelte'; - // Importar las APIs + // Importar solo la API de pedimentos import { pedimentosApi, type CreatePedimentoData, type UpdatePedimentoData } from '$lib/api/dashboard/a76/pedimentos'; - import { pedimentoDatesApi, type UpdatePedimentoDatesData, type CreatePedimentoDatesData } from '$lib/api/dashboard/a76/pedimento-dates'; - import { pedimentoPaymentsApi, type UpdatePedimentoPaymentsData, type CreatePedimentoPaymentsData } from '$lib/api/dashboard/a76/pedimento-payments'; - import { pedimentoTransportApi, type UpdatePedimentoTransportMeansData, type CreatePedimentoTransportMeansData } from '$lib/api/dashboard/a76/pedimento-transport'; - import { pedimentoValidationApi, type UpdatePedimentoValidationData, type CreatePedimentoValidationData } from '$lib/api/dashboard/a76/pedimento-validation'; let { data }: { data: PageData } = $props(); @@ -30,7 +26,7 @@ let error = $state(null); let success = $state(false); - // ID del pedimento - se usa para crear sub-recursos después de crear el pedimento + // ID del pedimento let pedimentoId = $state(data.pedimentoId); // Referencias a los componentes de formulario para obtener sus datos @@ -40,7 +36,7 @@ let transportFormData = $state(null); let validationFormData = $state(null); - // Estados para saber si existen datos previos + // Estados para saber si existen datos previos (para compatibilidad con componentes hijos) let datesExists = $state(false); let paymentsExists = $state(false); let transportExists = $state(false); @@ -70,114 +66,97 @@ success = false; try { - let pedimentoId = data.pedimentoId; - - // 1. Crear o actualizar datos generales - if (generalFormData) { - const payload = { - year: generalFormData.year || null, - customs_office: generalFormData.customs_office || null, - license: generalFormData.license || null, - pedimento_number: generalFormData.pedimento_number || null, - client_id: generalFormData.client_id, - operation_type: generalFormData.operation_type, - pedimento_type: generalFormData.pedimento_type, - pedimento_code: generalFormData.pedimento_code || null, - regime: generalFormData.regime || null, - status: generalFormData.status || null, - usd_value: generalFormData.usd_value, - paid_price: generalFormData.paid_price, - gross_weight: generalFormData.gross_weight, - exchange_rate: generalFormData.exchange_rate + // Validar campos requeridos para creación + if (data.isCreate && generalFormData) { + const requiredFields = { + year: 'Año', + customs_office: 'Aduana', + license: 'Patente', + pedimento_number: 'Número de Pedimento', + client_id: 'ID del Cliente', + operation_type: 'Tipo de Operación', + pedimento_type: 'Tipo de Pedimento', + regime: 'Régimen', + status: 'Estado' }; - if (data.isCreate) { - // Crear nuevo pedimento - const response = await pedimentosApi.create(payload); - if (response.error) throw new Error(response.error); - if (!response.data?.id) throw new Error('No se recibió el ID del pedimento creado'); - pedimentoId = response.data.id; - } else { - // Actualizar pedimento existente - const response = await pedimentosApi.update(pedimentoId!, payload); - if (response.error) throw new Error(response.error); + const missingFields: string[] = []; + for (const [field, label] of Object.entries(requiredFields)) { + const value = (generalFormData as any)[field]; + if (value === null || value === undefined || value === '') { + missingFields.push(label); + } + } + + if (missingFields.length > 0) { + throw new Error(`Los siguientes campos son obligatorios: ${missingFields.join(', ')}`); } } - // 2. Guardar fechas - if (datesFormData && (datesFormData.entry_date || datesFormData.pedimento_date || datesFormData.payment_date)) { - const payload = { + // Construir el payload unificado + const payload: CreatePedimentoData | UpdatePedimentoData = { + // Datos generales + year: generalFormData?.year || undefined, + customs_office: generalFormData?.customs_office || undefined, + license: generalFormData?.license || undefined, + pedimento_number: generalFormData?.pedimento_number || undefined, + client_id: generalFormData?.client_id || undefined, + operation_type: generalFormData?.operation_type || undefined, + pedimento_type: generalFormData?.pedimento_type || undefined, + pedimento_code: generalFormData?.pedimento_code || undefined, + regime: generalFormData?.regime || undefined, + status: generalFormData?.status || undefined, + usd_value: generalFormData?.usd_value || undefined, + paid_price: generalFormData?.paid_price || undefined, + gross_weight: generalFormData?.gross_weight || undefined, + exchange_rate: generalFormData?.exchange_rate || undefined, + // Sub-recursos + pedimento_dates: (datesFormData?.entry_date || datesFormData?.pedimento_date || datesFormData?.payment_date) ? { entry_date: datesFormData.entry_date || null, pedimento_date: datesFormData.pedimento_date || null, payment_date: datesFormData.payment_date || null - }; - - if (datesExists && !data.isCreate) { - const response = await pedimentoDatesApi.update(pedimentoId!, payload as UpdatePedimentoDatesData); - if (response.error && response.status !== 404) throw new Error(response.error); - } else { - const response = await pedimentoDatesApi.create(pedimentoId!, payload as CreatePedimentoDatesData); - if (response.error) throw new Error(response.error); - datesExists = true; - } - } - - // 3. Guardar pagos - if (paymentsFormData && (paymentsFormData.payment_form || paymentsFormData.bank_identifier)) { - const payload = { + } : undefined, + pedimento_payments: (paymentsFormData?.payment_form || paymentsFormData?.bank_identifier) ? { payment_form: paymentsFormData.payment_form || null, bank_identifier: paymentsFormData.bank_identifier || null - }; - - if (paymentsExists && !data.isCreate) { - const response = await pedimentoPaymentsApi.update(pedimentoId!, payload as UpdatePedimentoPaymentsData); - if (response.error && response.status !== 404) throw new Error(response.error); - } else { - const response = await pedimentoPaymentsApi.create(pedimentoId!, payload as CreatePedimentoPaymentsData); - if (response.error) throw new Error(response.error); - paymentsExists = true; - } - } - - // 4. Guardar transporte - if (transportFormData && (transportFormData.arrival_key || transportFormData.arrival_data || transportFormData.departure_key || transportFormData.departure_data)) { - const payload = { + } : undefined, + pedimento_transport_means: (transportFormData?.arrival_key || transportFormData?.arrival_data || transportFormData?.departure_key || transportFormData?.departure_data) ? { arrival_key: transportFormData.arrival_key || null, arrival_data: transportFormData.arrival_data || null, departure_key: transportFormData.departure_key || null, departure_data: transportFormData.departure_data || null - }; - - if (transportExists && !data.isCreate) { - const response = await pedimentoTransportApi.update(pedimentoId!, payload as UpdatePedimentoTransportMeansData); - if (response.error && response.status !== 404) throw new Error(response.error); - } else { - const response = await pedimentoTransportApi.create(pedimentoId!, payload as CreatePedimentoTransportMeansData); - if (response.error) throw new Error(response.error); - transportExists = true; - } - } - - // 5. Guardar validación - if (validationFormData && validationFormData.document) { - const payload = { + } : undefined, + pedimento_validation: validationFormData?.document ? { document: validationFormData.document || null - }; - - if (validationExists && !data.isCreate) { - const response = await pedimentoValidationApi.update(pedimentoId!, payload as UpdatePedimentoValidationData); - if (response.error && response.status !== 404) throw new Error(response.error); - } else { - const response = await pedimentoValidationApi.create(pedimentoId!, payload as CreatePedimentoValidationData); - if (response.error) throw new Error(response.error); - validationExists = true; - } - } + } : undefined + }; - // Si fue una creación, redirigir a la página de edición - if (data.isCreate && pedimentoId) { - await goto(`/dashboard/pedimentos/edit/${pedimentoId}`); + // Eliminar campos undefined para no enviarlos + Object.keys(payload).forEach(key => { + if (payload[key as keyof typeof payload] === undefined) { + delete payload[key as keyof typeof payload]; + } + }); + + let newPedimentoId = pedimentoId; + + if (data.isCreate) { + // Crear nuevo pedimento con todos sus sub-recursos + const response = await pedimentosApi.create(payload as CreatePedimentoData); + if (response.error) { + const errorMsg = typeof response.error === 'string' ? response.error : 'Error al crear el pedimento'; + throw new Error(errorMsg); + } + if (!response.data?.id) throw new Error('No se recibió el ID del pedimento creado'); + newPedimentoId = response.data.id; + + // Redirigir a la página de edición + await goto(`/dashboard/pedimentos/edit/${newPedimentoId}`); return; + } else { + // Actualizar pedimento existente con todos sus sub-recursos + const response = await pedimentosApi.update(pedimentoId!, payload as UpdatePedimentoData); + if (response.error) throw new Error(response.error); } success = true;