feat: Introduce customs office and transport means fields to pedimento data models and forms.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 @@
|
||||
<Input
|
||||
id="year"
|
||||
bind:value={formData.year}
|
||||
placeholder="23"
|
||||
maxlength={2}
|
||||
class="text-center md:w-16"
|
||||
disabled
|
||||
readonly
|
||||
placeholder="25"
|
||||
maxlength={4}
|
||||
class="text-center md:w-20"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -747,19 +760,144 @@
|
||||
<!-- Despacho -->
|
||||
<div class="space-y-2">
|
||||
<Label for="despacho">Despacho</Label>
|
||||
<Input id="despacho" type="number" bind:value={formData.despacho} placeholder="0" />
|
||||
<Select.Root
|
||||
type="single"
|
||||
value={formData.pedimento_customs_offices.dispatch_customs || ''}
|
||||
onValueChange={(v: string) =>
|
||||
(formData.pedimento_customs_offices.dispatch_customs = v || '')}
|
||||
>
|
||||
<Select.Trigger id="despacho" class="w-full">
|
||||
{formData.pedimento_customs_offices.dispatch_customs || 'Sel...'}
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
{#each customsSections.filter((s) => !formData.customs_office || s.customs_code.startsWith(formData.customs_office.substring(0, 2))) as section}
|
||||
<Select.Item value={section.customs_code}>
|
||||
{section.customs_code} - {section.section_name}
|
||||
</Select.Item>
|
||||
{/each}
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
</div>
|
||||
|
||||
<!-- Destino -->
|
||||
<div class="space-y-2">
|
||||
<Label for="destino">Destino <span class="text-red-500">*</span></Label>
|
||||
<Select.Root
|
||||
type="single"
|
||||
value={formData.pedimento_transport_means.destination
|
||||
? String(formData.pedimento_transport_means.destination)
|
||||
: ''}
|
||||
onValueChange={(v: string) =>
|
||||
(formData.pedimento_transport_means.destination = v ? Number(v) : null)}
|
||||
>
|
||||
<Select.Trigger id="destino" class="w-full">
|
||||
{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...'}
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
<Select.Item value="1">1 - REGION FRONTERIZA</Select.Item>
|
||||
<Select.Item value="8">8 - RECTIFICACION REGION FRONTERIZA</Select.Item>
|
||||
<Select.Item value="9">9 - INTERIOR DEL PAIS</Select.Item>
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
</div>
|
||||
|
||||
<!-- Aduana E/S -->
|
||||
<div class="space-y-2">
|
||||
<Label for="aduana_es">Aduana E/S</Label>
|
||||
<Input id="aduana_es" type="number" bind:value={formData.aduana_es} placeholder="0" />
|
||||
<Label for="entry_exit_customs">Aduana E/S</Label>
|
||||
<Input
|
||||
id="entry_exit_customs"
|
||||
type="text"
|
||||
maxlength={3}
|
||||
bind:value={formData.pedimento_customs_offices.entry_exit_customs}
|
||||
placeholder="000"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- E/S -->
|
||||
<!-- Método de Entrada/Salida -->
|
||||
<div class="space-y-2">
|
||||
<Label for="es">E/S</Label>
|
||||
<Input id="es" type="number" bind:value={formData.es} placeholder="0" />
|
||||
<Label for="entry_exit">Método de Entrada</Label>
|
||||
<Select.Root
|
||||
type="single"
|
||||
value={formData.pedimento_transport_means.entry_exit || ''}
|
||||
onValueChange={(v: string) => (formData.pedimento_transport_means.entry_exit = v || '')}
|
||||
>
|
||||
<Select.Trigger id="entry_exit" class="w-full">
|
||||
<span class="truncate">
|
||||
{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...'}
|
||||
</span>
|
||||
</Select.Trigger>
|
||||
<Select.Content class="max-h-[300px]">
|
||||
{#each transportModes as mode}
|
||||
<Select.Item value={mode.key}>{mode.key} - {mode.name}</Select.Item>
|
||||
{/each}
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
</div>
|
||||
|
||||
<!-- Arribo -->
|
||||
<div class="space-y-2">
|
||||
<Label for="arrival">Arribo</Label>
|
||||
<Select.Root
|
||||
type="single"
|
||||
value={formData.pedimento_transport_means.arrival || ''}
|
||||
onValueChange={(v: string) => (formData.pedimento_transport_means.arrival = v || '')}
|
||||
>
|
||||
<Select.Trigger id="arrival" class="w-full">
|
||||
<span class="truncate">
|
||||
{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...'}
|
||||
</span>
|
||||
</Select.Trigger>
|
||||
<Select.Content class="max-h-[300px]">
|
||||
{#each transportModes as mode}
|
||||
<Select.Item value={mode.key}>{mode.key} - {mode.name}</Select.Item>
|
||||
{/each}
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
</div>
|
||||
|
||||
<!-- Salida -->
|
||||
<div class="space-y-2">
|
||||
<Label for="departure">Salida</Label>
|
||||
<Select.Root
|
||||
type="single"
|
||||
value={formData.pedimento_transport_means.departure || ''}
|
||||
onValueChange={(v: string) => (formData.pedimento_transport_means.departure = v || '')}
|
||||
>
|
||||
<Select.Trigger id="departure" class="w-full">
|
||||
<span class="truncate">
|
||||
{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...'}
|
||||
</span>
|
||||
</Select.Trigger>
|
||||
<Select.Content class="max-h-[300px]">
|
||||
{#each transportModes as mode}
|
||||
<Select.Item value={mode.key}>{mode.key} - {mode.name}</Select.Item>
|
||||
{/each}
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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'}
|
||||
/>
|
||||
</Tabs.Content>
|
||||
|
||||
Reference in New Issue
Block a user