258 lines
9.2 KiB
Python
258 lines
9.2 KiB
Python
from typing import Optional, List
|
|
from datetime import datetime, date
|
|
from decimal import Decimal
|
|
from pydantic import BaseModel, Field
|
|
from .models import OperationType
|
|
|
|
|
|
# --- Base Schemas ---
|
|
class InvoiceHeaderBase(BaseModel):
|
|
"""Base fields for Invoice Header"""
|
|
operation_type: Optional[OperationType] = Field(
|
|
None, max_length=20, description="Operation type: imp/exp")
|
|
invoice_type: Optional[str] = Field(
|
|
None, max_length=5, description="Invoice type key")
|
|
invoice_number: Optional[str] = Field(
|
|
None, max_length=20, 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")
|
|
invoice_date: Optional[date] = Field(None, description="Invoice date")
|
|
is_updated: Optional[bool] = Field(None, description="Status")
|
|
traffic_light_status: Optional[str] = Field(
|
|
None, max_length=50, description="Traffic light status (SEMAFORO)")
|
|
process_log: Optional[str] = Field(
|
|
None, max_length=300, description="Processing log")
|
|
comments_status: Optional[str] = Field(
|
|
None, description="Comments and 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")
|
|
|
|
|
|
class InvoiceComplianceMxBase(BaseModel):
|
|
"""Base fields for Compliance MX"""
|
|
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)")
|
|
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")
|
|
is_mixed: Optional[bool] = Field(
|
|
None, description="Is mixed operation")
|
|
waste_type: Optional[str] = Field(
|
|
None, max_length=1, description="Waste type")
|
|
appendix_17: Optional[int] = Field(None, description="Appendix 17")
|
|
edocument: Optional[str] = Field(
|
|
None, max_length=50, description="E-document")
|
|
electronic_signature: Optional[str] = Field(
|
|
None, max_length=999, description="Electronic signature")
|
|
sem_id: Optional[int] = Field(None, description="SEM ID")
|
|
|
|
|
|
class InvoiceFinancialsBase(BaseModel):
|
|
"""Base fields for Financials"""
|
|
currency: Optional[str] = Field(
|
|
None, max_length=3, description="Currency code")
|
|
exchange_rate: Optional[Decimal] = Field(None, description="Exchange rate")
|
|
value_mn: Optional[Decimal] = Field(None, description="Value in MXN")
|
|
value_me: Optional[Decimal] = Field(
|
|
None, description="Value in foreign currency")
|
|
customs_value_mn: Optional[Decimal] = Field(
|
|
None, description="Customs value in MXN")
|
|
freight: Optional[Decimal] = Field(None, description="Freight cost")
|
|
insurance: Optional[Decimal] = Field(None, description="Insurance cost")
|
|
iva_mn: Optional[Decimal] = Field(None, description="IVA in MXN")
|
|
iva_factor: Optional[Decimal] = Field(None, description="IVA factor")
|
|
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")
|
|
|
|
|
|
class InvoiceLogisticsBase(BaseModel):
|
|
"""Base fields for Logistics"""
|
|
carrier_id: Optional[str] = Field(
|
|
None, max_length=10, description="Carrier ID")
|
|
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")
|
|
vehicle_num: Optional[str] = Field(
|
|
None, max_length=20, description="Vehicle number")
|
|
license_plate: Optional[str] = Field(
|
|
None, max_length=20, description="License plate")
|
|
seal_number: Optional[str] = Field(
|
|
None, max_length=15, description="Seal number")
|
|
guide_number: Optional[str] = Field(
|
|
None, max_length=20, description="Guide number")
|
|
entry_exit_date: Optional[date] = Field(
|
|
None, description="Entry/Exit date")
|
|
|
|
|
|
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"""
|
|
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 ---
|
|
|
|
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[List[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"""
|
|
pass
|
|
|
|
|
|
class InvoiceHeaderUpdate(InvoiceHeaderBase):
|
|
"""Schema for updating Invoice Header with nested relations"""
|
|
compliance_mx: Optional[InvoiceComplianceMxUpdate] = None
|
|
financials: Optional[InvoiceFinancialsUpdate] = None
|
|
logistics: Optional[List[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"""
|
|
invoice_id: int
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class InvoiceLogisticsResponse(InvoiceLogisticsBase):
|
|
"""Schema for Logistics response"""
|
|
logistics_id: int
|
|
invoice_id: int
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class InvoiceSalesDetailsResponse(InvoiceSalesDetailsBase):
|
|
"""Schema for Sales Details response"""
|
|
detail_id: int
|
|
invoice_id: int
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class InvoiceCollectionsResponse(InvoiceCollectionsBase):
|
|
"""Schema for Collections response"""
|
|
collection_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: List[InvoiceLogisticsResponse] = []
|
|
details: List[InvoiceSalesDetailsResponse] = []
|
|
collections: List[InvoiceCollectionsResponse] = []
|
|
|
|
class Config:
|
|
from_attributes = True
|