diff --git a/.gitignore b/.gitignore index 0af971f5..17d85cdc 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,4 @@ node_modules/ # Docker *.dockerignore +postgres-data/ \ No newline at end of file diff --git a/backend/api/v1/modules/a76/invoices/models.py b/backend/api/v1/modules/a76/invoices/models.py index 7f787def..a5337664 100644 --- a/backend/api/v1/modules/a76/invoices/models.py +++ b/backend/api/v1/modules/a76/invoices/models.py @@ -10,74 +10,98 @@ 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) + system: Mapped[Optional[str]] = mapped_column(String(10)) # SISTEMA / Sistema de origen <-- no tiene campo en la antigua base de datos, sera para fixed-asset(scaf), inventory(scaii) + 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 +113,150 @@ 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 + is_pedimento_pending: Mapped[Optional[bool]] = mapped_column(Boolean, default=False) # PED_PENDIENTE_ASIGNAR (Mapear 1 -> True, 0 -> False) + + # 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 +265,67 @@ 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 Info + carrier_id: Mapped[Optional[str]] = mapped_column(String(10)) # TRANSPORTISTA / Transportista + transport_id: Mapped[Optional[str]] = mapped_column(String(10)) # NUMTRAILER / Transportista + transport_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_num: Mapped[Optional[str]] = mapped_column(String(20)) # NUMTRASPORTE / Número 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 +334,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 +354,15 @@ 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 - + 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 / Concepto + # Relationship - header: Mapped["InvoiceHeader"] = relationship( - back_populates="collections") + header: Mapped["InvoiceHeader"] = relationship(back_populates="collections") + concept: Mapped[Optional[str]] = mapped_column(String(100)) # CONCEPTO / Conce \ No newline at end of file diff --git a/backend/api/v1/modules/a76/invoices/schemas.py b/backend/api/v1/modules/a76/invoices/schemas.py index 8075cd94..2afaec50 100644 --- a/backend/api/v1/modules/a76/invoices/schemas.py +++ b/backend/api/v1/modules/a76/invoices/schemas.py @@ -8,8 +8,10 @@ from .models import OperationType # --- Base Schemas --- class InvoiceHeaderBase(BaseModel): """Base fields for Invoice Header""" + system: Optional[str] = Field( + None, max_length=10, description="System of origin") operation_type: Optional[OperationType] = Field( - None, max_length=20, description="Operation type: imp/exp") + None, max_length=10, description="Operation type: imp/exp/sm/ctm") invoice_type: Optional[str] = Field( None, max_length=5, description="Invoice type key") invoice_number: Optional[str] = Field( @@ -20,20 +22,64 @@ class InvoiceHeaderBase(BaseModel): None, max_length=50, description="Purchase order") related_doc_id: Optional[int] = Field( None, description="Related document ID for rectifications") + alternate_invoice: Optional[str] = Field( + None, max_length=99, description="Alternate invoice") + invoice_ref: Optional[str] = Field( + None, max_length=19, description="Invoice reference") + proforma_number: Optional[str] = Field( + None, max_length=20, description="Proforma number") invoice_date: Optional[date] = Field(None, description="Invoice date") + emission_date: Optional[date] = Field(None, description="Emission date") is_updated: Optional[bool] = Field(None, description="Status") + updated_date: Optional[datetime] = Field(None, description="Update date") + who_updated: Optional[str] = Field( + None, max_length=20, description="Who updated") + capture_user: Optional[str] = Field( + None, max_length=20, description="Capture user") traffic_light_status: Optional[str] = Field( - None, max_length=50, description="Traffic light status (SEMAFORO)") + None, max_length=50, description="Traffic light status") process_log: Optional[str] = Field( None, max_length=300, description="Processing log") + status_rec: Optional[int] = Field(None, description="Reception status") + status_rep: Optional[str] = Field( + None, max_length=2, description="Report status") + observation_es: Optional[str] = Field( + None, description="Observations in Spanish") + observation_en: Optional[str] = Field( + None, description="Observations in English") comments_status: Optional[str] = Field( - None, description="Comments and observations") + None, description="Comments status") + vu_observations: Optional[str] = Field( + None, max_length=500, description="VUCEM observations") cfdi_uuid: Optional[str] = Field( None, max_length=100, description="CFDI UUID") path_pdf: Optional[str] = Field( None, max_length=500, description="Path to PDF file") path_xml: Optional[str] = Field( None, max_length=500, description="Path to XML file") + subcompany: Optional[str] = Field( + None, max_length=5, description="Subcompany") + party_count: Optional[int] = Field(None, description="Quantity of parties") + generate_id: Optional[str] = Field( + None, max_length=1, description="Generate ID") + generate_desc_parties: Optional[str] = Field( + None, max_length=12, description="Generate description of parties") + apply_manual_discount: Optional[str] = Field( + None, max_length=1, description="Apply manual discount") + is_bulk: Optional[bool] = Field(None, description="Is bulk") + download_substance: Optional[bool] = Field( + None, description="Download substance") + download_class: Optional[bool] = Field( + None, description="Download class") + download_def: Optional[bool] = Field( + None, description="Definitive download") + payment_terms: Optional[str] = Field( + None, max_length=200, description="Payment terms") + handling_fees: Optional[Decimal] = Field(None, description="Handling fees") + option_iv18: Optional[str] = Field( + None, max_length=50, description="Option IV18") + enajenation_goods: Optional[bool] = Field( + None, description="Enajenation of goods") class InvoiceComplianceMxBase(BaseModel): @@ -41,21 +87,105 @@ class InvoiceComplianceMxBase(BaseModel): pedimento: Optional[str] = Field( None, max_length=19, description="Pedimento number") pedimento_code: Optional[str] = Field( - None, max_length=5, description="Pedimento code (R1/K1)") + None, max_length=5, description="Pedimento code (R1)") + pedimento_k1: Optional[str] = Field( + None, max_length=15, description="Pedimento K1") remesa: Optional[int] = Field(None, description="Remesa") aduana: Optional[str] = Field( None, max_length=5, description="Customs office") - customs_agent: Optional[str] = Field( - None, max_length=10, description="Customs agent") + port_of_entry: Optional[str] = Field( + None, max_length=6, description="Port of entry") + destination: Optional[str] = Field( + None, max_length=3, description="Destination code") + manifest_number: Optional[str] = Field( + None, max_length=15, description="Manifest number") + provider_header: Optional[str] = Field( + None, max_length=20, description="Provider header") + provider_id: Optional[str] = Field( + None, description="Provider ID") + sold_to_header: Optional[str] = Field( + None, max_length=20, description="Sold to header") + sold_to_id: Optional[str] = Field( + None, description="Sold to ID") + shipped_to_header: Optional[str] = Field( + None, max_length=20, description="Shipped to header") + shipped_to_id: Optional[str] = Field( + None, description="Shipped to ID") + shipped_by_header: Optional[str] = Field( + None, max_length=20, description="Shipped by header") + shipped_by_id: Optional[str] = Field( + None, description="Shipped by ID") + customs_broker_id: Optional[str] = Field( + None, description="Customs broker ID") + customs_broker_us_id: Optional[str] = Field( + None, description="US customs broker ID") + broker_invoice_num: Optional[str] = Field( + None, max_length=20, description="Broker invoice number") + broker_invoice_date: Optional[date] = Field( + None, description="Broker invoice date") is_mixed: Optional[bool] = Field( None, description="Is mixed operation") waste_type: Optional[str] = Field( None, max_length=1, description="Waste type") + scrap_type: Optional[str] = Field( + None, max_length=1, description="Scrap type") appendix_17: Optional[int] = Field(None, description="Appendix 17") + is_regime_change: Optional[str] = Field( + None, max_length=1, description="Is regime change") + which_exchange_rate: Optional[str] = Field( + None, max_length=5, description="Which exchange rate") + value_method: Optional[str] = Field( + None, max_length=2, description="Value method") + act_value: Optional[str] = Field( + None, max_length=5, description="Act value") + is_pedimento_pending: Optional[bool] = Field( + None, description="Is pedimento pending") + is_owner_of_goods: Optional[str] = Field( + None, max_length=2, description="Is owner of goods") + generate_balances: Optional[str] = Field( + None, max_length=2, description="Generate balances") + was_reviewed_by_company: Optional[bool] = Field( + None, description="Was reviewed by company") edocument: Optional[str] = Field( None, max_length=50, description="E-document") electronic_signature: Optional[str] = Field( None, max_length=999, description="Electronic signature") + certificate_number: Optional[str] = Field( + None, max_length=99, description="Certificate number") + niu_number: Optional[str] = Field( + None, max_length=19, description="NIU number") + bill_of_lading_count: Optional[str] = Field( + None, max_length=12, description="Bill of lading count") + addendum_vu: Optional[str] = Field( + None, max_length=204, description="VUCEM addendum") + origin_destination_cove: Optional[str] = Field( + None, max_length=19, description="Origin/Destination COVE") + vucem_operation_num: Optional[str] = Field( + None, max_length=19, description="VUCEM operation number") + customs_person_line: Optional[int] = Field( + None, description="Customs person line") + contingency_mode: Optional[bool] = Field( + None, description="Contingency mode") + enclosure: Optional[str] = Field( + None, max_length=4, description="Enclosure") + guide_type_to_identify: Optional[str] = Field( + None, max_length=1, description="Guide type to identify") + location: Optional[str] = Field( + None, max_length=200, description="Location") + dot_code: Optional[str] = Field( + None, max_length=20, description="DOT code") + subdivision: Optional[str] = Field( + None, max_length=20, description="Subdivision") + acts_as: Optional[str] = Field( + None, max_length=20, description="Acts as") + movement_type: Optional[str] = Field( + None, max_length=31, description="Movement type") + office_document: Optional[str] = Field( + None, max_length=30, description="Office document") + reason_export: Optional[str] = Field( + None, max_length=1, description="Reason for export") + signature_key: Optional[str] = Field( + None, max_length=10, description="Signature key") sem_id: Optional[int] = Field(None, description="SEM ID") @@ -63,44 +193,148 @@ class InvoiceFinancialsBase(BaseModel): """Base fields for Financials""" currency: Optional[str] = Field( None, max_length=3, description="Currency code") + currency_type: Optional[str] = Field( + None, description="Currency type") exchange_rate: Optional[Decimal] = Field(None, description="Exchange rate") + exchange_rate_mm: Optional[Decimal] = Field( + None, description="Exchange rate currency to currency") value_mn: Optional[Decimal] = Field(None, description="Value in MXN") value_me: Optional[Decimal] = Field( None, description="Value in foreign currency") + value_mc: Optional[Decimal] = Field( + None, description="Value in third currency") customs_value_mn: Optional[Decimal] = Field( None, description="Customs value in MXN") + customs_value_me: Optional[Decimal] = Field( + None, description="Customs value in foreign currency") + raw_material_value_mn: Optional[Decimal] = Field( + None, description="Raw material value in MXN") + raw_material_value_me: Optional[Decimal] = Field( + None, description="Raw material value in foreign currency") + aggregate_value_mn: Optional[Decimal] = Field( + None, description="Aggregate value in MXN") + aggregate_value_me: Optional[Decimal] = Field( + None, description="Aggregate value in foreign currency") + aggregate_value_mc: Optional[Decimal] = Field( + None, description="Aggregate value in third currency") + mexican_value_mn: Optional[Decimal] = Field( + None, description="Mexican merchandise value in MXN") + mexican_value_me: Optional[Decimal] = Field( + None, description="Mexican merchandise value in foreign currency") + mexican_value_mc: Optional[Decimal] = Field( + None, description="Mexican merchandise value in third currency") + national_packaging_mn: Optional[Decimal] = Field( + None, description="National packaging in MXN") + national_packaging_me: Optional[Decimal] = Field( + None, description="National packaging in foreign currency") + national_packaging_mc: Optional[Decimal] = Field( + None, description="National packaging in third currency") freight: Optional[Decimal] = Field(None, description="Freight cost") insurance: Optional[Decimal] = Field(None, description="Insurance cost") + insurance_value: Optional[Decimal] = Field( + None, description="Insurance value") + packaging: Optional[Decimal] = Field(None, description="Packaging") + other_increments: Optional[Decimal] = Field( + None, description="Other increments") + total_increments_mn: Optional[Decimal] = Field( + None, description="Total increments in MXN") + total_increments_me: Optional[Decimal] = Field( + None, description="Total increments in foreign currency") iva_mn: Optional[Decimal] = Field(None, description="IVA in MXN") - iva_factor: Optional[Decimal] = Field(None, description="IVA factor") + iva_me: Optional[Decimal] = Field( + None, description="IVA in foreign currency") + iva_mc: Optional[Decimal] = Field( + None, description="IVA in third currency") + iva_factor: Optional[str] = Field( + None, max_length=10, description="IVA factor") + tax_value_me: Optional[Decimal] = Field( + None, description="Tax value in foreign currency") + seal_value_2500: Optional[bool] = Field( + None, description="Seal value 2500") total_quantity: Optional[Decimal] = Field( None, description="Total quantity") gross_weight: Optional[Decimal] = Field(None, description="Gross weight") net_weight: Optional[Decimal] = Field(None, description="Net weight") bundle_count: Optional[int] = Field(None, description="Bundle count") + weight_factor: Optional[Decimal] = Field(None, description="Weight factor") class InvoiceLogisticsBase(BaseModel): """Base fields for Logistics""" carrier_id: Optional[str] = Field( None, max_length=10, description="Carrier ID") + transport_id: Optional[str] = Field( + None, max_length=10, description="Transport ID") + transport_us_id: Optional[str] = Field( + None, max_length=10, description="US transport ID") + transport_type: Optional[str] = Field( + None, max_length=15, description="Transport type") + transport_num: Optional[str] = Field( + None, max_length=20, description="Transport number") transport_mode: Optional[str] = Field( None, max_length=15, description="Transport mode") driver_name: Optional[str] = Field( None, max_length=80, description="Driver name") is_rail: Optional[str] = Field( None, max_length=2, description="Is rail transport") - rail_id: Optional[str] = Field(None, max_length=31, description="Rail ID") + rail_id: Optional[str] = Field( + None, max_length=31, description="Rail ID") vehicle_num: Optional[str] = Field( None, max_length=20, description="Vehicle number") license_plate: Optional[str] = Field( None, max_length=20, description="License plate") + license_plate_complete: Optional[str] = Field( + None, max_length=40, description="Complete license plate") + trailer_num: Optional[str] = Field( + None, max_length=20, description="Trailer number") seal_number: Optional[str] = Field( None, max_length=15, description="Seal number") guide_number: Optional[str] = Field( None, max_length=20, description="Guide number") + bill_number: Optional[str] = Field( + None, max_length=15, description="Bill number") + reference_number: Optional[str] = Field( + None, max_length=14, description="Reference number") + shipment_number: Optional[str] = Field( + None, max_length=19, description="Shipment number") + incoterm: Optional[str] = Field( + None, max_length=5, description="Incoterm") + identifier_1: Optional[str] = Field( + None, max_length=2, description="Identifier 1") + complement_1: Optional[str] = Field( + None, max_length=30, description="Complement 1") + identifier_2: Optional[str] = Field( + None, max_length=2, description="Identifier 2") + complement_2: Optional[str] = Field( + None, max_length=30, description="Complement 2") + weight_type: Optional[str] = Field( + None, max_length=6, description="Weight type") + container_types: Optional[str] = Field( + None, max_length=500, description="Container types") + vehicle_data: Optional[str] = Field( + None, max_length=500, description="Vehicle data") + origin_location: Optional[str] = Field( + None, max_length=200, description="Origin location") + destination_location: Optional[str] = Field( + None, max_length=200, description="Destination location") + transport_itinerary: Optional[str] = Field( + None, max_length=1000, description="Transport itinerary") + destination_goods: Optional[str] = Field( + None, max_length=50, description="Destination of goods") entry_exit_date: Optional[date] = Field( None, description="Entry/Exit date") + delivery_date: Optional[date] = Field( + None, description="Delivery date") + delivered_status: Optional[str] = Field( + None, max_length=2, description="Delivered status") + received_by: Optional[str] = Field( + None, max_length=50, description="Received by") + payment_date: Optional[date] = Field( + None, description="Payment date") + payment_receipt_num: Optional[str] = Field( + None, max_length=20, description="Payment receipt number") + is_ctm_process: Optional[str] = Field( + None, max_length=2, description="Is CTM process") class InvoiceSalesDetailsBase(BaseModel): @@ -117,13 +351,10 @@ class InvoiceSalesDetailsBase(BaseModel): class InvoiceCollectionsBase(BaseModel): """Base fields for Collections""" + line_number: int = Field(..., description="Line number") + invoice_number: Optional[str] = Field( + None, max_length=15, description="Invoice number") concept: Optional[str] = Field(None, max_length=100, description="Concept") - is_collected: Optional[int] = Field(None, description="Is collected flag") - collection_date: Optional[date] = Field( - None, description="Collection date") - amount: Optional[Decimal] = Field(None, description="Amount") - collector_user: Optional[str] = Field( - None, max_length=20, description="Collector user") # --- Create Schemas --- @@ -186,7 +417,7 @@ class InvoiceSalesDetailsUpdate(InvoiceSalesDetailsBase): class InvoiceCollectionsUpdate(InvoiceCollectionsBase): """Schema for updating Collections""" - pass + line_number: Optional[int] = None class InvoiceHeaderUpdate(InvoiceHeaderBase): @@ -210,6 +441,7 @@ class InvoiceComplianceMxResponse(InvoiceComplianceMxBase): class InvoiceFinancialsResponse(InvoiceFinancialsBase): """Schema for Financials response""" + id: int invoice_id: int class Config: @@ -218,7 +450,7 @@ class InvoiceFinancialsResponse(InvoiceFinancialsBase): class InvoiceLogisticsResponse(InvoiceLogisticsBase): """Schema for Logistics response""" - logistics_id: int + id: int invoice_id: int class Config: @@ -227,7 +459,7 @@ class InvoiceLogisticsResponse(InvoiceLogisticsBase): class InvoiceSalesDetailsResponse(InvoiceSalesDetailsBase): """Schema for Sales Details response""" - detail_id: int + id: int invoice_id: int class Config: @@ -236,7 +468,7 @@ class InvoiceSalesDetailsResponse(InvoiceSalesDetailsBase): class InvoiceCollectionsResponse(InvoiceCollectionsBase): """Schema for Collections response""" - collection_id: int + id: int invoice_id: int class Config: diff --git a/estructura.txt b/estructura.txt deleted file mode 100644 index aa2beccb..00000000 --- a/estructura.txt +++ /dev/null @@ -1,1190 +0,0 @@ -. -├── azure.crt -├── backend -│   ├── alembic -│   │   ├── env.py -│   │   ├── README -│   │   ├── script.py.mako -│   │   └── versions -│   │   ├── 531bf8cdae06_create_material_types_table.py -│   │   └── 7937209f9718_seed_initial_data.py -│   ├── alembic.ini -│   ├── api -│   │   └── v1 -│   │   ├── common -│   │   │   ├── base_models.py -│   │   │   ├── crud_routes.py -│   │   │   ├── dto_mixins.py -│   │   │   └── tenant_crud_routes.py -│   │   ├── modules -│   │   │   ├── a24 -│   │   │   │   ├── fa -│   │   │   │   │   └── fa_classes -│   │   │   │   │   └── models.py -│   │   │   │   └── inv -│   │   │   │   ├── inv_classes -│   │   │   │   │   └── models.py -│   │   │   │   └── location -│   │   │   │   ├── dto.py -│   │   │   │   ├── __init__.py -│   │   │   │   ├── models.py -│   │   │   │   ├── routes.py -│   │   │   │   └── service.py -│   │   │   ├── a76 -│   │   │   │   ├── classes -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── __init__.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── service.py -│   │   │   │   │   └── test_classes.py -│   │   │   │   ├── clients_and_providers -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── __init__.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── service.py -│   │   │   │   │   └── test_client_and_provider.py -│   │   │   │   ├── country_rule_oct -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── services.py -│   │   │   │   │   └── test_country_rule_oct.py -│   │   │   │   ├── customs_brokers -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   └── services.py -│   │   │   │   ├── fraction_rule_octave -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── services.py -│   │   │   │   │   └── test_fraction_rule_octave.py -│   │   │   │   ├── general_catalogs -│   │   │   │   │   ├── classification_concepts -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── __init__.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   └── service.py -│   │   │   │   │   ├── company -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── __init__.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   ├── service.py -│   │   │   │   │   │   └── test_company.py -│   │   │   │   │   ├── concepts -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── __init__.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   └── service.py -│   │   │   │   │   ├── customs_broker_concepts -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── __init__.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   └── service.py -│   │   │   │   │   ├── doda -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── __init__.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   └── service.py -│   │   │   │   │   ├── electronic_notices -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── __init__.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   └── service.py -│   │   │   │   │   ├── equivalencies -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── __init__.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   └── service.py -│   │   │   │   │   ├── error_catalogs -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── __init__.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   └── service.py -│   │   │   │   │   ├── exchange_rate -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   ├── services.py -│   │   │   │   │   │   └── test_exchange_rate.py -│   │   │   │   │   ├── identifiers -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── __init__.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   └── service.py -│   │   │   │   │   ├── inpc -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── __init__.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   └── service.py -│   │   │   │   │   ├── legends -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── __init__.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   └── service.py -│   │   │   │   │   ├── multi_currency_types -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── __init__.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   └── service.py -│   │   │   │   │   ├── packages -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   ├── services.py -│   │   │   │   │   │   └── test_package.py -│   │   │   │   │   ├── ports -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── __init__.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   └── service.py -│   │   │   │   │   ├── prevalidators -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── __init__.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   └── service.py -│   │   │   │   │   ├── seal -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   ├── services.py -│   │   │   │   │   │   └── test_seal.py -│   │   │   │   │   ├── signatures -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── __init__.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   └── service.py -│   │   │   │   │   ├── unit_conversions -│   │   │   │   │   │   ├── dto.py -│   │   │   │   │   │   ├── __init__.py -│   │   │   │   │   │   ├── models.py -│   │   │   │   │   │   ├── routes.py -│   │   │   │   │   │   └── service.py -│   │   │   │   │   └── units_of_measure -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── __init__.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   └── service.py -│   │   │   │   ├── invoices -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── schemas.py -│   │   │   │   │   └── services.py -│   │   │   │   ├── parts -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── __init__.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── service.py -│   │   │   │   │   └── test_parts.py -│   │   │   │   ├── pedmientos -│   │   │   │   │   ├── dtos -│   │   │   │   │   │   ├── pedimento_config_additional.py -│   │   │   │   │   │   ├── pedimento_config_calculations.py -│   │   │   │   │   │   ├── pedimento_config_parameters.py -│   │   │   │   │   │   ├── pedimento_config_surcharges.py -│   │   │   │   │   │   ├── pedimento_config_update_rectification.py -│   │   │   │   │   │   ├── pedimento_config_updates.py -│   │   │   │   │   │   ├── pedimento_customs_offices.py -│   │   │   │   │   │   ├── pedimento_dates.py -│   │   │   │   │   │   ├── pedimento_decrementables.py -│   │   │   │   │   │   ├── pedimento_incrementables.py -│   │   │   │   │   │   ├── pedimento_indexes.py -│   │   │   │   │   │   ├── pedimento_payments.py -│   │   │   │   │   │   ├── pedimento_rectification_destination.py -│   │   │   │   │   │   ├── pedimento_rectification_origin.py -│   │   │   │   │   │   ├── pedimentos.py -│   │   │   │   │   │   ├── pedimento_transport_means.py -│   │   │   │   │   │   └── pedimento_validation.py -│   │   │   │   │   ├── models -│   │   │   │   │   │   ├── pedimento_config_additional.py -│   │   │   │   │   │   ├── pedimento_config_calculations.py -│   │   │   │   │   │   ├── pedimento_config_parameters.py -│   │   │   │   │   │   ├── pedimento_config_surcharges.py -│   │   │   │   │   │   ├── pedimento_config_update_rectification.py -│   │   │   │   │   │   ├── pedimento_config_updates.py -│   │   │   │   │   │   ├── pedimento_customs_offices.py -│   │   │   │   │   │   ├── pedimento_dates.py -│   │   │   │   │   │   ├── pedimento_decrementables.py -│   │   │   │   │   │   ├── pedimento_incrementables.py -│   │   │   │   │   │   ├── pedimento_indexes.py -│   │   │   │   │   │   ├── pedimento_payments.py -│   │   │   │   │   │   ├── pedimento_rectification_destination.py -│   │   │   │   │   │   ├── pedimento_rectification_origin.py -│   │   │   │   │   │   ├── pedimentos.py -│   │   │   │   │   │   ├── pedimento_transport_means.py -│   │   │   │   │   │   └── pedimento_validation.py -│   │   │   │   │   ├── router.py -│   │   │   │   │   ├── routes -│   │   │   │   │   │   ├── pedimento_config_additional.py -│   │   │   │   │   │   ├── pedimento_config_calculations.py -│   │   │   │   │   │   ├── pedimento_config_parameters.py -│   │   │   │   │   │   ├── pedimento_config_surcharges.py -│   │   │   │   │   │   ├── pedimento_config_update_rectification.py -│   │   │   │   │   │   ├── pedimento_config_updates.py -│   │   │   │   │   │   ├── pedimento_customs_offices.py -│   │   │   │   │   │   ├── pedimento_dates.py -│   │   │   │   │   │   ├── pedimento_decrementables.py -│   │   │   │   │   │   ├── pedimento_incrementables.py -│   │   │   │   │   │   ├── pedimento_indexes.py -│   │   │   │   │   │   ├── pedimento_payments.py -│   │   │   │   │   │   ├── pedimento_rectification_destination.py -│   │   │   │   │   │   ├── pedimento_rectification_origin.py -│   │   │   │   │   │   ├── pedimentos.py -│   │   │   │   │   │   ├── pedimento_transport_means.py -│   │   │   │   │   │   └── pedimento_validation.py -│   │   │   │   │   └── services -│   │   │   │   │   ├── pedimento_config_additional.py -│   │   │   │   │   ├── pedimento_config_calculations.py -│   │   │   │   │   ├── pedimento_config_parameters.py -│   │   │   │   │   ├── pedimento_config_surcharges.py -│   │   │   │   │   ├── pedimento_config_update_rectification.py -│   │   │   │   │   ├── pedimento_config_updates.py -│   │   │   │   │   ├── pedimento_customs_offices.py -│   │   │   │   │   ├── pedimento_dates.py -│   │   │   │   │   ├── pedimento_decrementables.py -│   │   │   │   │   ├── pedimento_incrementables.py -│   │   │   │   │   ├── pedimento_indexes.py -│   │   │   │   │   ├── pedimento_payments.py -│   │   │   │   │   ├── pedimento_rectification_destination.py -│   │   │   │   │   ├── pedimento_rectification_origin.py -│   │   │   │   │   ├── pedimentos.py -│   │   │   │   │   ├── pedimento_transport_means.py -│   │   │   │   │   └── pedimento_validation.py -│   │   │   │   ├── permission_rule_oct -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── services.py -│   │   │   │   │   └── test_permission_rule_oct.py -│   │   │   │   ├── router.py -│   │   │   │   └── transportation -│   │   │   │   ├── drivers -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   └── services.py -│   │   │   │   ├── trailers -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   └── services.py -│   │   │   │   ├── transporters -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   └── services.py -│   │   │   │   └── vehicles -│   │   │   │   ├── dto.py -│   │   │   │   ├── models.py -│   │   │   │   ├── routes.py -│   │   │   │   └── services.py -│   │   │   ├── core -│   │   │   │   ├── auth -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── __init__.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   └── service.py -│   │   │   │   ├── licenses -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── __init__.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   └── service.py -│   │   │   │   ├── router.py -│   │   │   │   ├── tenants -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── __init__.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   └── service.py -│   │   │   │   └── user_tenant -│   │   │   │   ├── dto.py -│   │   │   │   ├── models.py -│   │   │   │   ├── routes.py -│   │   │   │   └── service.py -│   │   │   └── public -│   │   │   ├── __init__.py -│   │   │   ├── reference_data -│   │   │   │   ├── code_pedimento_regimens -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── seed.py -│   │   │   │   │   └── test_code_pedimento_regimens.py -│   │   │   │   ├── conftest.py -│   │   │   │   ├── containers -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── seed.py -│   │   │   │   │   └── test_containers.py -│   │   │   │   ├── countries -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── seed.py -│   │   │   │   │   └── test_countries.py -│   │   │   │   ├── currency_types -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── seed.py -│   │   │   │   │   └── test_currency_types.py -│   │   │   │   ├── customs_sections -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── seed.py -│   │   │   │   │   └── test_customs_sections.py -│   │   │   │   ├── customs_warehouses -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── seed.py -│   │   │   │   │   └── test_customs_warehouses.py -│   │   │   │   ├── incoterms -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── seed.py -│   │   │   │   │   └── test_incoterms.py -│   │   │   │   ├── invoice_types -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── seed.py -│   │   │   │   │   └── test_invoice_types.py -│   │   │   │   ├── material_types -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── seed.py -│   │   │   │   │   └── test_material_types.py -│   │   │   │   ├── payment_methods -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── seed.py -│   │   │   │   │   └── test_payment_methods.py -│   │   │   │   ├── pedimento_codes -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── seed.py -│   │   │   │   │   └── test_pedimento_codes.py -│   │   │   │   ├── pedimento_regimens -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── seed.py -│   │   │   │   │   └── test_pedimento_regimens.py -│   │   │   │   ├── router.py -│   │   │   │   ├── sectors -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── seed.py -│   │   │   │   │   └── test_sectors.py -│   │   │   │   ├── states -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── seed.py -│   │   │   │   │   └── test_states.py -│   │   │   │   ├── trailer_types -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   └── services.py -│   │   │   │   ├── transport_modes -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── seed.py -│   │   │   │   │   └── test_transport_modes.py -│   │   │   │   ├── transport_types -│   │   │   │   │   ├── dto.py -│   │   │   │   │   ├── models.py -│   │   │   │   │   ├── routes.py -│   │   │   │   │   ├── seed.py -│   │   │   │   │   └── test_transport_types.py -│   │   │   │   └── valuation_methods -│   │   │   │   ├── dto.py -│   │   │   │   ├── models.py -│   │   │   │   ├── routes.py -│   │   │   │   ├── seed.py -│   │   │   │   └── test_valuation_methods.py -│   │   │   └── router.py -│   │   └── router.py -│   ├── core -│   │   ├── config.py -│   │   ├── database.py -│   │   ├── __init__.py -│   │   ├── middleware.py -│   │   └── security.py -│   ├── Dockerfile -│   ├── main.py -│   ├── __pycache__ -│   └── requirements.txt -├── docker-compose.yml -├── docs -│   ├── a76.json -│   ├── ARCHITECTURE.md -│   ├── KEYCLOAK_SETUP.md -│   ├── MICROSOFT_SSO_SETUP.md -│   └── VERIFICAR_MICROSOFT_CONFIG.md -├── estructura.txt -├── frontend -│   ├── components.json -│   ├── Dockerfile -│   ├── e2e -│   │   └── demo.test.ts -│   ├── eslint.config.js -│   ├── messages -│   │   ├── en.json -│   │   └── es.json -│   ├── node_modules -│   ├── package.json -│   ├── playwright.config.ts -│   ├── pnpm-lock.yaml -│   ├── pnpm-workspace.yaml -│   ├── project.inlang -│   │   ├── cache -│   │   │   └── plugins -│   │   │   ├── 2sy648wh9sugi -│   │   │   └── ygx0uiahq6uw -│   │   ├── project_id -│   │   └── settings.json -│   ├── README.md -│   ├── src -│   │   ├── app.css -│   │   ├── app.d.ts -│   │   ├── app.html -│   │   ├── demo.spec.ts -│   │   ├── hooks.server.ts -│   │   ├── hooks.ts -│   │   ├── lib -│   │   │   ├── api -│   │   │   │   └── dashboard -│   │   │   │   ├── a76 -│   │   │   │   │   ├── classes.ts -│   │   │   │   │   ├── clients-providers.ts -│   │   │   │   │   ├── customs-brokers.ts -│   │   │   │   │   ├── general_catalogs -│   │   │   │   │   │   ├── classification-concepts.ts -│   │   │   │   │   │   ├── company.ts -│   │   │   │   │   │   ├── concepts.ts -│   │   │   │   │   │   ├── customs-broker-concepts.ts -│   │   │   │   │   │   ├── doda.ts -│   │   │   │   │   │   ├── electronic-notices.ts -│   │   │   │   │   │   ├── equivalencies.ts -│   │   │   │   │   │   ├── error-catalogs.ts -│   │   │   │   │   │   ├── exchange-rate.ts -│   │   │   │   │   │   ├── identifiers.ts -│   │   │   │   │   │   ├── index.ts -│   │   │   │   │   │   ├── inpc.ts -│   │   │   │   │   │   ├── legends.ts -│   │   │   │   │   │   ├── locations.ts -│   │   │   │   │   │   ├── multi-currency-types.ts -│   │   │   │   │   │   ├── packages.ts -│   │   │   │   │   │   ├── ports.ts -│   │   │   │   │   │   ├── prevalidators.ts -│   │   │   │   │   │   ├── seal.ts -│   │   │   │   │   │   ├── signatures.ts -│   │   │   │   │   │   ├── um-ace.ts -│   │   │   │   │   │   ├── um-customs-ame.ts -│   │   │   │   │   │   ├── um-customs-mex.ts -│   │   │   │   │   │   ├── um-oma.ts -│   │   │   │   │   │   ├── unit-conversions.ts -│   │   │   │   │   │   ├── unit-measures.ts -│   │   │   │   │   │   └── units-of-measure.ts -│   │   │   │   │   ├── index.ts -│   │   │   │   │   ├── invoices.ts -│   │   │   │   │   ├── pedimento-dates.ts -│   │   │   │   │   ├── pedimento-payments.ts -│   │   │   │   │   ├── pedimentos.ts -│   │   │   │   │   ├── pedimento-transport.ts -│   │   │   │   │   └── pedimento-validation.ts -│   │   │   │   └── refrence_data -│   │   │   │   ├── code_pedimento_regimens.ts -│   │   │   │   ├── containers.ts -│   │   │   │   ├── countries.ts -│   │   │   │   ├── currency_types.ts -│   │   │   │   ├── customs_sections.ts -│   │   │   │   ├── customs_warehouses.ts -│   │   │   │   ├── incoterms.ts -│   │   │   │   ├── invoice_types.ts -│   │   │   │   ├── material_types.ts -│   │   │   │   ├── payment_methods.ts -│   │   │   │   ├── pedimento_codes.ts -│   │   │   │   ├── pedimento_regimens.ts -│   │   │   │   ├── sectors.ts -│   │   │   │   ├── states.ts -│   │   │   │   ├── transport_modes.ts -│   │   │   │   ├── transport_types.ts -│   │   │   │   └── valuation_methods.ts -│   │   │   ├── api.ts -│   │   │   ├── assets -│   │   │   │   └── favicon.svg -│   │   │   ├── auth.ts -│   │   │   ├── components -│   │   │   │   ├── dashboard -│   │   │   │   │   ├── classes -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   └── data-table.svelte -│   │   │   │   │   ├── clients_and_providers -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   ├── company -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   └── data-table-actions.svelte -│   │   │   │   │   ├── customs_brokers -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   ├── create-dialog.svelte -│   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   ├── details-dialog.svelte -│   │   │   │   │   │   └── edit-dialog.svelte -│   │   │   │   │   ├── exchange-rate -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   └── data-table.svelte -│   │   │   │   │   ├── general_catalogs -│   │   │   │   │   │   └── simple-data-table.svelte -│   │   │   │   │   ├── identifiers -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   └── data-table.svelte -│   │   │   │   │   ├── invoices -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   ├── locations -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   └── data-table.svelte -│   │   │   │   │   ├── packages -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   └── data-table.svelte -│   │   │   │   │   ├── pedimentos -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   └── edit -│   │   │   │   │   │   ├── dates-tab-form.svelte -│   │   │   │   │   │   ├── general-tab-form.svelte -│   │   │   │   │   │   ├── payments-tab-form.svelte -│   │   │   │   │   │   ├── transport-tab-form.svelte -│   │   │   │   │   │   └── validation-tab-form.svelte -│   │   │   │   │   ├── ports -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   └── data-table-actions.svelte -│   │   │   │   │   ├── reference_data -│   │   │   │   │   │   ├── code_pedimento_regimens -│   │   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   │   ├── containers -│   │   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   │   ├── countries -│   │   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   │   ├── currency_types -│   │   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   │   ├── customs_sections -│   │   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   │   ├── customs_warehouses -│   │   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   │   ├── incoterms -│   │   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   │   ├── invoice_types -│   │   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   │   ├── material_types -│   │   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   │   ├── payment_methods -│   │   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   │   ├── pedimento_codes -│   │   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   │   ├── pedimento_regimens -│   │   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   │   ├── sectors -│   │   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   │   ├── states -│   │   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   │   ├── transport_modes -│   │   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   │   ├── transport_types -│   │   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   │   └── valuation_methods -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   ├── delete-dialog.svelte -│   │   │   │   │   │   └── details-dialog.svelte -│   │   │   │   │   ├── seal -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   ├── data-table.svelte -│   │   │   │   │   │   └── index.ts -│   │   │   │   │   └── units_of_measure -│   │   │   │   │   ├── ace -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   └── data-table.svelte -│   │   │   │   │   ├── american -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   └── data-table-actions.svelte -│   │   │   │   │   ├── customs -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   └── data-table.svelte -│   │   │   │   │   ├── general -│   │   │   │   │   │   ├── columns.ts -│   │   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   │   ├── data-table-actions.svelte -│   │   │   │   │   │   └── data-table.svelte -│   │   │   │   │   └── oma -│   │   │   │   │   ├── columns.ts -│   │   │   │   │   ├── create-edit-dialog.svelte -│   │   │   │   │   └── data-table-actions.svelte -│   │   │   │   ├── login-form.svelte -│   │   │   │   ├── sidebar -│   │   │   │   │   ├── app-sidebar.svelte -│   │   │   │   │   ├── modules.ts -│   │   │   │   │   ├── nav-main.svelte -│   │   │   │   │   ├── nav-projects.svelte -│   │   │   │   │   ├── nav-user.svelte -│   │   │   │   │   └── team-switcher.svelte -│   │   │   │   └── ui -│   │   │   │   ├── alert -│   │   │   │   │   ├── alert-description.svelte -│   │   │   │   │   ├── alert.svelte -│   │   │   │   │   ├── alert-title.svelte -│   │   │   │   │   └── index.ts -│   │   │   │   ├── alert-dialog -│   │   │   │   │   ├── alert-dialog-action.svelte -│   │   │   │   │   ├── alert-dialog-cancel.svelte -│   │   │   │   │   ├── alert-dialog-content.svelte -│   │   │   │   │   ├── alert-dialog-description.svelte -│   │   │   │   │   ├── alert-dialog-footer.svelte -│   │   │   │   │   ├── alert-dialog-header.svelte -│   │   │   │   │   ├── alert-dialog-overlay.svelte -│   │   │   │   │   ├── alert-dialog-title.svelte -│   │   │   │   │   ├── alert-dialog-trigger.svelte -│   │   │   │   │   └── index.ts -│   │   │   │   ├── avatar -│   │   │   │   │   ├── avatar-fallback.svelte -│   │   │   │   │   ├── avatar-image.svelte -│   │   │   │   │   ├── avatar.svelte -│   │   │   │   │   └── index.ts -│   │   │   │   ├── badge -│   │   │   │   │   ├── badge.svelte -│   │   │   │   │   └── index.ts -│   │   │   │   ├── breadcrumb -│   │   │   │   │   ├── breadcrumb-ellipsis.svelte -│   │   │   │   │   ├── breadcrumb-item.svelte -│   │   │   │   │   ├── breadcrumb-link.svelte -│   │   │   │   │   ├── breadcrumb-list.svelte -│   │   │   │   │   ├── breadcrumb-page.svelte -│   │   │   │   │   ├── breadcrumb-separator.svelte -│   │   │   │   │   ├── breadcrumb.svelte -│   │   │   │   │   └── index.ts -│   │   │   │   ├── button -│   │   │   │   │   ├── button.svelte -│   │   │   │   │   └── index.ts -│   │   │   │   ├── card -│   │   │   │   │   ├── card-action.svelte -│   │   │   │   │   ├── card-content.svelte -│   │   │   │   │   ├── card-description.svelte -│   │   │   │   │   ├── card-footer.svelte -│   │   │   │   │   ├── card-header.svelte -│   │   │   │   │   ├── card.svelte -│   │   │   │   │   ├── card-title.svelte -│   │   │   │   │   └── index.ts -│   │   │   │   ├── collapsible -│   │   │   │   │   ├── collapsible-content.svelte -│   │   │   │   │   ├── collapsible.svelte -│   │   │   │   │   ├── collapsible-trigger.svelte -│   │   │   │   │   └── index.ts -│   │   │   │   ├── data-table -│   │   │   │   │   ├── data-table.svelte.ts -│   │   │   │   │   ├── flex-render.svelte -│   │   │   │   │   ├── index.ts -│   │   │   │   │   └── render-helpers.ts -│   │   │   │   ├── dialog -│   │   │   │   │   ├── dialog-close.svelte -│   │   │   │   │   ├── dialog-content.svelte -│   │   │   │   │   ├── dialog-description.svelte -│   │   │   │   │   ├── dialog-footer.svelte -│   │   │   │   │   ├── dialog-header.svelte -│   │   │   │   │   ├── dialog-overlay.svelte -│   │   │   │   │   ├── dialog-title.svelte -│   │   │   │   │   ├── dialog-trigger.svelte -│   │   │   │   │   └── index.ts -│   │   │   │   ├── dropdown-menu -│   │   │   │   │   ├── dropdown-menu-checkbox-item.svelte -│   │   │   │   │   ├── dropdown-menu-content.svelte -│   │   │   │   │   ├── dropdown-menu-group-heading.svelte -│   │   │   │   │   ├── dropdown-menu-group.svelte -│   │   │   │   │   ├── dropdown-menu-item.svelte -│   │   │   │   │   ├── dropdown-menu-label.svelte -│   │   │   │   │   ├── dropdown-menu-radio-group.svelte -│   │   │   │   │   ├── dropdown-menu-radio-item.svelte -│   │   │   │   │   ├── dropdown-menu-separator.svelte -│   │   │   │   │   ├── dropdown-menu-shortcut.svelte -│   │   │   │   │   ├── dropdown-menu-sub-content.svelte -│   │   │   │   │   ├── dropdown-menu-sub-trigger.svelte -│   │   │   │   │   ├── dropdown-menu-trigger.svelte -│   │   │   │   │   └── index.ts -│   │   │   │   ├── field -│   │   │   │   │   ├── field-content.svelte -│   │   │   │   │   ├── field-description.svelte -│   │   │   │   │   ├── field-error.svelte -│   │   │   │   │   ├── field-group.svelte -│   │   │   │   │   ├── field-label.svelte -│   │   │   │   │   ├── field-legend.svelte -│   │   │   │   │   ├── field-separator.svelte -│   │   │   │   │   ├── field-set.svelte -│   │   │   │   │   ├── field.svelte -│   │   │   │   │   ├── field-title.svelte -│   │   │   │   │   └── index.ts -│   │   │   │   ├── input -│   │   │   │   │   ├── index.ts -│   │   │   │   │   └── input.svelte -│   │   │   │   ├── label -│   │   │   │   │   ├── index.ts -│   │   │   │   │   └── label.svelte -│   │   │   │   ├── select -│   │   │   │   │   ├── index.ts -│   │   │   │   │   ├── select-content.svelte -│   │   │   │   │   ├── select-group-heading.svelte -│   │   │   │   │   ├── select-group.svelte -│   │   │   │   │   ├── select-item.svelte -│   │   │   │   │   ├── select-label.svelte -│   │   │   │   │   ├── select-scroll-down-button.svelte -│   │   │   │   │   ├── select-scroll-up-button.svelte -│   │   │   │   │   ├── select-separator.svelte -│   │   │   │   │   └── select-trigger.svelte -│   │   │   │   ├── separator -│   │   │   │   │   ├── index.ts -│   │   │   │   │   └── separator.svelte -│   │   │   │   ├── sheet -│   │   │   │   │   ├── index.ts -│   │   │   │   │   ├── sheet-close.svelte -│   │   │   │   │   ├── sheet-content.svelte -│   │   │   │   │   ├── sheet-description.svelte -│   │   │   │   │   ├── sheet-footer.svelte -│   │   │   │   │   ├── sheet-header.svelte -│   │   │   │   │   ├── sheet-overlay.svelte -│   │   │   │   │   ├── sheet-title.svelte -│   │   │   │   │   └── sheet-trigger.svelte -│   │   │   │   ├── sidebar -│   │   │   │   │   ├── constants.ts -│   │   │   │   │   ├── context.svelte.ts -│   │   │   │   │   ├── index.ts -│   │   │   │   │   ├── sidebar-content.svelte -│   │   │   │   │   ├── sidebar-footer.svelte -│   │   │   │   │   ├── sidebar-group-action.svelte -│   │   │   │   │   ├── sidebar-group-content.svelte -│   │   │   │   │   ├── sidebar-group-label.svelte -│   │   │   │   │   ├── sidebar-group.svelte -│   │   │   │   │   ├── sidebar-header.svelte -│   │   │   │   │   ├── sidebar-input.svelte -│   │   │   │   │   ├── sidebar-inset.svelte -│   │   │   │   │   ├── sidebar-menu-action.svelte -│   │   │   │   │   ├── sidebar-menu-badge.svelte -│   │   │   │   │   ├── sidebar-menu-button.svelte -│   │   │   │   │   ├── sidebar-menu-item.svelte -│   │   │   │   │   ├── sidebar-menu-skeleton.svelte -│   │   │   │   │   ├── sidebar-menu-sub-button.svelte -│   │   │   │   │   ├── sidebar-menu-sub-item.svelte -│   │   │   │   │   ├── sidebar-menu-sub.svelte -│   │   │   │   │   ├── sidebar-menu.svelte -│   │   │   │   │   ├── sidebar-provider.svelte -│   │   │   │   │   ├── sidebar-rail.svelte -│   │   │   │   │   ├── sidebar-separator.svelte -│   │   │   │   │   ├── sidebar.svelte -│   │   │   │   │   └── sidebar-trigger.svelte -│   │   │   │   ├── skeleton -│   │   │   │   │   ├── index.ts -│   │   │   │   │   └── skeleton.svelte -│   │   │   │   ├── switch -│   │   │   │   │   ├── index.ts -│   │   │   │   │   └── switch.svelte -│   │   │   │   ├── table -│   │   │   │   │   ├── index.ts -│   │   │   │   │   ├── table-body.svelte -│   │   │   │   │   ├── table-caption.svelte -│   │   │   │   │   ├── table-cell.svelte -│   │   │   │   │   ├── table-footer.svelte -│   │   │   │   │   ├── table-header.svelte -│   │   │   │   │   ├── table-head.svelte -│   │   │   │   │   ├── table-row.svelte -│   │   │   │   │   └── table.svelte -│   │   │   │   ├── tabs -│   │   │   │   │   ├── index.ts -│   │   │   │   │   ├── tabs-content.svelte -│   │   │   │   │   ├── tabs-list.svelte -│   │   │   │   │   ├── tabs.svelte -│   │   │   │   │   └── tabs-trigger.svelte -│   │   │   │   ├── textarea -│   │   │   │   │   ├── index.ts -│   │   │   │   │   └── textarea.svelte -│   │   │   │   └── tooltip -│   │   │   │   ├── index.ts -│   │   │   │   ├── tooltip-content.svelte -│   │   │   │   └── tooltip-trigger.svelte -│   │   │   ├── hooks -│   │   │   │   └── is-mobile.svelte.ts -│   │   │   ├── paraglide -│   │   │   │   ├── messages -│   │   │   │   │   ├── en.js -│   │   │   │   │   ├── es.js -│   │   │   │   │   └── _index.js -│   │   │   │   ├── messages.js -│   │   │   │   ├── registry.js -│   │   │   │   ├── runtime.js -│   │   │   │   └── server.js -│   │   │   ├── server -│   │   │   │   └── api.ts -│   │   │   ├── sso.ts -│   │   │   ├── stores -│   │   │   │   └── company.svelte.ts -│   │   │   └── utils.ts -│   │   └── routes -│   │   ├── api -│   │   │   └── company -│   │   │   └── my-companies -│   │   │   └── +server.ts -│   │   ├── auth -│   │   │   └── callback -│   │   │   ├── +page.server.ts -│   │   │   └── +page.svelte -│   │   ├── dashboard -│   │   │   ├── classes -│   │   │   │   └── +page.svelte -│   │   │   ├── clients_and_providers -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── customs_brokers -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── general_catalogs -│   │   │   │   ├── classification_concepts -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── company_information -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── concepts -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── customs_broker_concepts -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── doda -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── electronic_notices -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── equivalencies -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── error_catalogs -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── exchange-rate -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── identifiers -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── inpc -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── legends -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── locations -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── multi_currency_types -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── packages -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── +page.svelte -│   │   │   │   ├── ports -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── prevalidators -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── seal -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── signatures -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── unit_conversions -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   └── units_of_measure -│   │   │   │   ├── ace -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── american -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── customs -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── general -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   └── oma -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── invoices -│   │   │   │   ├── exportacion -│   │   │   │   │   ├── exportacion -│   │   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   │   └── +page.svelte -│   │   │   │   │   └── reparacion -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   └── importacion -│   │   │   │   ├── cambio_regimen -│   │   │   │   │   ├── new -│   │   │   │   │   │   └── +page.svelte -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── compras_mexicanas -│   │   │   │   │   ├── new -│   │   │   │   │   │   └── +page.svelte -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── definitiva -│   │   │   │   │   ├── new -│   │   │   │   │   │   └── +page.svelte -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   └── temporal -│   │   │   │   ├── new -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── +layout.server.ts -│   │   │   ├── +layout.svelte -│   │   │   ├── +layout.ts -│   │   │   ├── +page.svelte -│   │   │   ├── pedimentos -│   │   │   │   ├── edit -│   │   │   │   │   └── [id] -│   │   │   │   │   ├── +page.server.ts -│   │   │   │   │   └── +page.svelte -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   └── reference_data -│   │   │   ├── code_pedimento_regimens -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── containers -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── countries -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── currency_types -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── customs_sections -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── customs_warehouses -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── incoterms -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── invoice_types -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── material_types -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── +page.svelte -│   │   │   ├── payment_methods -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── pedimento_codes -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── pedimento_regimens -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── sectors -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── states -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── transport_modes -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   ├── transport_types -│   │   │   │   ├── +page.server.ts -│   │   │   │   └── +page.svelte -│   │   │   └── valuation_methods -│   │   │   ├── +page.server.ts -│   │   │   └── +page.svelte -│   │   ├── demo -│   │   │   ├── +page.svelte -│   │   │   └── paraglide -│   │   │   └── +page.svelte -│   │   ├── +layout.svelte -│   │   ├── login -│   │   │   ├── +page.server.ts -│   │   │   └── +page.svelte -│   │   ├── logout -│   │   │   └── +server.ts -│   │   ├── +page.server.ts -│   │   ├── +page.svelte -│   │   ├── page.svelte.spec.ts -│   │   └── register -│   │   └── +page.svelte -│   ├── svelte.config.js -│   ├── tsconfig.json -│   ├── vite.config.ts -│   └── vitest-setup-client.ts -├── pnpm-lock.yaml -├── README.md -├── scripts -│   ├── backend-entrypoint.sh -│   ├── frontend-entrypoint.sh -│   ├── health-check.sh -│   ├── init_first_time.sh -│   ├── keycloak-entrypoint.sh -│   ├── postgres-app-entrypoint.sh -│   └── postgres-keycloak-entrypoint.sh -└── start.sh - -245 directories, 943 files diff --git a/frontend/package.json b/frontend/package.json index 79332865..5845afea 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -21,7 +21,7 @@ "@eslint/js": "^9.36.0", "@inlang/paraglide-js": "^2.3.2", "@internationalized/date": "^3.10.0", - "@lucide/svelte": "^0.544.0", + "@lucide/svelte": "^0.561.0", "@playwright/test": "^1.55.1", "@sveltejs/adapter-node": "^5.3.2", "@sveltejs/kit": "^2.43.2", @@ -32,7 +32,7 @@ "@tanstack/table-core": "^8.21.3", "@types/node": "^20", "@vitest/browser": "^3.2.4", - "bits-ui": "^2.14.2", + "bits-ui": "^2.14.4", "clsx": "^2.1.1", "eslint": "^9.36.0", "eslint-config-prettier": "^10.1.8", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index ad22d6ef..35a56541 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -28,8 +28,8 @@ importers: specifier: ^3.10.0 version: 3.10.0 '@lucide/svelte': - specifier: ^0.544.0 - version: 0.544.0(svelte@5.40.2) + specifier: ^0.561.0 + version: 0.561.0(svelte@5.40.2) '@playwright/test': specifier: ^1.55.1 version: 1.56.1 @@ -61,8 +61,8 @@ importers: specifier: ^3.2.4 version: 3.2.4(playwright@1.56.1)(vite@7.1.10(@types/node@20.19.22)(jiti@2.6.1)(lightningcss@1.30.1))(vitest@3.2.4) bits-ui: - specifier: ^2.14.2 - version: 2.14.2(@internationalized/date@3.10.0)(@sveltejs/kit@2.47.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.40.2)(vite@7.1.10(@types/node@20.19.22)(jiti@2.6.1)(lightningcss@1.30.1)))(svelte@5.40.2)(vite@7.1.10(@types/node@20.19.22)(jiti@2.6.1)(lightningcss@1.30.1)))(svelte@5.40.2) + specifier: ^2.14.4 + version: 2.14.4(@internationalized/date@3.10.0)(@sveltejs/kit@2.47.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.40.2)(vite@7.1.10(@types/node@20.19.22)(jiti@2.6.1)(lightningcss@1.30.1)))(svelte@5.40.2)(vite@7.1.10(@types/node@20.19.22)(jiti@2.6.1)(lightningcss@1.30.1)))(svelte@5.40.2) clsx: specifier: ^2.1.1 version: 2.1.1 @@ -407,8 +407,8 @@ packages: '@lix-js/server-protocol-schema@0.1.1': resolution: {integrity: sha512-jBeALB6prAbtr5q4vTuxnRZZv1M2rKe8iNqRQhFJ4Tv7150unEa0vKyz0hs8Gl3fUGsWaNJBh3J8++fpbrpRBQ==} - '@lucide/svelte@0.544.0': - resolution: {integrity: sha512-9f9O6uxng2pLB01sxNySHduJN3HTl5p0HDu4H26VR51vhZfiMzyOMe9Mhof3XAk4l813eTtl+/DYRvGyoRR+yw==} + '@lucide/svelte@0.561.0': + resolution: {integrity: sha512-vofKV2UFVrKE6I4ewKJ3dfCXSV6iP6nWVmiM83MLjsU91EeJcEg7LoWUABLp/aOTxj1HQNbJD1f3g3L0JQgH9A==} peerDependencies: svelte: ^5 @@ -919,8 +919,8 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - bits-ui@2.14.2: - resolution: {integrity: sha512-YqpAJj/nRTZjf7IlgUC3QlepVZ7YFiAQWpZaYUOAZFW5Py+g5DYkhEDTdNFI5SReo7l1rct/nRpMK4pfL9Xffw==} + bits-ui@2.14.4: + resolution: {integrity: sha512-W6kenhnbd/YVvur+DKkaVJ6GldE53eLewur5AhUCqslYQ0vjZr8eWlOfwZnMiPB+PF5HMVqf61vXBvmyrAmPWg==} engines: {node: '>=20'} peerDependencies: '@internationalized/date': ^3.8.1 @@ -2240,7 +2240,7 @@ snapshots: '@lix-js/server-protocol-schema@0.1.1': {} - '@lucide/svelte@0.544.0(svelte@5.40.2)': + '@lucide/svelte@0.561.0(svelte@5.40.2)': dependencies: svelte: 5.40.2 @@ -2735,7 +2735,7 @@ snapshots: balanced-match@1.0.2: {} - bits-ui@2.14.2(@internationalized/date@3.10.0)(@sveltejs/kit@2.47.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.40.2)(vite@7.1.10(@types/node@20.19.22)(jiti@2.6.1)(lightningcss@1.30.1)))(svelte@5.40.2)(vite@7.1.10(@types/node@20.19.22)(jiti@2.6.1)(lightningcss@1.30.1)))(svelte@5.40.2): + bits-ui@2.14.4(@internationalized/date@3.10.0)(@sveltejs/kit@2.47.1(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.40.2)(vite@7.1.10(@types/node@20.19.22)(jiti@2.6.1)(lightningcss@1.30.1)))(svelte@5.40.2)(vite@7.1.10(@types/node@20.19.22)(jiti@2.6.1)(lightningcss@1.30.1)))(svelte@5.40.2): dependencies: '@floating-ui/core': 1.7.3 '@floating-ui/dom': 1.7.4 diff --git a/frontend/src/lib/api/dashboard/a76/invoices.ts b/frontend/src/lib/api/dashboard/a76/invoices.ts index 99a23601..78043d2e 100644 --- a/frontend/src/lib/api/dashboard/a76/invoices.ts +++ b/frontend/src/lib/api/dashboard/a76/invoices.ts @@ -13,8 +13,12 @@ export interface InvoiceComplianceMx { invoice_id?: number; pedimento?: string | null; pedimento_code?: string | null; + pedimento_k1?: string | null; remesa?: number | null; - aduana?: string | null; + aduana?: string | null; + port_of_entry?: string | null; + destination?: string | null; + manifest_number?: string | null; provider_header?: string | null; provider_id?: string | null; sold_to_header?: string | null; @@ -24,11 +28,42 @@ export interface InvoiceComplianceMx { shipped_by_header?: string | null; shipped_by_id?: string | null; customs_broker_id?: string | null; + customs_broker_us_id?: string | null; + broker_invoice_num?: string | null; + broker_invoice_date?: string | null; is_mixed?: boolean | null; waste_type?: string | null; + scrap_type?: string | null; appendix_17?: number | null; + is_regime_change?: string | null; + which_exchange_rate?: string | null; + value_method?: string | null; + act_value?: string | null; + is_pedimento_pending?: boolean | null; + is_owner_of_goods?: string | null; + generate_balances?: string | null; + was_reviewed_by_company?: boolean | null; edocument?: string | null; + code_signature?: string | null; electronic_signature?: string | null; + certificate_number?: string | null; + niu_number?: string | null; + bill_of_lading_count?: string | null; + addendum_vu?: string | null; + origin_destination_cove?: string | null; + vucem_operation_num?: string | null; + customs_person_line?: number | null; + contingency_mode?: boolean | null; + enclosure?: string | null; + guide_type_to_identify?: string | null; + location?: string | null; + dot_code?: string | null; + subdivision?: string | null; + acts_as?: string | null; + movement_type?: string | null; + office_document?: string | null; + reason_export?: string | null; + signature_key?: string | null; sem_id?: number | null; } @@ -38,33 +73,83 @@ export interface InvoiceFinancials { currency?: string | null; currency_type?: string | null; exchange_rate?: number | null; + exchange_rate_mm?: number | null; value_mn?: number | null; value_me?: number | null; + value_mc?: number | null; customs_value_mn?: number | null; + customs_value_me?: number | null; + raw_material_value_mn?: number | null; + raw_material_value_me?: number | null; + aggregate_value_mn?: number | null; + aggregate_value_me?: number | null; + aggregate_value_mc?: number | null; + mexican_value_mn?: number | null; + mexican_value_me?: number | null; + mexican_value_mc?: number | null; + national_packaging_mn?: number | null; + national_packaging_me?: number | null; + national_packaging_mc?: number | null; freight?: number | null; insurance?: number | null; + insurance_value?: number | null; + packaging?: number | null; + other_increments?: number | null; + total_increments_mn?: number | null; + total_increments_me?: number | null; iva_mn?: number | null; - iva_factor?: number | null; + iva_me?: number | null; + iva_mc?: number | null; + iva_factor?: string | null; + tax_value_me?: number | null; + seal_value_2500?: boolean | null; total_quantity?: number | null; gross_weight?: number | null; net_weight?: number | null; bundle_count?: number | null; + weight_factor?: number | null; } export interface InvoiceLogistics { id?: number; invoice_id?: number; carrier_id?: string | null; + transport_id?: string | null; + transport_us_id?: string | null; transport_type?: TransportType | null; + transport_num?: string | null; transport_mode?: string | null; driver_name?: string | null; is_rail?: string | null; rail_id?: string | null; vehicle_num?: string | null; license_plate?: string | null; + license_plate_complete?: string | null; + trailer_num?: string | null; seal_number?: string | null; guide_number?: string | null; + bill_number?: string | null; + reference_number?: string | null; + shipment_number?: string | null; + incoterm?: string | null; + identifier_1?: string | null; + complement_1?: string | null; + identifier_2?: string | null; + complement_2?: string | null; + weight_type?: string | null; + container_types?: string | null; + vehicle_data?: string | null; + origin_location?: string | null; + destination_location?: string | null; + transport_itinerary?: string | null; + destination_goods?: string | null; entry_exit_date?: string | null; + delivery_date?: string | null; + delivered_status?: string | null; + received_by?: string | null; + payment_date?: string | null; + payment_receipt_num?: string | null; + is_ctm_process?: string | null; } export interface InvoiceSalesDetails { @@ -91,25 +176,47 @@ export interface Invoice { id: number; tenant_id: number; company_id: number; + system?: string | null; operation_type?: OperationType | null; invoice_type?: string | null; invoice_number?: string | null; project_number?: string | null; purchase_order?: string | null; related_doc_id?: number | null; + alternate_invoice?: string | null; + invoice_ref?: string | null; + proforma_number?: string | null; invoice_date?: string | null; capture_date: string; + emission_date?: string | null; is_updated?: boolean | null; updated_date?: string | null; who_updated?: string | null; + capture_user?: string | null; traffic_light_status?: string | null; process_log?: string | null; + status_rec?: number | null; + status_rep?: string | null; observation_es?: string | null; observation_en?: string | null; comments_status?: string | null; + vu_observations?: string | null; cfdi_uuid?: string | null; path_pdf?: string | null; path_xml?: string | null; + subcompany?: string | null; + party_count?: number | null; + generate_id?: string | null; + generate_desc_parties?: string | null; + apply_manual_discount?: string | null; + is_bulk?: boolean | null; + download_substance?: boolean | null; + download_class?: boolean | null; + download_def?: boolean | null; + payment_terms?: string | null; + handling_fees?: number | null; + option_iv18?: string | null; + enajenation_goods?: boolean | null; compliance_mx?: InvoiceComplianceMx | null; financials?: InvoiceFinancials | null; logistics?: InvoiceLogistics[]; @@ -125,21 +232,46 @@ export interface InvoiceListResponse { } export interface CreateInvoiceData { + system?: string | null; operation_type?: OperationType | null; invoice_type?: string | null; invoice_number?: string | null; project_number?: string | null; purchase_order?: string | null; related_doc_id?: number | null; + alternate_invoice?: string | null; + invoice_ref?: string | null; + proforma_number?: string | null; invoice_date?: string | null; + emission_date?: string | null; + is_updated?: boolean | null; + updated_date?: string | null; + who_updated?: string | null; + capture_user?: string | null; traffic_light_status?: string | null; process_log?: string | null; + status_rec?: number | null; + status_rep?: string | null; observation_es?: string | null; observation_en?: string | null; comments_status?: string | null; + vu_observations?: string | null; cfdi_uuid?: string | null; path_pdf?: string | null; path_xml?: string | null; + subcompany?: string | null; + party_count?: number | null; + generate_id?: string | null; + generate_desc_parties?: string | null; + apply_manual_discount?: string | null; + is_bulk?: boolean | null; + download_substance?: boolean | null; + download_class?: boolean | null; + download_def?: boolean | null; + payment_terms?: string | null; + handling_fees?: number | null; + option_iv18?: string | null; + enajenation_goods?: boolean | null; compliance_mx?: Omit | null; financials?: Omit | null; logistics?: Omit[] | null; diff --git a/frontend/src/lib/assets/favicon.svg b/frontend/src/lib/assets/favicon.svg index 1e26f0a3..6ab796db 100644 --- a/frontend/src/lib/assets/favicon.svg +++ b/frontend/src/lib/assets/favicon.svg @@ -1,13 +1 @@ - - - - - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/frontend/src/lib/components/dashboard/invoices/columns.ts b/frontend/src/lib/components/dashboard/invoices/columns.ts index d7f03fc5..bee37d2d 100644 --- a/frontend/src/lib/components/dashboard/invoices/columns.ts +++ b/frontend/src/lib/components/dashboard/invoices/columns.ts @@ -1,89 +1,250 @@ -/** - * Definición de columnas para la tabla de facturas - */ +import type { ColumnDef } from "@tanstack/table-core"; +import { renderComponent, renderSnippet } from "$lib/components/ui/data-table/index.js"; +import { createRawSnippet } from "svelte"; +import DataTableActions from "./data-table-actions.svelte"; import type { Invoice } from '$lib/api/dashboard/a76/invoices'; -import DataTableActions from './data-table-actions.svelte'; -export function createColumns() { +/** + * Formatea un número como moneda MXN + */ +function formatCurrencyMXN(value?: number | null): string { + if (value === null || value === undefined) return '-'; + return new Intl.NumberFormat('es-MX', { + style: 'currency', + currency: 'MXN', + minimumFractionDigits: 2, + maximumFractionDigits: 2 + }).format(value); +} + +/** + * Formatea un número como moneda USD + */ +function formatCurrencyUSD(value?: number | null): string { + if (value === null || value === undefined) return '-'; + return new Intl.NumberFormat('es-MX', { + style: 'currency', + currency: 'USD', + minimumFractionDigits: 2, + maximumFractionDigits: 2 + }).format(value); +} + +/** + * Formatea una fecha + */ +function formatDate(date?: string | null): string { + if (!date) return '-'; + return new Date(date).toLocaleDateString('es-MX', { + year: 'numeric', + month: '2-digit', + day: '2-digit' + }); +} + +/** + * Obtiene el color del badge según el tipo de operación + */ +function getOperationTypeColor(type?: string | null): string { + if (!type) return 'bg-gray-100 text-gray-800'; + return type === 'imp' ? 'bg-blue-100 text-blue-800' : 'bg-green-100 text-green-800'; +} + +/** + * Obtiene el color del badge según el semáforo fiscal + */ +function getTrafficLightColor(status?: string | null): string { + if (!status) return 'bg-gray-100 text-gray-800'; + + const statusLower = status.toLowerCase(); + if (statusLower.includes('verde') || statusLower === 'green') return 'bg-green-100 text-green-800'; + if (statusLower.includes('amarillo') || statusLower === 'yellow') return 'bg-yellow-100 text-yellow-800'; + if (statusLower.includes('rojo') || statusLower === 'red') return 'bg-red-100 text-red-800'; + + return 'bg-gray-100 text-gray-800'; +} + +export function createColumns(onSuccess?: () => void): ColumnDef[] { return [ { - accessorKey: 'id', - header: 'ID', - cell: (info: any) => info.getValue(), - enableSorting: true - }, - { - accessorKey: 'operation_type', - header: 'Tipo', - cell: (info: any) => { - const type = info.getValue(); - return type === 'imp' ? 'Importación' : type === 'exp' ? 'Exportación' : '-'; + accessorKey: "id", + header: "ID", + cell: ({ row }) => { + const idSnippet = createRawSnippet<[{ id: number }]>((getId) => { + const { id } = getId(); + return { + render: () => + `
#${id}
` + }; + }); + return renderSnippet(idSnippet, { id: row.original.id }); } }, { - accessorKey: 'invoice_number', - header: 'Número de Factura', - cell: (info: any) => info.getValue() || '-' - }, - { - accessorKey: 'invoice_type', - header: 'Tipo Factura', - cell: (info: any) => info.getValue() || '-' - }, - { - accessorKey: 'project_number', - header: 'Proyecto', - cell: (info: any) => info.getValue() || '-' - }, - { - accessorKey: 'compliance_mx.pedimento', - header: 'Pedimento', - cell: (info: any) => { - const row = info.row.original; - return row.compliance_mx?.pedimento || '-'; + accessorKey: "operation_type", + header: "Operación", + cell: ({ row }) => { + const type = row.original.operation_type; + const colorClass = getOperationTypeColor(type); + const label = type === 'imp' ? 'IMP' : type === 'exp' ? 'EXP' : 'N/A'; + + const typeSnippet = createRawSnippet<[{ label: string; colorClass: string }]>((getType) => { + const { label, colorClass } = getType(); + return { + render: () => + ` + ${label} + ` + }; + }); + return renderSnippet(typeSnippet, { label, colorClass }); } }, { - accessorKey: 'invoice_date', - header: 'Fecha Factura', - cell: (info: any) => { - const date = info.getValue(); - if (!date) return '-'; - return new Date(date).toLocaleDateString('es-MX'); + accessorKey: "invoice_number", + header: "Número de Factura", + cell: ({ row }) => { + const numberSnippet = createRawSnippet<[{ number?: string | null }]>((getNumber) => { + const { number } = getNumber(); + return { + render: () => + `${number || 'N/A'}` + }; + }); + return renderSnippet(numberSnippet, { number: row.original.invoice_number }); } }, { - accessorKey: 'financials.value_mn', - header: 'Valor MN', - cell: (info: any) => { - const row = info.row.original; - const value = row.financials?.value_mn; - if (value === null || value === undefined) return '-'; - return new Intl.NumberFormat('es-MX', { - style: 'currency', - currency: 'MXN' - }).format(value); + accessorKey: "invoice_type", + header: "Tipo", + cell: ({ row }) => { + const typeSnippet = createRawSnippet<[{ type?: string | null }]>((getType) => { + const { type } = getType(); + return { + render: () => + `
${type || '-'}
` + }; + }); + return renderSnippet(typeSnippet, { type: row.original.invoice_type }); } }, { - accessorKey: 'traffic_light_status', - header: 'Semáforo', - cell: (info: any) => info.getValue() || '-' - }, - { - accessorKey: 'capture_date', - header: 'Fecha Captura', - cell: (info: any) => { - const date = info.getValue(); - if (!date) return '-'; - return new Date(date).toLocaleDateString('es-MX'); + accessorKey: "project_number", + header: "Proyecto", + cell: ({ row }) => { + const projectSnippet = createRawSnippet<[{ project?: string | null }]>((getProject) => { + const { project } = getProject(); + return { + render: () => + `
${project || '-'}
` + }; + }); + return renderSnippet(projectSnippet, { project: row.original.project_number }); } }, { - id: 'actions', - header: 'Acciones', - cell: (info: any) => DataTableActions, - enableSorting: false + accessorKey: "compliance_mx.pedimento", + header: "Pedimento", + cell: ({ row }) => { + const pedimento = row.original.compliance_mx?.pedimento; + + const pedimentoSnippet = createRawSnippet<[{ pedimento?: string | null }]>((getPedimento) => { + const { pedimento } = getPedimento(); + return { + render: () => + `
${pedimento || '-'}
` + }; + }); + return renderSnippet(pedimentoSnippet, { pedimento }); + } + }, + { + accessorKey: "financials.value_mn", + header: () => { + const headerSnippet = createRawSnippet(() => { + return { + render: () => `
Valor MN
` + }; + }); + return renderSnippet(headerSnippet, {}); + }, + cell: ({ row }) => { + const valueMN = row.original.financials?.value_mn; + + const valueSnippet = createRawSnippet<[{ value: string }]>((getValue) => { + const { value } = getValue(); + return { + render: () => + `
${value}
` + }; + }); + return renderSnippet(valueSnippet, { value: formatCurrencyMXN(valueMN) }); + } + }, + { + accessorKey: "financials.value_me", + header: () => { + const headerSnippet = createRawSnippet(() => { + return { + render: () => `
Valor ME
` + }; + }); + return renderSnippet(headerSnippet, {}); + }, + cell: ({ row }) => { + const valueME = row.original.financials?.value_me; + + const valueSnippet = createRawSnippet<[{ value: string }]>((getValue) => { + const { value } = getValue(); + return { + render: () => + `
${value}
` + }; + }); + return renderSnippet(valueSnippet, { value: formatCurrencyUSD(valueME) }); + } + }, + { + accessorKey: "traffic_light_status", + header: "Semáforo", + cell: ({ row }) => { + const status = row.original.traffic_light_status; + const colorClass = getTrafficLightColor(status); + + const statusSnippet = createRawSnippet<[{ status?: string | null; colorClass: string }]>((getStatus) => { + const { status, colorClass } = getStatus(); + return { + render: () => + ` + ${status || '-'} + ` + }; + }); + return renderSnippet(statusSnippet, { status, colorClass }); + } + }, + { + accessorKey: "invoice_date", + header: "Fecha Factura", + cell: ({ row }) => { + const dateSnippet = createRawSnippet<[{ date: string }]>((getDate) => { + const { date } = getDate(); + return { + render: () => + `
${date}
` + }; + }); + return renderSnippet(dateSnippet, { date: formatDate(row.original.invoice_date) }); + } + }, + { + id: "actions", + cell: ({ row }) => { + return renderComponent(DataTableActions, { invoice: row.original, onSuccess }); + } } ]; } + +// Mantener compatibilidad hacia atrás +export const columns = createColumns(); diff --git a/frontend/src/lib/components/dashboard/invoices/data-table-actions.svelte b/frontend/src/lib/components/dashboard/invoices/data-table-actions.svelte index 4b5f2e65..bbb7a09f 100644 --- a/frontend/src/lib/components/dashboard/invoices/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/invoices/data-table-actions.svelte @@ -3,26 +3,24 @@ import { Button } from '$lib/components/ui/button'; import * as DropdownMenu from '$lib/components/ui/dropdown-menu'; import { Ellipsis, Eye, Pencil, Trash2 } from 'lucide-svelte'; - import { goto } from '$app/navigation'; + import DetailsDialog from './details-dialog.svelte'; + import DeleteDialog from './delete-dialog.svelte'; interface Props { invoice: Invoice; + onSuccess?: () => void; } - let { invoice }: Props = $props(); + let { invoice, onSuccess }: Props = $props(); + + let showDetails = $state(false); + let showDelete = $state(false); - function dispatchView() { - window.dispatchEvent(new CustomEvent('invoiceView', { detail: invoice })); + function handleEdit() { + // Redirigir a la página de edición + window.location.href = `/dashboard/invoices/edit/${invoice.id}`; } - function dispatchDelete() { - window.dispatchEvent(new CustomEvent('invoiceDelete', { detail: invoice })); - } - - function dispatchEdit() { - window.dispatchEvent(new CustomEvent('invoiceEdit', { detail: invoice })); - } - @@ -38,20 +36,36 @@ Acciones - + showDetails = true}> Ver Detalles - + Editar - + showDelete = true} class="text-destructive"> Eliminar - \ No newline at end of file + + + +{#if showDetails} + showDetails = false} + /> +{/if} + +{#if showDelete} + showDelete = false} + {onSuccess} + /> +{/if} \ No newline at end of file diff --git a/frontend/src/lib/components/dashboard/invoices/data-table.svelte b/frontend/src/lib/components/dashboard/invoices/data-table.svelte index 14c41b7e..ef98de23 100644 --- a/frontend/src/lib/components/dashboard/invoices/data-table.svelte +++ b/frontend/src/lib/components/dashboard/invoices/data-table.svelte @@ -83,18 +83,10 @@ {#each row.getVisibleCells() as cell (cell.id)} - {#if cell.column.id === 'actions'} - {@const cellDef = cell.column.columnDef.cell} - {#if cellDef && typeof cellDef === 'function'} - {@const Component = cellDef(cell.getContext())} - - {/if} - {:else} - - {/if} + {/each} diff --git a/frontend/src/lib/components/dashboard/invoices/delete-dialog.svelte b/frontend/src/lib/components/dashboard/invoices/delete-dialog.svelte index f33d7937..c813bbae 100644 --- a/frontend/src/lib/components/dashboard/invoices/delete-dialog.svelte +++ b/frontend/src/lib/components/dashboard/invoices/delete-dialog.svelte @@ -5,27 +5,26 @@ import { companyStore } from "$lib/stores/company.svelte"; import { LoaderCircle } from 'lucide-svelte'; - let { - open = $bindable(false), - item, - onSuccess - }: { - open: boolean; - item: Invoice | null; + interface Props { + invoice: Invoice; + onClose: () => void; onSuccess?: () => void; - } = $props(); + } + + let { invoice, onClose, onSuccess }: Props = $props(); + let open = $state(true); let loading = $state(false); let error = $state(null); async function handleDelete() { - if (!item || !companyStore.activeCompany) return; + if (!invoice || !companyStore.activeCompany) return; loading = true; error = null; try { - const response = await invoicesApi.delete(item.id, companyStore.activeCompany.id); + const response = await invoicesApi.delete(invoice.id, companyStore.activeCompany.id); if (response.error) { error = response.error; @@ -33,7 +32,7 @@ } // Éxito - open = false; + onClose(); if (onSuccess) { onSuccess(); } @@ -48,8 +47,10 @@ function handleOpenChange(newOpen: boolean) { if (!newOpen) { error = null; + onClose(); + } else { + open = newOpen; } - open = newOpen; } @@ -59,30 +60,30 @@ ¿Estás seguro?

Esta acción no se puede deshacer. Se eliminará permanentemente esta factura:

- {#if item} + {#if invoice}
ID: - {item.id} + {invoice.id}
Número de Factura: - {item.invoice_number || 'N/A'} + {invoice.invoice_number || 'N/A'}
Tipo: - {item.operation_type === 'imp' ? 'Importación' : - item.operation_type === 'exp' ? 'Exportación' : 'N/A'} + {invoice.operation_type === 'imp' ? 'Importación' : + invoice.operation_type === 'exp' ? 'Exportación' : 'N/A'}
Proyecto: - {item.project_number || 'N/A'} + {invoice.project_number || 'N/A'}
Pedimento: - {item.compliance_mx?.pedimento || 'N/A'} + {invoice.compliance_mx?.pedimento || 'N/A'}
{/if} diff --git a/frontend/src/lib/components/dashboard/invoices/details-dialog.svelte b/frontend/src/lib/components/dashboard/invoices/details-dialog.svelte index e517faa3..12bc4862 100644 --- a/frontend/src/lib/components/dashboard/invoices/details-dialog.svelte +++ b/frontend/src/lib/components/dashboard/invoices/details-dialog.svelte @@ -5,13 +5,13 @@ import { Badge } from '$lib/components/ui/badge'; import { Button } from '$lib/components/ui/button'; - let { - open = $bindable(false), - invoice - }: { - open: boolean; - invoice: Invoice | null; - } = $props(); + interface Props { + invoice: Invoice; + onClose: () => void; + } + + let { invoice, onClose }: Props = $props(); + let open = $state(true); function formatDate(dateString: string | null | undefined): string { if (!dateString) return '-'; @@ -32,7 +32,7 @@ } - (open = v)}> + { open = v; if (!v) onClose(); }}> Detalles de Factura #{invoice?.id} diff --git a/frontend/src/lib/components/dashboard/invoices/edit/continuation-tab-form.svelte b/frontend/src/lib/components/dashboard/invoices/edit/continuation-tab-form.svelte new file mode 100644 index 00000000..63d613fd --- /dev/null +++ b/frontend/src/lib/components/dashboard/invoices/edit/continuation-tab-form.svelte @@ -0,0 +1,298 @@ + + + +
+ +
+

Información General

+ + +
+ + +
+ + +
+ +
+ + +
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+ + +
+ + +
+ +
+ + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+

Errores de Facturación

+ +
+ + + + + + + + + + {#if formData.errores_facturacion?.length} + {#each formData.errores_facturacion as error} + + + + + + {/each} + {:else} + + + + {/if} + +
LíneaClaveDescripción
{error.linea}{error.clave}{error.descripcion}
+ Sin errores registrados +
+
+ +
+ + + +
+ + +
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+
+
diff --git a/frontend/src/lib/components/dashboard/invoices/edit/general-tab-form.svelte b/frontend/src/lib/components/dashboard/invoices/edit/general-tab-form.svelte new file mode 100644 index 00000000..5f9e640d --- /dev/null +++ b/frontend/src/lib/components/dashboard/invoices/edit/general-tab-form.svelte @@ -0,0 +1,574 @@ + + + +
+ +
+
+

Datos del pedimento

+
+
+ Fecha del: +

{formData.fecha_pedimento_del || '-'}

+
+
+ Fecha al: +

{formData.fecha_pedimento_al || '-'}

+
+
+ Clave: +

{formData.clave_pedimento || '-'}

+
+
+ Régimen: +

{formData.regimen_pedimento || '-'}

+
+
+
+ +

Clientes - Proveedores - Agente Aduanal

+
+ + { + formData.provider_header = v ?? ''; + }} + > + + + {formData.provider_header + ? providerHeaderOptions.find(o => o.value === formData.provider_header)?.label || formData.provider_header + : 'Selecciona encabezado...'} + + + + {#each providerHeaderOptions as option} + + {option.label} + + {/each} + + + { + formData.provider_id = v ? parseInt(v) : null; + }} + > + + + {formData.provider_id + ? providers.find(p => p.id === formData.provider_id)?.name || 'Selecciona...' + : 'Selecciona...'} + + + + {#each providers as provider} + + {provider.name} + + {/each} + + +
+ +
+ + { + formData.sold_to_header = v ?? ''; + }} + > + + + {formData.sold_to_header + ? soldToHeaderOptions.find(o => o.value === formData.sold_to_header)?.label || formData.sold_to_header + : 'Selecciona encabezado...'} + + + + {#each soldToHeaderOptions as option} + + {option.label} + + {/each} + + + { + formData.sold_to_id = v ? parseInt(v) : null; + }} + > + + + {formData.sold_to_id + ? clients.find(c => c.id === formData.sold_to_id)?.name || 'Selecciona...' + : 'Selecciona...'} + + + + {#each clients as client} + + {client.name} + + {/each} + + +
+ +
+ + { + formData.shipped_to_header = v ?? ''; + }} + > + + + {formData.shipped_to_header + ? shippedToHeaderOptions.find(o => o.value === formData.shipped_to_header)?.label || formData.shipped_to_header + : 'Selecciona encabezado...'} + + + + {#each shippedToHeaderOptions as option} + + {option.label} + + {/each} + + + { + formData.shipped_to_id = v ? parseInt(v) : null; + }} + > + + + {formData.shipped_to_id + ? allClientsProviders.find(cp => cp.id === formData.shipped_to_id)?.name || 'Selecciona...' + : 'Selecciona...'} + + + + {#each allClientsProviders as cp} + + {cp.name} ({cp.type === 'client' ? 'C' : 'P'}) + + {/each} + + +
+ +
+
+ + { + formData.customs_broker_id = v || null; + }} + > + + + {formData.customs_broker_id + ? customsBrokers.find(cb => cb.broker_key === formData.customs_broker_id)?.name || '...' + : '...'} + + + + {#each customsBrokers as broker} + + {broker.name} + + {/each} + + +
+ +
+ + { + formData.customs_broker_us_id = v || null; + }} + > + + + {formData.customs_broker_us_id + ? customsBrokers.find(cb => cb.broker_key === formData.customs_broker_us_id)?.name || '...' + : '...'} + + + + {#each customsBrokers as broker} + + {broker.name} + + {/each} + + +
+
+
+ + +
+ +
+

Tipo de Moneda - Pesos Netos y Brutos

+ + +
+ +
+ + +
+
+ + +
+
+ + +
+
+
+ +
+
+ + { + formData.currency_type = v ?? ''; + }} + > + + + {formData.currency_type || '...'} + + + + {#each currencyTypes as currencyType} + + {currencyType.code} + + {/each} + + +
+ +
+ + { + formData.weight_type = v ?? ''; + }} + > + + + {formData.weight_type || '...'} + + + + {#each weightTypeOptions as weightType} + + {weightType.value} + + {/each} + + +
+ +
+ + +
+
+ +
+ + { + formData.invoice_type = v ?? ''; + }} + > + + + {formData.invoice_type + ? `${formData.invoice_type}` + : '...'} + + + + {#each invoiceTypes as type} + + {type.key} - {type.description} + + {/each} + + +
+
+ + +
+

Transportista

+ +
+
+ + +
+ +
+ + { + formData.transport_type = v ?? ''; + }} + > + + + {formData.transport_type || '...'} + + + + {#each transportTypes as transportType} + + {transportType.transport_code} + + {/each} + + +
+
+ +
+ + +
+ +
+
+ + +
+ +
+ + +
+
+ +
+ + +
+ +
+ + +
+
+
+
diff --git a/frontend/src/lib/components/dashboard/invoices/edit/invoice-top-fields.svelte b/frontend/src/lib/components/dashboard/invoices/edit/invoice-top-fields.svelte new file mode 100644 index 00000000..8e4700a4 --- /dev/null +++ b/frontend/src/lib/components/dashboard/invoices/edit/invoice-top-fields.svelte @@ -0,0 +1,176 @@ + + + +
+
+ + { + formData.operation_type = v ? parseInt(v) : null; + }} + > + + + {formData.operation_type !== null + ? (formData.operation_type === 1 ? 'Exp' : 'Imp') + : '...'} + + + + Exportación + Importación + + +
+
+ + { + formData.invoice_type = v ?? ''; + }} + > + + + {formData.invoice_type + ? `${formData.invoice_type}` + : '...'} + + + + {#each invoiceTypes as type} + + {type.key} - {type.description} + + {/each} + + +
+ +
+ + { + formData.is_pedimento_pending = checked; + }} + /> +
+
+ + { + formData.pedimento_id = v ? parseInt(v) : null; + if (v) { + handlePedimentoChange(v); + } + }} + > + + + {formData.pedimento || 'Selecciona pedimento...'} + + + + {#each pedimentos as pedimento} + + {pedimento.year}-{pedimento.customs_office}-{pedimento.license}-{pedimento.pedimento_number} + + {/each} + + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
diff --git a/frontend/src/lib/components/dashboard/invoices/edit/observations-tab-form.svelte b/frontend/src/lib/components/dashboard/invoices/edit/observations-tab-form.svelte new file mode 100644 index 00000000..1f9c1204 --- /dev/null +++ b/frontend/src/lib/components/dashboard/invoices/edit/observations-tab-form.svelte @@ -0,0 +1,404 @@ + + + + +
+
+

Observacion de la factura mexicana y bilingue:

+
+