refactor: enhance invoice mapping functions and integrate PedimentosResponse DTO in catalog service

This commit is contained in:
2026-02-13 16:26:06 -06:00
parent 794d6d1781
commit e05e50f2b8
4 changed files with 190 additions and 13 deletions

View File

@@ -17,6 +17,7 @@ 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 .dtos.pedimentos import PedimentosResponse
from .schemas import PedimentoCatalogsResponse, PedimentoCreationResponse, PedimentoEditionResponse
@@ -111,10 +112,13 @@ class PedimentoCatalogService:
if not pedimento:
return None
# Convert SQLAlchemy object to Pydantic DTO
pedimento_dto = PedimentosResponse.model_validate(pedimento)
return PedimentoEditionResponse(
**catalogs.model_dump(),
is_create=False,
pedimento=pedimento,
pedimento=pedimento_dto,
pedimento_id=pedimento_id
)

View File

@@ -2,7 +2,7 @@
Consolidated schemas for Pedimento catalog responses
"""
from typing import List, Optional, Any
from typing import List, Optional
from pydantic import BaseModel
# Import DTOs for catalog items
@@ -11,6 +11,7 @@ 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 .dtos.pedimentos import PedimentosResponse
class PedimentoCatalogsResponse(BaseModel):
@@ -33,5 +34,5 @@ class PedimentoEditionResponse(PedimentoCatalogsResponse):
"""Response for editing an existing pedimento (catalogs + pedimento data)"""
is_create: bool = False
pedimento: Optional[Any] = None # Will be PedimentosResponse but avoiding circular import
pedimento: Optional[PedimentosResponse] = None
pedimento_id: Optional[int] = None

View File

@@ -24,6 +24,7 @@
invoice,
onSave,
onCancel,
isTargetingPreset = false,
isSaving = false
}: {
open: boolean;
@@ -32,6 +33,7 @@
invoice: Invoice | null;
onSave: () => void;
onCancel?: () => void;
isTargetingPreset?: boolean;
isSaving?: boolean;
} = $props();

View File

@@ -222,29 +222,199 @@
return { ...skeleton, ...filtered };
}
// Función para mapear la factura existente a los formData
function mapInvoiceToTopFields(invoice: any) {
if (!invoice) return topFieldsSkeleton;
let operationType: string | null = null;
if (invoice.operation_type) {
operationType = invoice.operation_type;
} else if (data.filters?.operation_type !== undefined) {
operationType = data.filters.operation_type ?? null;
}
return {
is_pedimento_pending: invoice.compliance_mx?.is_pedimento_pending || false,
pedimento_id: invoice.compliance_mx?.pedimento_id || '',
remesa: invoice.compliance_mx?.remesa || '',
invoice_number: invoice.invoice_number || '',
invoice_date: invoice.invoice_date || new Date().toISOString().split('T')[0],
emission_date: invoice.emission_date || new Date().toISOString().split('T')[0],
operation_type: operationType,
invoice_type: invoice.invoice_type || (data.filters?.invoice_type ?? ''),
fecha_pedimento_del: '',
fecha_pedimento_al: '',
clave_pedimento: '',
regimen_pedimento: ''
};
}
function mapInvoiceToGeneral(invoice: any) {
if (!invoice) return generalSkeleton;
return {
provider_header: invoice.compliance_mx?.provider_header || 'proveedor',
provider_id: invoice.compliance_mx?.provider_id || null,
sold_to_header: invoice.compliance_mx?.sold_to_header || 'consignado_a',
sold_to_id: invoice.compliance_mx?.sold_to_id || null,
shipped_to_header: invoice.compliance_mx?.shipped_to_header || 'enviado_a',
shipped_to_id: invoice.compliance_mx?.shipped_to_id || null,
customs_broker_id: invoice.compliance_mx?.customs_broker_id || null,
customs_broker_us_id: invoice.compliance_mx?.customs_broker_us_id || null,
currency_type: invoice.financials?.currency_type || '',
currency: invoice.financials?.currency || 'foreign',
exchange_rate: invoice.financials?.exchange_rate || null,
weight_type: 'kgs',
iva_factor: invoice.financials?.iva_factor || null,
carrier_id: invoice.logistics?.carrier_id || null,
transport_id: invoice.logistics?.transport_id || '',
driver_name: invoice.logistics?.driver_name || '',
transport_type: invoice.logistics?.transport_type || '',
transport_num: invoice.logistics?.vehicle_num || '',
aduana: invoice.compliance_mx?.aduana || '',
document_type: invoice.document_type || ''
};
}
function mapInvoiceToObservations(invoice: any) {
if (!invoice) return observationSkeleton;
return {
observation_es: invoice.observation_es || '',
observation_en: invoice.observation_en || '',
freight: invoice.financials?.freight || null,
insurance_value: invoice.financials?.insurance_value || null,
insurance: invoice.financials?.insurance || null,
packaging: invoice.financials?.packaging || null,
other_increments: invoice.financials?.other_increments || null,
total_increments_mn: invoice.financials?.total_increments_mn || null,
total_increments_me: invoice.financials?.total_increments_me || null,
incoterm: invoice.logistics?.incoterm || null,
enclosure: invoice.compliance_mx?.enclosure || null,
num_seals: null,
movement_type: invoice.compliance_mx?.movement_type || '',
alternate_invoice: invoice.alternate_invoice || '',
valuation_method: invoice.compliance_mx?.value_method || null
};
}
function mapInvoiceToItems(invoice: any) {
if (!invoice) return ensureItemsFormData(null);
return {
items: invoice.items || []
};
}
function mapInvoiceToOthers(invoice: any) {
if (!invoice) return othersSkeleton;
return {
comments_status: invoice.comments_status || '',
transport_mode: invoice.logistics?.transport_mode || 'TRUCK',
is_mixed: invoice.compliance_mx?.is_mixed || false,
print_stamp: invoice.print_stamp || false,
rule_3121_parties_ii: invoice.compliance_mx?.rule_3121_parties_ii || false,
related_doc_id: invoice.related_doc_id || null,
code_signature: invoice.compliance_mx?.code_signature || '',
electronic_signature: invoice.compliance_mx?.electronic_signature || '',
mandatory_person: invoice.compliance_mx?.mandatory_person || '',
contingency_mode: invoice.compliance_mx?.contingency_mode || false,
cove: invoice.compliance_mx?.cove || '',
operation_num: invoice.compliance_mx?.operation_num || '',
adendas: invoice.compliance_mx?.adendas || '',
observations_vu: invoice.compliance_mx?.observations_vu || '',
certified_number: invoice.compliance_mx?.certified_number || '',
bill_number: invoice.logistics?.bill_number || '',
guide_number: invoice.logistics?.guide_number || '',
shipment_number: invoice.logistics?.shipment_number || '',
option_iv18: invoice.compliance_mx?.option_iv18 || '',
delivered_status: invoice.delivered_status || false,
received_by: invoice.received_by || '',
delivery_date: invoice.delivery_date || ''
};
}
function mapInvoiceToContinuation(invoice: any) {
if (!invoice) return continuationSkeleton;
return {
numero_tipo_transporte: invoice.logistics?.numero_tipo_transporte || '',
es_ferrocarril: invoice.logistics?.es_ferrocarril || 'no',
numero_bl: invoice.logistics?.numero_bl || '',
cantidad_guias_embarque: invoice.logistics?.cantidad_guias_embarque || null,
destino_origen: invoice.logistics?.destino_origen || '',
puerto_entrada: invoice.logistics?.puerto_entrada || '',
vehicle_data: invoice.logistics?.vehicle_data || '',
fue_revisado_equipo: invoice.logistics?.fue_revisado_equipo || false,
sub_division: invoice.compliance_mx?.subdivision || false,
funge_como_cd: invoice.logistics?.acts_as_cd || false,
llego_pedimento: invoice.compliance_mx?.llego_pedimento || false,
errores_facturacion: invoice.errores_facturacion || [],
semaforo_verde_aduana_mexicana: invoice.compliance_mx?.semaforo_verde_aduana_mexicana || false,
semaforo_verde_aduana_americana: invoice.compliance_mx?.semaforo_verde_aduana_americana || false,
semaforo_rojo_aduana_mexicana: invoice.compliance_mx?.semaforo_rojo_aduana_mexicana || false,
semaforo_rojo_aduana_americana: invoice.compliance_mx?.semaforo_rojo_aduana_americana || false,
is_mixed: invoice.compliance_mx?.is_mixed || false,
reason_export: invoice.compliance_mx?.reason_export || '1',
purchase_order: invoice.purchase_order || '',
payment_terms: invoice.payment_terms || '',
handling_fees: invoice.financials?.handling_fees || 0,
cfdi_uuid: invoice.cfdi_uuid || '',
path_pdf: invoice.path_pdf || '',
path_xml: invoice.path_xml || ''
};
}
// Referencias a los componentes de formulario para obtener sus datos
// Si estamos en modo edición (!data.isCreate) y tenemos una factura, usarla
// Si estamos en modo creación, usar defaultSettings
let InvoiceTopFieldsFormData = $state<any>(
mergeDefaults(topFieldsSkeleton, data.defaultSettings?.InvoiceTopFieldsFormData)
!data.isCreate && data.invoice
? mapInvoiceToTopFields(data.invoice)
: mergeDefaults(topFieldsSkeleton, data.defaultSettings?.InvoiceTopFieldsFormData)
);
let generalFormData = $state<any>(
mergeDefaults(generalSkeleton, data.defaultSettings?.generalFormData)
!data.isCreate && data.invoice
? mapInvoiceToGeneral(data.invoice)
: mergeDefaults(generalSkeleton, data.defaultSettings?.generalFormData)
);
let observationFormData = $state<any>(
mergeDefaults(observationSkeleton, data.defaultSettings?.observationFormData)
!data.isCreate && data.invoice
? mapInvoiceToObservations(data.invoice)
: mergeDefaults(observationSkeleton, data.defaultSettings?.observationFormData)
);
let itemsFormData = $state<any>(
!data.isCreate && data.invoice
? mapInvoiceToItems(data.invoice)
: ensureItemsFormData(data.defaultSettings?.itemsFormData)
);
let itemsFormData = $state<any>(ensureItemsFormData(data.defaultSettings?.itemsFormData));
let othersFormData = $state<any>(
mergeDefaults(othersSkeleton, data.defaultSettings?.othersFormData)
!data.isCreate && data.invoice
? mapInvoiceToOthers(data.invoice)
: mergeDefaults(othersSkeleton, data.defaultSettings?.othersFormData)
);
let continuationFormData = $state<any>(
mergeDefaults(continuationSkeleton, data.defaultSettings?.continuationFormData)
!data.isCreate && data.invoice
? mapInvoiceToContinuation(data.invoice)
: mergeDefaults(continuationSkeleton, data.defaultSettings?.continuationFormData)
);
// Estados para saber si existen datos previos
let observationExists = $state(!!data.defaultSettings?.observationFormData);
let itemsExists = $state(!!data.defaultSettings?.itemsFormData?.items?.length);
let othersExists = $state(!!data.defaultSettings?.othersFormData);
let continuationExists = $state(!!data.defaultSettings?.continuationFormData);
let observationExists = $state(
!data.isCreate ? !!data.invoice : !!data.defaultSettings?.observationFormData
);
let itemsExists = $state(
!data.isCreate
? !!(data.invoice?.items && data.invoice.items.length > 0)
: !!data.defaultSettings?.itemsFormData?.items?.length
);
let othersExists = $state(
!data.isCreate ? !!data.invoice : !!data.defaultSettings?.othersFormData
);
let continuationExists = $state(
!data.isCreate ? !!data.invoice : !!data.defaultSettings?.continuationFormData
);
let calculatedExchangeRate = $state<number | null>(
data.invoice?.financials?.exchange_rate ?? null