From 72db67e1610c6af26b4f7db7ae4a4e4ff40065b2 Mon Sep 17 00:00:00 2001 From: Galindo97 Date: Wed, 25 Feb 2026 11:41:35 -0600 Subject: [PATCH] feat: Introduce customs office and transport means fields to pedimento data models and forms. --- .../modules/a76/pedmientos/catalog_service.py | 18 ++ .../api/v1/modules/a76/pedmientos/schemas.py | 4 + .../src/lib/api/dashboard/a76/pedimentos.ts | 8 + .../pedimentos/edit/general-tab-form.svelte | 170 ++++++++++++++++-- .../pedimentos/edit/[id]/+page.server.ts | 12 +- .../pedimentos/edit/[id]/+page.svelte | 42 ++++- 6 files changed, 231 insertions(+), 23 deletions(-) diff --git a/backend/api/v1/modules/a76/pedmientos/catalog_service.py b/backend/api/v1/modules/a76/pedmientos/catalog_service.py index 13b4a01e..cc0dd1ab 100644 --- a/backend/api/v1/modules/a76/pedmientos/catalog_service.py +++ b/backend/api/v1/modules/a76/pedmientos/catalog_service.py @@ -6,6 +6,8 @@ from sqlalchemy.orm import Session from api.v1.modules.public.reference_data.pedimento_codes.models import PedimentoCode from api.v1.modules.public.reference_data.customs_sections.models import CustomsSection from api.v1.modules.public.reference_data.code_pedimento_regimens.models import CodePedimentoRegimen +from api.v1.modules.public.reference_data.transport_types.models import TransportType +from api.v1.modules.public.reference_data.transport_modes.models import TransportMode # Import A76 Services from api.v1.modules.a76.customs_brokers.services import CustomsBrokerService @@ -15,6 +17,8 @@ from api.v1.modules.a76.clients_and_providers.service import ClientProviderServi from api.v1.modules.public.reference_data.pedimento_codes.dto import PedimentoCodeDTO from api.v1.modules.public.reference_data.customs_sections.dto import CustomsSectionDTO from api.v1.modules.public.reference_data.code_pedimento_regimens.dto import CodePedimentoRegimenDTO +from api.v1.modules.public.reference_data.transport_types.dto import TransportTypeDTO +from api.v1.modules.public.reference_data.transport_modes.dto import TransportModeDTO from api.v1.modules.a76.customs_brokers.dto import CustomsBrokerResponseDTO from api.v1.modules.a76.clients_and_providers.dto import ClientProviderResponseDTO from .dtos.pedimentos import PedimentosResponse @@ -53,6 +57,20 @@ class PedimentoCatalogService: except Exception as e: print(f"Error fetching code_pedimento_regimens: {e}") + try: + response.transport_types = [ + TransportTypeDTO.model_validate(obj) for obj in db.query(TransportType).limit(200).all() + ] + except Exception as e: + print(f"Error fetching transport_types: {e}") + + try: + response.transport_modes = [ + TransportModeDTO.model_validate(obj) for obj in db.query(TransportMode).limit(100).all() + ] + except Exception as e: + print(f"Error fetching transport_modes: {e}") + # Helper to fetch tenant/company specific data def fetch_tenant_data(): # Customs Brokers diff --git a/backend/api/v1/modules/a76/pedmientos/schemas.py b/backend/api/v1/modules/a76/pedmientos/schemas.py index aeec5ee3..8eec714e 100644 --- a/backend/api/v1/modules/a76/pedmientos/schemas.py +++ b/backend/api/v1/modules/a76/pedmientos/schemas.py @@ -11,6 +11,8 @@ from api.v1.modules.public.reference_data.customs_sections.dto import CustomsSec from api.v1.modules.public.reference_data.code_pedimento_regimens.dto import CodePedimentoRegimenDTO from api.v1.modules.a76.customs_brokers.dto import CustomsBrokerResponseDTO from api.v1.modules.a76.clients_and_providers.dto import ClientProviderResponseDTO +from api.v1.modules.public.reference_data.transport_types.dto import TransportTypeDTO +from api.v1.modules.public.reference_data.transport_modes.dto import TransportModeDTO from .dtos.pedimentos import PedimentosResponse @@ -22,6 +24,8 @@ class PedimentoCatalogsResponse(BaseModel): code_pedimento_regimens: List[CodePedimentoRegimenDTO] = [] customs_brokers: List[CustomsBrokerResponseDTO] = [] clients: List[ClientProviderResponseDTO] = [] + transport_types: List[TransportTypeDTO] = [] + transport_modes: List[TransportModeDTO] = [] class PedimentoCreationResponse(PedimentoCatalogsResponse): diff --git a/frontend/src/lib/api/dashboard/a76/pedimentos.ts b/frontend/src/lib/api/dashboard/a76/pedimentos.ts index 582e913d..b075e59e 100644 --- a/frontend/src/lib/api/dashboard/a76/pedimentos.ts +++ b/frontend/src/lib/api/dashboard/a76/pedimentos.ts @@ -39,6 +39,11 @@ export interface PedimentoTransportMeans { departure?: string | null; } +export interface PedimentoCustomsOffices { + dispatch_customs?: string | null; + entry_exit_customs?: string | null; +} + export interface PedimentoValidation { validator?: string | null; validation_ack?: string | null; @@ -186,6 +191,7 @@ export interface Pedimento { pedimento_config_parameters?: PedimentoConfigParameters | null; pedimento_config_updates?: PedimentoConfigUpdates | null; pedimento_config_update_rectification?: PedimentoConfigUpdateRectification | null; + pedimento_customs_offices?: PedimentoCustomsOffices | null; identificadores?: Identificador[] | null; } @@ -226,6 +232,7 @@ export interface CreatePedimentoData { pedimento_config_parameters?: PedimentoConfigParameters | null; pedimento_config_updates?: PedimentoConfigUpdates | null; pedimento_config_update_rectification?: PedimentoConfigUpdateRectification | null; + pedimento_customs_offices?: PedimentoCustomsOffices | null; identificadores?: Identificador[] | null; } @@ -259,6 +266,7 @@ export interface UpdatePedimentoData { pedimento_config_parameters?: PedimentoConfigParameters | null; pedimento_config_updates?: PedimentoConfigUpdates | null; pedimento_config_update_rectification?: PedimentoConfigUpdateRectification | null; + pedimento_customs_offices?: PedimentoCustomsOffices | null; identificadores?: Identificador[] | null; } diff --git a/frontend/src/lib/components/dashboard/pedimentos/edit/general-tab-form.svelte b/frontend/src/lib/components/dashboard/pedimentos/edit/general-tab-form.svelte index 2ecf6562..aa8d3f8e 100644 --- a/frontend/src/lib/components/dashboard/pedimentos/edit/general-tab-form.svelte +++ b/frontend/src/lib/components/dashboard/pedimentos/edit/general-tab-form.svelte @@ -12,6 +12,8 @@ import type { CustomsBroker } from '$lib/api/dashboard/a76/customs-brokers'; import type { ClientProvider } from '$lib/api/dashboard/a76/clients-providers'; import type { CodePedimentoRegimen } from '$lib/api/dashboard/reference_data/code_pedimento_regimens'; + import type { TransportType } from '$lib/api/dashboard/reference_data/transport_types'; + import type { TransportMode } from '$lib/api/dashboard/reference_data/transport_modes'; import IdentificadoresTabForm from './identifiers-tab-form.svelte'; import ExchangeRateDialog from '$lib/components/dashboard/exchange_rate/create-edit-dialog.svelte'; import { Calendar, Clock } from 'lucide-svelte'; @@ -36,6 +38,8 @@ customsBrokers = [], clients = [], codePedimentoRegimens = [], + transportTypes = [], + transportModes = [], isActive = false }: { pedimento: Pedimento | null; @@ -46,6 +50,8 @@ customsBrokers?: CustomsBroker[]; clients?: ClientProvider[]; codePedimentoRegimens?: CodePedimentoRegimen[]; + transportTypes?: TransportType[]; + transportModes?: TransportMode[]; isActive?: boolean; } = $props(); @@ -312,10 +318,19 @@ entry_date: loadServerDate(datesData?.entry_date) || currentDate, end_date: loadServerDate(datesData?.end_date) || end_date, payment_date: loadServerDate(datesData?.payment_date) || payment_date, - pedimento_date: loadServerDate(datesData?.pedimento_date), - extraction_date: loadServerDate(datesData?.extraction_date), - rectification_payment_date: loadServerDate(datesData?.rectification_payment_date), - original_date: loadServerDate(datesData?.original_date), + extraction_date: loadServerDate(datesData?.entry_date) || null, + original_date: loadServerDate(datesData?.original_date) || null, + // Mapeos de sub-recursos + pedimento_customs_offices: { + dispatch_customs: pedimento?.pedimento_customs_offices?.dispatch_customs || '', + entry_exit_customs: pedimento?.pedimento_customs_offices?.entry_exit_customs || '' + }, + pedimento_transport_means: { + destination: pedimento?.pedimento_transport_means?.destination || null, + entry_exit: pedimento?.pedimento_transport_means?.entry_exit || '', + arrival: pedimento?.pedimento_transport_means?.arrival || '', + departure: pedimento?.pedimento_transport_means?.departure || '' + }, // Campos de captura automática (Local) fecha_captura: currentDate, hora_captura: currentTime @@ -370,7 +385,7 @@ { value: 'automobile', label: 'Automóvil' }, { value: 'complementary', label: 'Complementario' }, { value: 'consolidated', label: 'Consolidado' }, - { value: 'normal', label: 'Normal' } + { value: 'normal', label: 'Normal (Individual)' } ]; const tipoOperacionOptions = [ @@ -443,11 +458,9 @@ @@ -747,19 +760,144 @@
- + + (formData.pedimento_customs_offices.dispatch_customs = v || '')} + > + + {formData.pedimento_customs_offices.dispatch_customs || 'Sel...'} + + + {#each customsSections.filter((s) => !formData.customs_office || s.customs_code.startsWith(formData.customs_office.substring(0, 2))) as section} + + {section.customs_code} - {section.section_name} + + {/each} + + +
+ + +
+ + + (formData.pedimento_transport_means.destination = v ? Number(v) : null)} + > + + {formData.pedimento_transport_means.destination === 1 + ? '1 - REGION FRONTERIZA' + : formData.pedimento_transport_means.destination === 8 + ? '8 - RECTIFICACION REGION FRONTERIZA' + : formData.pedimento_transport_means.destination === 9 + ? '9 - INTERIOR DEL PAIS' + : 'Seleccionar...'} + + + 1 - REGION FRONTERIZA + 8 - RECTIFICACION REGION FRONTERIZA + 9 - INTERIOR DEL PAIS + +
- - + +
- +
- - + + (formData.pedimento_transport_means.entry_exit = v || '')} + > + + + {transportModes.find((m) => m.key === formData.pedimento_transport_means.entry_exit) + ?.name || + transportTypes.find( + (t) => t.transport_code === formData.pedimento_transport_means.entry_exit + )?.description || + formData.pedimento_transport_means.entry_exit || + 'Seleccionar...'} + + + + {#each transportModes as mode} + {mode.key} - {mode.name} + {/each} + + +
+ + +
+ + (formData.pedimento_transport_means.arrival = v || '')} + > + + + {transportModes.find((m) => m.key === formData.pedimento_transport_means.arrival) + ?.name || + transportTypes.find( + (t) => t.transport_code === formData.pedimento_transport_means.arrival + )?.description || + formData.pedimento_transport_means.arrival || + 'Seleccionar...'} + + + + {#each transportModes as mode} + {mode.key} - {mode.name} + {/each} + + +
+ + +
+ + (formData.pedimento_transport_means.departure = v || '')} + > + + + {transportModes.find((m) => m.key === formData.pedimento_transport_means.departure) + ?.name || + transportTypes.find( + (t) => t.transport_code === formData.pedimento_transport_means.departure + )?.description || + formData.pedimento_transport_means.departure || + 'Seleccionar...'} + + + + {#each transportModes as mode} + {mode.key} - {mode.name} + {/each} + +
diff --git a/frontend/src/routes/dashboard/pedimentos/edit/[id]/+page.server.ts b/frontend/src/routes/dashboard/pedimentos/edit/[id]/+page.server.ts index 2a67bd94..2e923b7d 100644 --- a/frontend/src/routes/dashboard/pedimentos/edit/[id]/+page.server.ts +++ b/frontend/src/routes/dashboard/pedimentos/edit/[id]/+page.server.ts @@ -39,6 +39,8 @@ export const load: PageServerLoad = async ({ params, cookies, fetch }) => { customsBrokers: [], clients: [], codePedimentoRegimens: [], + transportTypes: [], + transportModes: [], error: 'Error al cargar catálogos. Verifique la conexión con el backend.' }; } @@ -53,7 +55,9 @@ export const load: PageServerLoad = async ({ params, cookies, fetch }) => { customsSections: data.customs_sections || [], customsBrokers: data.customs_brokers || [], clients: data.clients || [], - codePedimentoRegimens: data.code_pedimento_regimens || [] + codePedimentoRegimens: data.code_pedimento_regimens || [], + transportTypes: data.transport_types || [], + transportModes: data.transport_modes || [] }; } catch (e) { console.error('❌ Error loading new pedimento data:', e); @@ -67,6 +71,8 @@ export const load: PageServerLoad = async ({ params, cookies, fetch }) => { customsBrokers: [], clients: [], codePedimentoRegimens: [], + transportTypes: [], + transportModes: [], error: 'Error al cargar catálogos. Verifique la conexión con el backend.' }; } @@ -106,7 +112,9 @@ export const load: PageServerLoad = async ({ params, cookies, fetch }) => { customsSections: data.customs_sections || [], customsBrokers: data.customs_brokers || [], clients: data.clients || [], - codePedimentoRegimens: data.code_pedimento_regimens || [] + codePedimentoRegimens: data.code_pedimento_regimens || [], + transportTypes: data.transport_types || [], + transportModes: data.transport_modes || [] }; } catch (e) { console.error('Error loading pedimento:', e); diff --git a/frontend/src/routes/dashboard/pedimentos/edit/[id]/+page.svelte b/frontend/src/routes/dashboard/pedimentos/edit/[id]/+page.svelte index b6e05d88..8f306d7a 100644 --- a/frontend/src/routes/dashboard/pedimentos/edit/[id]/+page.svelte +++ b/frontend/src/routes/dashboard/pedimentos/edit/[id]/+page.svelte @@ -54,6 +54,8 @@ import type { CustomsBroker } from '$lib/api/dashboard/a76/customs-brokers'; import type { ClientProvider } from '$lib/api/dashboard/a76/clients-providers'; import type { CodePedimentoRegimen } from '$lib/api/dashboard/reference_data/code_pedimento_regimens'; + import type { TransportType } from '$lib/api/dashboard/reference_data/transport_types'; + import type { TransportMode } from '$lib/api/dashboard/reference_data/transport_modes'; // Get sidebar context const sidebar = useSidebar(); @@ -67,6 +69,8 @@ customsBrokers?: CustomsBroker[]; clients?: ClientProvider[]; codePedimentoRegimens?: CodePedimentoRegimen[]; + transportTypes?: TransportType[]; + transportModes?: TransportMode[]; user?: any; companies?: any[]; authenticated?: boolean; @@ -463,6 +467,32 @@ end_date: generalFormData.end_date || null }; } + + // Aduanas (Despacho y Entrada/Salida) + const hasCustomsValue = + generalFormData.pedimento_customs_offices?.dispatch_customs || + generalFormData.pedimento_customs_offices?.entry_exit_customs; + if (hasCustomsValue) { + payload.pedimento_customs_offices = { + dispatch_customs: generalFormData.pedimento_customs_offices.dispatch_customs || null, + entry_exit_customs: generalFormData.pedimento_customs_offices.entry_exit_customs || null + }; + } + + // Transportes y Destino + const hasTransportValue = + generalFormData.pedimento_transport_means?.destination || + generalFormData.pedimento_transport_means?.entry_exit || + generalFormData.pedimento_transport_means?.arrival || + generalFormData.pedimento_transport_means?.departure; + if (hasTransportValue) { + payload.pedimento_transport_means = { + destination: generalFormData.pedimento_transport_means.destination || null, + entry_exit: generalFormData.pedimento_transport_means.entry_exit || null, + arrival: generalFormData.pedimento_transport_means.arrival || null, + departure: generalFormData.pedimento_transport_means.departure || null + }; + } } // Solo agregar sub-recursos en modo UPDATE (no en CREATE) @@ -1060,11 +1090,13 @@ pedimento={data.pedimento} bind:formData={generalFormData} bind:identificadoresFormData - pedimentoCodes={data.pedimentoCodes || []} - customsSections={data.customsSections || []} - customsBrokers={data.customsBrokers || []} - clients={data.clients || []} - codePedimentoRegimens={data.codePedimentoRegimens || []} + pedimentoCodes={data.pedimentoCodes} + customsSections={data.customsSections} + customsBrokers={data.customsBrokers} + clients={data.clients} + codePedimentoRegimens={data.codePedimentoRegimens} + transportTypes={data.transportTypes} + transportModes={data.transportModes} isActive={activeTab === 'general'} />