Files
plantillas-proyectos/backend/api/v1/modules/a76/invoices/schemas.py

487 lines
21 KiB
Python

from typing import Literal, Optional, List
from datetime import datetime, date
from decimal import Decimal
from pydantic import BaseModel, Field
from .models import DestinationOriginCove, OperationType, Currency, TransportType, WeightUnit
# --- Base Schemas ---
class InvoiceHeaderBase(BaseModel):
"""Base fields for Invoice Header"""
system: Optional[str] = Field(
None, max_length=12, description="System of origin")
operation_type: Optional[OperationType] = Field(
..., description="Operation type: imp/exp/sm/ctm")
invoice_type: Optional[str] = Field(
None, max_length=5, description="Invoice type key")
document_type: str = Field(
..., max_length=3, description="Document type (Regimen Aduanero)")
invoice_number: Optional[str] = Field(
None, max_length=100, description="Invoice number")
project_number: Optional[str] = Field(
None, max_length=14, description="Project number")
purchase_order: Optional[str] = Field(
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: date = Field(..., description="Invoice date")
emission_date: Optional[date] = Field(None, description="Emission date")
is_updated: bool = Field(False, 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")
process_log: Optional[str] = Field(
None, max_length=300, description="Processing log")
is_updated_rec: Optional[int] = Field(None, description="Reception status")
is_updated_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 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[bool] = Field(False, description="Generate ID")
generate_desc_parties: Optional[str] = Field(
None, max_length=12, description="Generate description of parties")
apply_manual_discount: Optional[bool] = Field(False, 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):
"""Base fields for Compliance MX"""
pedimento_id: Optional[int] = Field(
None, description="Pedimento id")
pedimento_r1: Optional[int] = Field(
None, description="Pedimento id (R1)")
pedimento_k1: Optional[int] = Field(
None, description="Pedimento id (K1)")
remesa: Optional[int] = Field(None, description="Remesa")
aduana: Optional[str] = Field(None, max_length=5, description="Customs office")
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: str = Field(
None, max_length=20, description="Provider header")
provider_id: int = Field(
None, description="Provider ID")
sold_to_header: str = Field(
None, max_length=20, description="Sold to header")
sold_to_id: int = Field(
None, description="Sold to ID")
shipped_to_header: str = Field(
None, max_length=20, description="Shipped to header")
shipped_to_id:int = Field(
None, description="Shipped to ID")
shipped_by_header: Optional[int] = Field(
None, max_length=20, description="Shipped by header")
shipped_by_id: Optional[int] = Field(
None, description="Shipped by ID")
customs_broker_id: int = Field(
None, description="Customs broker ID")
customs_broker_us_id: Optional[int] = 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(
False, 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[bool] = Field(
False, 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: bool = Field(..., description="Is pedimento pending")
is_owner_of_goods: Optional[bool] = Field(
False, description="Is owner of goods")
generate_balances: Optional[bool] = Field(
False, 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[DestinationOriginCove] = Field('franja_front_norte', max_length=20, 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")
class InvoiceFinancialsBase(BaseModel):
"""Base fields for Financials"""
currency: Currency = Field(
None, max_length=7, description="Currency code")
currency_type: Optional[str] = Field(
"USD", description="Currency type")
exchange_rate: Decimal = Field(0.00, 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_me: Optional[Decimal] = Field(
None, description="IVA in foreign currency")
iva_mc: Optional[Decimal] = Field(
None, description="IVA in third currency")
iva_factor: Optional[Decimal] = Field(None, 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: TransportType = 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(
30, max_length=15, description="Transport mode")
driver_name: Optional[str] = Field(
None, max_length=80, description="Driver name")
is_rail: Optional[bool] = Field(
False, description="Is rail transport")
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: WeightUnit = Field(
default="kgs", max_length=3, 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[bool] = Field(
False, description="Is CTM process")
class InvoiceSalesDetailsBase(BaseModel):
"""Base fields for Sales Details"""
line_number: int = Field(..., description="Line number")
sales_order: Optional[str] = Field(
None, max_length=20, description="Sales order")
colors_description: Optional[str] = Field(
None, max_length=49, description="Colors description")
square_color_code: Optional[str] = Field(
None, max_length=1, description="Square color code")
line_bundles: Optional[int] = Field(None, description="Line bundles count")
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")
# --- Create Schemas ---
class InvoiceComplianceMxCreate(InvoiceComplianceMxBase):
"""Schema for creating Compliance MX"""
pass
class InvoiceFinancialsCreate(InvoiceFinancialsBase):
"""Schema for creating Financials"""
pass
class InvoiceLogisticsCreate(InvoiceLogisticsBase):
"""Schema for creating Logistics"""
pass
class InvoiceSalesDetailsCreate(InvoiceSalesDetailsBase):
"""Schema for creating Sales Details"""
pass
class InvoiceCollectionsCreate(InvoiceCollectionsBase):
"""Schema for creating Collections"""
pass
class InvoiceHeaderCreate(InvoiceHeaderBase):
"""Schema for creating Invoice Header with nested relations"""
compliance_mx: Optional[InvoiceComplianceMxCreate] = None
financials: Optional[InvoiceFinancialsCreate] = None
logistics: Optional[InvoiceLogisticsCreate] = None
details: Optional[List[InvoiceSalesDetailsCreate]] = None
collections: Optional[List[InvoiceCollectionsCreate]] = None
# --- Update Schemas ---
class InvoiceComplianceMxUpdate(InvoiceComplianceMxBase):
"""Schema for updating Compliance MX"""
pass
class InvoiceFinancialsUpdate(InvoiceFinancialsBase):
"""Schema for updating Financials"""
pass
class InvoiceLogisticsUpdate(InvoiceLogisticsBase):
"""Schema for updating Logistics"""
pass
class InvoiceSalesDetailsUpdate(InvoiceSalesDetailsBase):
"""Schema for updating Sales Details"""
line_number: Optional[int] = None
class InvoiceCollectionsUpdate(InvoiceCollectionsBase):
"""Schema for updating Collections"""
line_number: Optional[int] = None
class InvoiceHeaderUpdate(InvoiceHeaderBase):
"""Schema for updating Invoice Header with nested relations"""
id: int
compliance_mx: Optional[InvoiceComplianceMxUpdate] = None
financials: Optional[InvoiceFinancialsUpdate] = None
logistics: Optional[InvoiceLogisticsUpdate] = None
details: Optional[List[InvoiceSalesDetailsUpdate]] = None
collections: Optional[List[InvoiceCollectionsUpdate]] = None
# --- Response Schemas ---
class InvoiceComplianceMxResponse(InvoiceComplianceMxBase):
"""Schema for Compliance MX response"""
invoice_id: int
class Config:
from_attributes = True
class InvoiceFinancialsResponse(InvoiceFinancialsBase):
"""Schema for Financials response"""
id: int
invoice_id: int
class Config:
from_attributes = True
class InvoiceLogisticsResponse(InvoiceLogisticsBase):
"""Schema for Logistics response"""
id: int
invoice_id: int
class Config:
from_attributes = True
class InvoiceSalesDetailsResponse(InvoiceSalesDetailsBase):
"""Schema for Sales Details response"""
id: int
invoice_id: int
class Config:
from_attributes = True
class InvoiceCollectionsResponse(InvoiceCollectionsBase):
"""Schema for Collections response"""
id: int
invoice_id: int
class Config:
from_attributes = True
class InvoiceHeaderResponse(InvoiceHeaderBase):
"""Schema for Invoice Header response with nested relations"""
id: int
capture_date: datetime
compliance_mx: Optional[InvoiceComplianceMxResponse] = None
financials: Optional[InvoiceFinancialsResponse] = None
logistics: Optional[InvoiceLogisticsResponse] = []
details: Optional[InvoiceSalesDetailsResponse] = []
collections: Optional[InvoiceCollectionsResponse] = []
class Config:
from_attributes = True