feat: enhance invoice models with additional fields and relationships for improved data handling

This commit is contained in:
AlexeerCT
2025-12-19 13:48:32 -06:00
parent fa70b747ec
commit 7c8b972899

View File

@@ -10,74 +10,97 @@ from ....common.base_models import TenantScopedMixin, TimestampMixin
class OperationType(str, Enum):
IMP = "imp" # Importación
EXP = "exp" # Exportación
SM_IN = "sm_in" # Entrada SM
SM_OUT = "sm_out" # Salida SM
CTM_SEND = "ctm_send" # Envío CTM
CTM_RECEIVE = "ctm_receive" # Recibo CTM
class TransportType(str, Enum):
NONE = "none" # Ninguno
TRANSPORT = "transport" # Transporte
BOX = "box" # Caja
PLATES = "licence plates" # Placas
TRUCK = "truck" # Camión
VESSEL = "vessel" # Buque
BARGE = "rail barge" # Ferrobarcaza
CONTAINER = "container" # Contenedor
AIRPLANE = "airplane" # Avión
GONDOLA = "gondola" # Góndola
FLATBED = "flatbed" # Plataforma
NONE = "none"
TRANSPORT = "transport"
BOX = "box"
PLATES = "licence plates"
TRUCK = "truck"
VESSEL = "vessel"
BARGE = "rail barge"
CONTAINER = "container"
AIRPLANE = "airplane"
GONDOLA = "gondola"
FLATBED = "flatbed"
# --- 1. Invoice Header (invoice_header) ---
class InvoiceHeader(Base, TenantScopedMixin, TimestampMixin):
__tablename__ = "invoice_header"
__table_args__ = (
{"schema": "a76"},
)
__table_args__ = ({"schema": "a76"},)
id: Mapped[int] = mapped_column(
BigInteger, primary_key=True, autoincrement=True)
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
# Identifiers
operation_type: Mapped[OperationType] = mapped_column(
String(3)) # TIPOMOVIMIENTO / Clasifica imp/exp
invoice_type: Mapped[Optional[str]] = mapped_column(ForeignKey(
"public.invoice_types.key")) # TIPOFACTURA (invoice_types)
invoice_number: Mapped[Optional[str]] = mapped_column(
String(20)) # FACTURAIMPO/FACTURAEXPO/FACTURAREMISION
project_number: Mapped[Optional[str]] = mapped_column(
String(14)) # NUMPROYECTO
purchase_order: Mapped[Optional[str]] = mapped_column(
String(50)) # ORDENCOMPRA
related_doc_id: Mapped[Optional[int]] = mapped_column(
Integer) # IDRELDOC (Para Rectificaciones)
operation_type: Mapped[OperationType] = mapped_column(String(10)) # TIPOMOVIMIENTO / Clasifica imp/exp/sm/ctm
invoice_type: Mapped[Optional[str]] = mapped_column(ForeignKey("public.invoice_types.key")) # TIPOFACTURA / TIPODOC
invoice_number: Mapped[Optional[str]] = mapped_column(String(20)) # FACTURAIMPO/FACTURAEXPO/FACTURAREMISION/FACTURAENVIO/FACTURASALIDA
project_number: Mapped[Optional[str]] = mapped_column(String(14)) # NUMPROYECTO
purchase_order: Mapped[Optional[str]] = mapped_column(String(50)) # ORDENCOMPRA
related_doc_id: Mapped[Optional[int]] = mapped_column(Integer) # IDRELDOC / Para Rectificaciones
alternate_invoice: Mapped[Optional[str]] = mapped_column(String(99)) # FACTURAALTERNA
invoice_ref: Mapped[Optional[str]] = mapped_column(String(19)) # FACTURAEXPOREF
proforma_number: Mapped[Optional[str]] = mapped_column(String(20)) # NUMEROPROFORMA
# Dates
invoice_date: Mapped[Optional[datetime]
] = mapped_column(Date) # FECHAFACTURA
capture_date: Mapped[datetime] = mapped_column(
TIMESTAMP(timezone=False), default=datetime.now) # FECHACAPTURA + HORAACTUAL
invoice_date: Mapped[Optional[datetime]] = mapped_column(Date) # FECHAFACTURA
capture_date: Mapped[datetime] = mapped_column(TIMESTAMP(timezone=False), default=datetime.now) # FECHACAPTURA + HORAACTUAL
emission_date: Mapped[Optional[datetime]] = mapped_column(Date) # FECHAEMISION
# Status & Control
is_updated: Mapped[Optional[str]] = mapped_column(Boolean) # ESTATUS
updated_date: Mapped[Optional[datetime]] = mapped_column(TIMESTAMP(timezone=False)) # FECHAACTUALIZACION
who_updated: Mapped[Optional[str]] = mapped_column(String(20)) # QUIENA ACTUALIZO
is_updated: Mapped[Optional[bool]] = mapped_column(Boolean) # ESTATUS
updated_date: Mapped[Optional[datetime]] = mapped_column(TIMESTAMP(timezone=False)) # FECHAACTUALIZACION / FECHAACTUAL
who_updated: Mapped[Optional[str]] = mapped_column(String(20)) # USUARIOACT / Quien actualizó
capture_user: Mapped[Optional[str]] = mapped_column(String(20)) # USUARIOCAP / Usuario que capturó
traffic_light_status: Mapped[Optional[str]] = mapped_column(String(50)) # SEMAFORO / SEMAFOROEXPO/IMPO
process_log: Mapped[Optional[str]] = mapped_column(String(300)) # COMOFUEPROCESADA
status_rec: Mapped[Optional[int]] = mapped_column(Integer) # ESTATUSREC / Estatus de recepción
status_rep: Mapped[Optional[str]] = mapped_column(String(2)) # ESTATUSREP / Estatus de reporte
# Comments
observation_es: Mapped[Optional[str]] = mapped_column(Text) #OBSERVACIONE
observation_en: Mapped[Optional[str]] = mapped_column(Text) #OBSERVACIONI
comments_status: Mapped[Optional[str]] = mapped_column(Text) #COMENTARIOSESTATUS
# Comments
observation_es: Mapped[Optional[str]] = mapped_column(Text) # OBSERVACIONE / Observaciones en español
observation_en: Mapped[Optional[str]] = mapped_column(Text) # OBSERVACIONI / Observaciones en inglés
comments_status: Mapped[Optional[str]] = mapped_column(Text) # COMENTARIOSESTATUS
vu_observations: Mapped[Optional[str]] = mapped_column(String(500)) # OBSERVACIONESVU / Observaciones VUCEM
# Digital Archive Links
cfdi_uuid: Mapped[Optional[str]] = mapped_column(String(100)) # CFDIUUID
path_pdf: Mapped[Optional[str]] = mapped_column(String(500)) # CFDIPATHPDF
path_xml: Mapped[Optional[str]] = mapped_column(String(500)) # CFDIPATHXML
# Relationships (Para navegacion ORM)
compliance_mx: Mapped["InvoiceComplianceMx"] = relationship(
back_populates="header", cascade="all, delete-orphan")
financials: Mapped["InvoiceFinancials"] = relationship(
back_populates="header", cascade="all, delete-orphan")
# Control & Subcompany
subcompany: Mapped[Optional[str]] = mapped_column(String(5)) # SUBEMPRESA
party_count: Mapped[Optional[int]] = mapped_column(Integer) # CANT_PARTIDAS / Cantidad de partidas
# Generation flags
generate_id: Mapped[Optional[str]] = mapped_column(String(1)) # GENERAID
generate_desc_parties: Mapped[Optional[str]] = mapped_column(String(12)) # GENDESCPARTIDAS / Generar descripción de partidas
apply_manual_discount: Mapped[Optional[str]] = mapped_column(String(1)) # APLICADESCMANUAL
# Bulk & Downloads
is_bulk: Mapped[Optional[bool]] = mapped_column(Boolean) # ESAGRANEL / Es a granel
download_substance: Mapped[Optional[bool]] = mapped_column(Boolean) # DESCARGASUST / Descarga de sustancia
download_class: Mapped[Optional[bool]] = mapped_column(Boolean) # DESCARGACLASE / Descarga de clase
download_def: Mapped[Optional[bool]] = mapped_column(Boolean) # DESCARGADEF / Descarga definitiva
# Additional fields
payment_terms: Mapped[Optional[str]] = mapped_column(String(200)) # TERMINOSPAGO / Términos de pago
handling_fees: Mapped[Optional[float]] = mapped_column(Numeric(19, 8)) # MANIOBRAS
option_iv18: Mapped[Optional[str]] = mapped_column(String(50)) # OPCIONIV18
enajenation_goods: Mapped[Optional[bool]] = mapped_column(Boolean) # ENAJENACIONBIENES / Enajenación de bienes
# Relationships
compliance_mx: Mapped[Optional["InvoiceComplianceMx"]] = relationship(
back_populates="header", cascade="all, delete-orphan", uselist=False)
financials: Mapped[Optional["InvoiceFinancials"]] = relationship(
back_populates="header", cascade="all, delete-orphan", uselist=False)
details: Mapped[List["InvoiceSalesDetails"]] = relationship(
back_populates="header", cascade="all, delete-orphan")
collections: Mapped[List["InvoiceCollections"]] = relationship(
@@ -89,79 +112,149 @@ class InvoiceHeader(Base, TenantScopedMixin, TimestampMixin):
# --- 2. Compliance MX (invoice_compliance_mx) ---
class InvoiceComplianceMx(Base, TenantScopedMixin, TimestampMixin):
__tablename__ = "invoice_compliance_mx"
__table_args__ = (
{"schema": "a76"},
)
__table_args__ = ({"schema": "a76"},)
invoice_id: Mapped[int] = mapped_column(
ForeignKey("a76.invoice_header.id"), primary_key=True)
invoice_id: Mapped[int] = mapped_column(ForeignKey("a76.invoice_header.id"), primary_key=True)
# Core Customs Data
pedimento: Mapped[Optional[str]] = mapped_column(
String(19)) # PEDIMENTO/PEDIMENTOIMPO/EXPO
pedimento_code: Mapped[Optional[str]] = mapped_column(
String(5)) # PEDIMENTOR1, K1
remesa: Mapped[Optional[int]] = mapped_column(Integer)
pedimento: Mapped[Optional[str]] = mapped_column(String(19)) # PEDIMENTO/PEDIMENTOIMPO/EXPO
pedimento_code: Mapped[Optional[str]] = mapped_column(String(5)) # PEDIMENTOR1
pedimento_k1: Mapped[Optional[str]] = mapped_column(String(15)) # PEDIMENTOK1
remesa: Mapped[Optional[int]] = mapped_column(Integer) # REMESA
aduana: Mapped[Optional[str]] = mapped_column(ForeignKey("public.customs_sections.customs_code")) # ADUANA_CRUCE
port_of_entry: Mapped[Optional[str]] = mapped_column(String(6)) # PUERTOENTRADA / Puerto de entrada
destination: Mapped[Optional[str]] = mapped_column(String(3)) # DESTINO / Código de destino
manifest_number: Mapped[Optional[str]] = mapped_column(String(15)) # MANIFIESTO / Número de manifiesto
# Clients & Providers
provider_header: Mapped[Optional[str]] = mapped_column(String(20)) # PROVEEDOREXPORTADOR
provider_header: Mapped[Optional[str]] = mapped_column(String(20)) # PROVEEDOREXPORTADOR
provider_id: Mapped[Optional[str]] = mapped_column(ForeignKey("a76.clients_and_providers.id")) # PROVEEDOR
sold_to_header: Mapped[Optional[str]] = mapped_column(String(20)) # VENDIDOCONSIGNADO
sold_to_id: Mapped[Optional[str]] = mapped_column(ForeignKey("a76.clients_and_providers.id")) # VENDIDOA
shipped_to_header: Mapped[Optional[str]] = mapped_column(String(20)) # ENVIADOTRANSFERIDO
shipped_to_id: Mapped[Optional[str]] = mapped_column(ForeignKey("a76.clients_and_providers.id")) # ENVIADOA
shipped_to_id: Mapped[Optional[str]] = mapped_column(ForeignKey("a76.clients_and_providers.id")) # ENVIADOA
shipped_by_header: Mapped[Optional[str]] = mapped_column(String(20)) # ENVIADOPORVENDIDOPOR
shipped_by_id: Mapped[Optional[str]] = mapped_column(ForeignKey("a76.clients_and_providers.id")) # VENDIDOPOR
shipped_by_id: Mapped[Optional[str]] = mapped_column(ForeignKey("a76.clients_and_providers.id")) # VENDIDOPOR/ENVIADOPOR
customs_broker_id: Mapped[Optional[str]] = mapped_column(ForeignKey("a76.customs_brokers.id")) # AADUANAL / Agente aduanal
customs_broker_us_id: Mapped[Optional[str]] = mapped_column(ForeignKey("a76.customs_brokers.id")) # AADUANALAME / Agente aduanal americano
customs_broker_id: Mapped[Optional[str]] = mapped_column(ForeignKey("a76.customs_brokers.id")) # AADUANAL
# Broker Invoice
broker_invoice_num: Mapped[Optional[str]] = mapped_column(String(20)) # NUMFACTURABROKER / Número factura broker
broker_invoice_date: Mapped[Optional[datetime]] = mapped_column(Date) # FECHAFACBROKER / Fecha factura broker
# Flags & Specific Regimes
is_mixed: Mapped[Optional[bool]] = mapped_column(Boolean) # ESMIXTO
waste_type: Mapped[Optional[str]] = mapped_column(String(1)) # TIPODESPERDICIO
appendix_17: Mapped[Optional[int]] = mapped_column(Integer) # APENDICE17
is_mixed: Mapped[Optional[bool]] = mapped_column(Boolean) # ESMIXTO / Es mixto
waste_type: Mapped[Optional[str]] = mapped_column(String(1)) # TIPODESPERDICIO / Tipo de desperdicio
scrap_type: Mapped[Optional[str]] = mapped_column(String(1)) # TIPOSCRAP / Tipo de scrap
appendix_17: Mapped[Optional[int]] = mapped_column(Integer) # APENDICE17 / Apéndice 17
is_regime_change: Mapped[Optional[str]] = mapped_column(String(1)) # ESCAMBIOREGIMEN / Es cambio de régimen
which_exchange_rate: Mapped[Optional[str]] = mapped_column(String(5)) # CUALTIPOCAMBIO / Cuál tipo de cambio
value_method: Mapped[Optional[str]] = mapped_column(String(2)) # METVALOR / Método de valoración
act_value: Mapped[Optional[str]] = mapped_column(String(5)) # ACTVALOR / Actualizar valor
# Ownership & Balances
is_owner_of_goods: Mapped[Optional[str]] = mapped_column(String(2)) # ESDUENOMCIA / Es dueño de mercancía
generate_balances: Mapped[Optional[str]] = mapped_column(String(2)) # GENERARSALDOS / Generar saldos
was_reviewed_by_company: Mapped[Optional[bool]] = mapped_column(Boolean) # FUEREVISADAMCIA / Fue revisada por la compañía
# VUCEM / Digital
edocument: Mapped[Optional[str]] = mapped_column(String(50)) # EDOCUMENT
electronic_signature: Mapped[Optional[str]] = mapped_column(String(999)) # FIRMAELECTRONICA
sem_id: Mapped[Optional[int]] = mapped_column(Integer) # SEM (de SFacEntradaSM/SFacSalidaSM)
edocument: Mapped[Optional[str]] = mapped_column(String(50)) # EDOCUMENT / Documento electrónico
electronic_signature: Mapped[Optional[str]] = mapped_column(String(999)) # FIRMAELECTRONICA / Firma electrónica
certificate_number: Mapped[Optional[str]] = mapped_column(String(99)) # NUMEROCERTIFICADO / Número de certificado
niu_number: Mapped[Optional[str]] = mapped_column(String(19)) # NUMERONIU / Número NIU
bill_of_lading_count: Mapped[Optional[str]] = mapped_column(String(12)) # CANTGUIASEMBARQUE / Cantidad guías embarque
addendum_vu: Mapped[Optional[str]] = mapped_column(String(204)) # ADENDAVU / Adenda VUCEM
origin_destination_cove: Mapped[Optional[str]] = mapped_column(String(19)) # DESTINOORIGENCOVE / Destino/Origen COVE
vucem_operation_num: Mapped[Optional[str]] = mapped_column(String(19)) # NUMOPERACIONVU / Número operación VUCEM
customs_person_line: Mapped[Optional[int]] = mapped_column(Integer) # LINEAPERSONAAA / Línea persona agente aduanal
# Additional Control
contingency_mode: Mapped[Optional[bool]] = mapped_column(Boolean) # MODOCONTINGENCIA / Modo contingencia
enclosure: Mapped[Optional[str]] = mapped_column(String(4)) # RECINTO / Recinto fiscal
guide_type_to_identify: Mapped[Optional[str]] = mapped_column(String(1)) # TIPODEGUIAAIDENTIFICAR / Tipo de guía a identificar
location: Mapped[Optional[str]] = mapped_column(String(200)) # LOCALIZACION / Localización
# DOT & Official
dot_code: Mapped[Optional[str]] = mapped_column(String(20)) # CLAVEDOT / Clave DOT
subdivision: Mapped[Optional[str]] = mapped_column(String(20)) # SUBDIVISION / Subdivisión
acts_as: Mapped[Optional[str]] = mapped_column(String(20)) # FUNGECOMOCO / Funge como
movement_type: Mapped[Optional[str]] = mapped_column(String(31)) # TIPOMOV / Tipo de movimiento
office_document: Mapped[Optional[str]] = mapped_column(String(30)) # OFICIO / Oficio
reason_export: Mapped[Optional[str]] = mapped_column(String(1)) # RAZONEXPORTACION / Razón de exportación
signature_key: Mapped[Optional[str]] = mapped_column(String(10)) # CLAVEFIRMA / Clave de firma
# SM specific
sem_id: Mapped[Optional[int]] = mapped_column(Integer) # SEM / ID SEM (de SFacEntradaSM/SFacSalidaSM)
# Relationship
header: Mapped["InvoiceHeader"] = relationship(
back_populates="compliance_mx")
header: Mapped["InvoiceHeader"] = relationship(back_populates="compliance_mx")
# --- 3. Financials (invoice_financials) ---
class InvoiceFinancials(Base, TenantScopedMixin, TimestampMixin):
__tablename__ = "invoice_financials"
__table_args__ = (
{"schema": "a76"},
)
__table_args__ = ({"schema": "a76"},)
id: Mapped[int] = mapped_column(
BigInteger, primary_key=True, autoincrement=True)
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
invoice_id: Mapped[int] = mapped_column(ForeignKey("a76.invoice_header.id"))
currency: Mapped[Optional[str]] = mapped_column(String(3)) # CLAVEMONEDA
currency_type: Mapped[Optional[str]] = mapped_column(ForeignKey("public.currency_types.code")) # TIPOCLAVEMONEDA
exchange_rate: Mapped[Optional[float]] = mapped_column(Numeric(13, 6)) # TIPOCAMBIO
# Currency
currency: Mapped[Optional[str]] = mapped_column(String(3)) # CLAVEMONEDA / Clave de moneda
currency_type: Mapped[Optional[str]] = mapped_column(ForeignKey("public.currency_types.code")) # TIPOMONEDA / TIPOCLAVEMONEDA
exchange_rate: Mapped[Optional[float]] = mapped_column(Numeric(13, 6)) # TIPOCAMBIO / Tipo de cambio
exchange_rate_mm: Mapped[Optional[float]] = mapped_column(Numeric(13, 6)) # TIPOCAMBIOMM / Tipo de cambio moneda a moneda
# Merchandise Values
value_mn: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALORIMPOMN/EXPOMN
value_me: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0)
customs_value_mn: Mapped[Optional[float]] = mapped_column( Numeric(23, 8), default=0) # VALORADUANASMN
# Merchandise Values (MN = National Currency, ME = Foreign Currency, MC = Third Currency)
value_mn: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALORIMPOMN/VALOREXPOMN/VALORENTMN/VALORSALMN
value_me: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALORIMPOME/VALOREXPOME/VALORENTME/VALORSALME
value_mc: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALORIMPOMC/VALOREXPOMC
# Customs Value
customs_value_mn: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALORADUANASMN / Valor en aduanas MN
customs_value_me: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALORADUANASME / Valor en aduanas ME
# Costs & Taxes
freight: Mapped[Optional[float]] = mapped_column(Numeric(19, 8), default=0) # FLETE
insurance: Mapped[Optional[float]] = mapped_column(Numeric(19, 8), default=0) # VALSEGUROS/SEGUROS
iva_mn: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # IVAEXPOMN / VALORIVAMN
iva_factor: Mapped[Optional[float]] = mapped_column(Numeric(17, 4)) # FACTORIVA
# Raw Materials
raw_material_value_mn: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALORMPMN / Valor materia prima MN
raw_material_value_me: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALORMPME / Valor materia prima ME
# Aggregate Value
aggregate_value_mn: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALORAGREMN / Valor agregado MN
aggregate_value_me: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALORAGREME / Valor agregado ME
aggregate_value_mc: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALORAGREMC / Valor agregado MC
# Mexican Merchandise Value
mexican_value_mn: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALORVMEXMN / Valor mercancía mexicana MN
mexican_value_me: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALORVMEXME / Valor mercancía mexicana ME
mexican_value_mc: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALORVMEXMC / Valor mercancía mexicana MC
# National Packaging
national_packaging_mn: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALEMPAQUENACMN / Valor empaque nacional MN
national_packaging_me: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALEMPAQUENACME / Valor empaque nacional ME
national_packaging_mc: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALEMPAQUENACMC / Valor empaque nacional MC
# Costs & Increments
freight: Mapped[Optional[float]] = mapped_column(Numeric(19, 8), default=0) # FLETE / Flete
insurance: Mapped[Optional[float]] = mapped_column(Numeric(19, 8), default=0) # SEGUROS / Seguros
insurance_value: Mapped[Optional[float]] = mapped_column(Numeric(19, 8), default=0) # VALSEGUROS / Valor seguros
packaging: Mapped[Optional[float]] = mapped_column(Numeric(19, 8), default=0) # EMBALAJES / Embalajes
other_increments: Mapped[Optional[float]] = mapped_column(Numeric(19, 8), default=0) # OTROSINCREMENTA / Otros incrementables
total_increments_mn: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # TOTALINCREMMN / Total incrementables MN
total_increments_me: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # TOTALINCREMME / Total incrementables ME
# Taxes
iva_mn: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # IVAEXPOMN/VALORIVAMN / IVA en MN
iva_me: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # IVAEXPOME/VALORIVAME / IVA en ME
iva_mc: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # IVAEXPOMC / IVA en MC
iva_factor: Mapped[Optional[str]] = mapped_column(String(10)) # FACTORIVA / Factor IVA (puede ser varchar en imports)
tax_value_me: Mapped[Optional[float]] = mapped_column(Numeric(23, 8), default=0) # VALORIMPUESTOME / Valor impuesto ME
seal_value_2500: Mapped[Optional[bool]] = mapped_column(Boolean) # SELLOVALOR2500 / Sello valor 2500
# Weights & Quantities
total_quantity: Mapped[Optional[float]] = mapped_column(Numeric(19, 8)) # CANTEXPO / CANTIMPO
gross_weight: Mapped[Optional[float]] = mapped_column(Numeric(19, 8)) # PESOBRUTO
net_weight: Mapped[Optional[float]] = mapped_column(Numeric(19, 8)) # PESONETO
bundle_count: Mapped[Optional[int]] = mapped_column(Integer) # CANTBULTOS
total_quantity: Mapped[Optional[float]] = mapped_column(Numeric(19, 8)) # CANTEXPO/CANTIMPO / Cantidad total
gross_weight: Mapped[Optional[float]] = mapped_column(Numeric(19, 8)) # PESOBRUTO / Peso bruto
net_weight: Mapped[Optional[float]] = mapped_column(Numeric(19, 8)) # PESONETO / Peso neto
bundle_count: Mapped[Optional[int]] = mapped_column(Integer) # CANTBULTOS / Cantidad de bultos
weight_factor: Mapped[Optional[float]] = mapped_column(Numeric(19, 8)) # FACTORPESO / Factor de peso
# Relationship
header: Mapped["InvoiceHeader"] = relationship(back_populates="financials")
@@ -170,38 +263,65 @@ class InvoiceFinancials(Base, TenantScopedMixin, TimestampMixin):
# --- 4. Logistics (invoice_logistics) ---
class InvoiceLogistics(Base, TenantScopedMixin, TimestampMixin):
__tablename__ = "invoice_logistics"
__table_args__ = (
{"schema": "a76"},
)
__table_args__ = ({"schema": "a76"},)
id: Mapped[int] = mapped_column(
BigInteger, primary_key=True, autoincrement=True)
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
invoice_id: Mapped[int] = mapped_column(ForeignKey("a76.invoice_header.id"))
# Carrier Info
carrier_id: Mapped[Optional[str]] = mapped_column(
String(10)) # TRANSPORTISTA
transport_type: Mapped[TransportType] = mapped_column(
String(15), default="none") # TRANSPORTE
transport_mode: Mapped[Optional[str]] = mapped_column(
String(15)) # MODTRANS
driver_name: Mapped[Optional[str]] = mapped_column(String(80)) # CONDUCTOR
is_rail: Mapped[Optional[str]] = mapped_column(String(2)) # ESFERROCARRIL
rail_id: Mapped[Optional[str]] = mapped_column(
String(31)) # IDFERRORCARRIL
carrier_id: Mapped[Optional[str]] = mapped_column(String(10)) # TRANSPORTISTA / Transportista
carrier_us_id: Mapped[Optional[str]] = mapped_column(String(10)) # TRANSPORTISTAAME / Transportista americano
transport_type: Mapped[TransportType] = mapped_column(String(15), default="none") # TRANSPORTE / Tipo de transporte
transport_mode: Mapped[Optional[str]] = mapped_column(String(15)) # MODTRANS / Modo de transporte
driver_name: Mapped[Optional[str]] = mapped_column(String(80)) # CONDUCTOR / Nombre del conductor
is_rail: Mapped[Optional[str]] = mapped_column(String(2)) # ESFERROCARRIL / Es ferrocarril
rail_id: Mapped[Optional[str]] = mapped_column(String(31)) # IDFERRORCARRIL / ID ferrocarril
# Vehicle & Tracking
vehicle_num: Mapped[Optional[str]] = mapped_column(
String(20)) # NUMVEHICULO / NUMTRAILER
license_plate: Mapped[Optional[str]] = mapped_column(
String(20)) # NUMTRASPORTE
seal_number: Mapped[Optional[str]] = mapped_column(String(15)) # PRECINTO
guide_number: Mapped[Optional[str]] = mapped_column(
String(20)) # NUMEROGUIA
vehicle_num: Mapped[Optional[str]] = mapped_column(String(20)) # NUMVEHICULO / Número de vehículo
license_plate: Mapped[Optional[str]] = mapped_column(String(20)) # NUMTRASPORTE / Número de transporte/placa
license_plate_complete: Mapped[Optional[str]] = mapped_column(String(40)) # NUMTRASPORTECOMPLE / Número transporte completo
trailer_num: Mapped[Optional[str]] = mapped_column(String(20)) # NUMTRAILER / Número de trailer
seal_number: Mapped[Optional[str]] = mapped_column(String(15)) # PRECINTO / Precinto
guide_number: Mapped[Optional[str]] = mapped_column(String(20)) # NUMEROGUIA / Número de guía
bill_number: Mapped[Optional[str]] = mapped_column(String(15)) # BILLNUMBER / Número de bill
reference_number: Mapped[Optional[str]] = mapped_column(String(14)) # NUMREFERENCIA / Número de referencia
shipment_number: Mapped[Optional[str]] = mapped_column(String(19)) # NUMEMBARQUE / Número de embarque
# Incoterms
incoterm: Mapped[Optional[str]] = mapped_column(String(5)) # INCOTERM / Término de comercio internacional
# Identifiers & Complements
identifier_1: Mapped[Optional[str]] = mapped_column(String(2)) # IDENTIFICADOR / Identificador 1
complement_1: Mapped[Optional[str]] = mapped_column(String(30)) # COMPLEMENTO1 / Complemento 1
identifier_2: Mapped[Optional[str]] = mapped_column(String(2)) # IDENTIFICADOR2 / Identificador 2
complement_2: Mapped[Optional[str]] = mapped_column(String(30)) # COMPLEMENTO2 / Complemento 2
# Weight & Container Info
weight_type: Mapped[Optional[str]] = mapped_column(String(6)) # TIPOPESO / Tipo de peso
container_types: Mapped[Optional[str]] = mapped_column(String(500)) # CONTENEDORESTIPO / Tipos de contenedores
vehicle_data: Mapped[Optional[str]] = mapped_column(String(500)) # DATOSVEHICULO / Datos del vehículo
# Locations & Routes
origin_location: Mapped[Optional[str]] = mapped_column(String(200)) # ORIGENUBICACION / Ubicación de origen
destination_location: Mapped[Optional[str]] = mapped_column(String(200)) # DESTINOUBICACION / Ubicación de destino
transport_itinerary: Mapped[Optional[str]] = mapped_column(String(1000)) # ITINERARIOTRANPORTE / Itinerario del transporte
destination_goods: Mapped[Optional[str]] = mapped_column(String(50)) # DESTINOMCIA / Destino de mercancía
# Logistics Dates
entry_exit_date: Mapped[Optional[datetime]] = mapped_column(
Date) # FECHAENTRADA / FECHAENVIO
entry_exit_date: Mapped[Optional[datetime]] = mapped_column(Date) # FECHAENTRADA/FECHAENVIO/FECHARECIBO / Fecha entrada/salida
delivery_date: Mapped[Optional[datetime]] = mapped_column(Date) # FECHAENTREGA / Fecha de entrega
# Delivery Control
delivered_status: Mapped[Optional[str]] = mapped_column(String(2)) # ENTREGADO / Estado de entrega
received_by: Mapped[Optional[str]] = mapped_column(String(50)) # RECIBIDOPOR / Recibido por
# Payment Info
payment_date: Mapped[Optional[datetime]] = mapped_column(Date) # FECHAPAGO / Fecha de pago
payment_receipt_num: Mapped[Optional[str]] = mapped_column(String(20)) # NUMRECIBOPAGO / Número de recibo de pago
# CTM Process
is_ctm_process: Mapped[Optional[str]] = mapped_column(String(2)) # SETRATAPROCESOCTM / Se trata de proceso CTM
# Relationship
header: Mapped["InvoiceHeader"] = relationship(back_populates="logistics")
@@ -210,25 +330,18 @@ class InvoiceLogistics(Base, TenantScopedMixin, TimestampMixin):
# --- 5. Sales Order Details (invoice_sales_details) ---
class InvoiceSalesDetails(Base, TenantScopedMixin, TimestampMixin):
__tablename__ = "invoice_sales_details"
__table_args__ = (
{"schema": "a76"},
)
__table_args__ = ({"schema": "a76"},)
id: Mapped[int] = mapped_column(
BigInteger, primary_key=True, autoincrement=True)
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
invoice_id: Mapped[int] = mapped_column(ForeignKey("a76.invoice_header.id"))
line_number: Mapped[int] = mapped_column(Integer) # LINEA
sales_order: Mapped[Optional[str]] = mapped_column(
String(20)) # ORDENVENTA
line_number: Mapped[int] = mapped_column(Integer) # LINEA / Número de línea
sales_order: Mapped[Optional[str]] = mapped_column(String(20)) # ORDENVENTA / Orden de venta
# Specific Custom Fields
colors_description: Mapped[Optional[str]
] = mapped_column(String(49)) # COLORES
square_color_code: Mapped[Optional[str]] = mapped_column(
String(1)) # COLORCUADRITO
line_bundles: Mapped[Optional[int]] = mapped_column(
Integer) # CANTBULTOS (de la linea)
colors_description: Mapped[Optional[str]] = mapped_column(String(49)) # COLORES / Descripción de colores
square_color_code: Mapped[Optional[str]] = mapped_column(String(1)) # COLORCUADRITO / Código de color cuadrito
line_bundles: Mapped[Optional[int]] = mapped_column(Integer) # CANTBULTOS / Cantidad de bultos de la línea
# Relationship
header: Mapped["InvoiceHeader"] = relationship(back_populates="details")
@@ -237,23 +350,12 @@ class InvoiceSalesDetails(Base, TenantScopedMixin, TimestampMixin):
# --- 6. Collections (invoice_collections) ---
class InvoiceCollections(Base, TenantScopedMixin, TimestampMixin):
__tablename__ = "invoice_collections"
__table_args__ = (
{"schema": "a76"},
)
__table_args__ = ({"schema": "a76"},)
id: Mapped[int] = mapped_column(
BigInteger, primary_key=True, autoincrement=True)
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
invoice_id: Mapped[int] = mapped_column(ForeignKey("a76.invoice_header.id"))
concept: Mapped[Optional[str]] = mapped_column(String(100)) # CONCEPTO
is_collected: Mapped[Optional[int]] = mapped_column(Integer) # COBRADO
collection_date: Mapped[Optional[datetime]
] = mapped_column(Date) # FECHACOBRANZA
amount: Mapped[Optional[float]] = mapped_column(Numeric(23, 8)) # VALOR
collector_user: Mapped[Optional[str]] = mapped_column(
String(20)) # FACTCOBRADOR
# Relationship
header: Mapped["InvoiceHeader"] = relationship(
back_populates="collections")
line_number: Mapped[int] = mapped_column(Integer) # LINEA / Número de línea
invoice_number: Mapped[Optional[str]] = mapped_column(String(15)) # FACTURA / Número de factura
concept: Mapped[Optional[str]] = mapped_column(String(100)) # CONCEPTO / Conce