diff --git a/backend/api/v1/modules/a76/invoices/models.py b/backend/api/v1/modules/a76/invoices/models.py index c005f38d..a5337664 100644 --- a/backend/api/v1/modules/a76/invoices/models.py +++ b/backend/api/v1/modules/a76/invoices/models.py @@ -38,6 +38,7 @@ class InvoiceHeader(Base, TenantScopedMixin, TimestampMixin): id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) # Identifiers + 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 @@ -151,6 +152,7 @@ class InvoiceComplianceMx(Base, TenantScopedMixin, TimestampMixin): 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 @@ -268,11 +270,13 @@ class InvoiceLogistics(Base, TenantScopedMixin, TimestampMixin): 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 Info carrier_id: Mapped[Optional[str]] = mapped_column(String(10)) # TRANSPORTISTA / Transportista - carrier_us_id: Mapped[Optional[str]] = mapped_column(String(10)) # TRANSPORTISTAAME / Transportista americano + transport_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_mode: Mapped[Optional[str]] = mapped_column(String(15)) # MODTRANS / Modo 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 @@ -357,5 +361,8 @@ class InvoiceCollections(Base, TenantScopedMixin, TimestampMixin): 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") 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/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/edit/compliance-tab-form.svelte b/frontend/src/lib/components/dashboard/invoices/edit/compliance-tab-form.svelte deleted file mode 100644 index 15ef3ab6..00000000 --- a/frontend/src/lib/components/dashboard/invoices/edit/compliance-tab-form.svelte +++ /dev/null @@ -1,60 +0,0 @@ - - - - - Cumplimiento Aduanal - Información de cumplimiento y aduanas - - -
-
- - -
-
- - -
-
-

Más campos por implementar...

-
-
\ No newline at end of file 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/financials-tab-form.svelte b/frontend/src/lib/components/dashboard/invoices/edit/financials-tab-form.svelte deleted file mode 100644 index 14e4b9ff..00000000 --- a/frontend/src/lib/components/dashboard/invoices/edit/financials-tab-form.svelte +++ /dev/null @@ -1,53 +0,0 @@ - - - - - Información Financiera - Valores, monedas y datos financieros - - -
-
- - -
-
- - -
-
-

Más campos por implementar...

-
-
\ No newline at end of file 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 index 37940c56..ac50af33 100644 --- a/frontend/src/lib/components/dashboard/invoices/edit/general-tab-form.svelte +++ b/frontend/src/lib/components/dashboard/invoices/edit/general-tab-form.svelte @@ -1,22 +1,32 @@ - - - - Información General - - Edita los datos principales de la factura - - - -
- -
-
- - { - formData.operation_type = v ? parseInt(v) : null; - }} - > - - - {formData.operation_type !== null - ? operationOptions.find(o => o.value === formData.operation_type)?.label - : 'Selecciona tipo...'} - - - - {#each operationOptions as option} - {option.label} - {/each} - - -
+ -
- - { - formData.invoice_type = v ?? ''; - }} - > - - - {formData.invoice_type - ? `${formData.invoice_type} - ${filteredInvoiceTypes().find(t => t.key === formData.invoice_type)?.description || ''}` - : 'Selecciona tipo...'} - - - - {#each filteredInvoiceTypes() as type} - - {type.key} - {type.description} - - {/each} - - -
-
+ +
+ +
+

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.traffic_light_status = v ?? 'green'; - }} - > - - - {trafficLightOptions.find(t => t.value === formData.traffic_light_status)?.label || 'Verde'} - - - - {#each trafficLightOptions as option} - {option.label} - {/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} + + +
+
+
- -
- -