"""Schemas del módulo Tarifario.""" from datetime import date, datetime from decimal import Decimal from pydantic import BaseModel, ConfigDict, Field # ---------- Quiebres y cargos ---------- class RateBreakDTO(BaseModel): model_config = ConfigDict(from_attributes=True) from_qty: Decimal = Field(0) rate: Decimal = Field(0) class RateChargeDTO(BaseModel): model_config = ConfigDict(from_attributes=True) concept: str = Field(..., max_length=60) charge_type: str = Field("fijo", max_length=20) value: Decimal | None = None condition: str | None = None class RateChargeCreate(BaseModel): concept: str = Field(..., max_length=60) charge_type: str = Field("fijo", max_length=20) value: Decimal | None = None condition: str | None = None rate_lane_id: int | None = None class RateChargeUpdate(BaseModel): concept: str | None = Field(None, max_length=60) charge_type: str | None = Field(None, max_length=20) value: Decimal | None = None condition: str | None = None class RateChargeResponse(BaseModel): model_config = ConfigDict(from_attributes=True) id: int rate_sheet_id: int | None rate_lane_id: int | None concept: str charge_type: str value: Decimal | None condition: str | None # ---------- Rutas ---------- class RateLaneBase(BaseModel): origin: str | None = Field(None, max_length=20) destination: str | None = Field(None, max_length=20) region: str | None = Field(None, max_length=60) equipment_type: str | None = Field(None, max_length=20) rate_unit: str | None = Field(None, max_length=20) min_charge: Decimal | None = None flat_rate: Decimal | None = None transit_days: int | None = None notes: str | None = None class RateLaneCreate(RateLaneBase): breaks: list[RateBreakDTO] = Field(default_factory=list) class RateLaneUpdate(RateLaneBase): breaks: list[RateBreakDTO] | None = None class RateLaneResponse(RateLaneBase): model_config = ConfigDict(from_attributes=True) id: int rate_sheet_id: int breaks: list[RateBreakDTO] = Field(default_factory=list) # ---------- Tarifario (cabecera) ---------- class RateSheetBase(BaseModel): supplier_id: int | None = None mode: str = Field(..., max_length=20) name: str = Field(..., min_length=1, max_length=255) currency: str | None = Field("USD", max_length=3) valid_from: date | None = None valid_to: date | None = None default_origin: str | None = Field(None, max_length=20) status: str = Field("borrador", max_length=20) notes: str | None = None class RateSheetCreate(RateSheetBase): pass class RateSheetUpdate(BaseModel): supplier_id: int | None = None mode: str | None = Field(None, max_length=20) name: str | None = Field(None, max_length=255) currency: str | None = Field(None, max_length=3) valid_from: date | None = None valid_to: date | None = None default_origin: str | None = Field(None, max_length=20) status: str | None = Field(None, max_length=20) notes: str | None = None class RateSheetResponse(RateSheetBase): model_config = ConfigDict(from_attributes=True) id: int tenant_id: int company_id: int source_file: str | None = None created_by: str | None = None updated_by: str | None = None created_at: datetime updated_at: datetime lane_count: int | None = None # ---------- Importación ---------- class ImportPreviewRow(BaseModel): row: int data: dict ok: bool warnings: list[str] = Field(default_factory=list) errors: list[str] = Field(default_factory=list) class ImportPreview(BaseModel): mode: str total: int valid: int rows: list[ImportPreviewRow] columns: list[str] class ImportConfirm(RateSheetCreate): lanes: list[RateLaneCreate] # ---------- Costeo ---------- class CostRequest(BaseModel): mode: str origin: str | None = None destination: str | None = None on_date: date | None = None gross_weight_kg: Decimal | None = None volume_m3: Decimal | None = None # Dimensiones (cm) para el peso volumétrico aéreo (P/Vol = L×A×H×cant / 6000) length_cm: Decimal | None = None width_cm: Decimal | None = None height_cm: Decimal | None = None equipment_type: str | None = None quantity: int = 1 dangerous: bool = False class CostChargeLine(BaseModel): concept: str amount: Decimal class CostOption(BaseModel): rate_sheet_id: int rate_sheet_name: str supplier_id: int | None currency: str | None chargeable: Decimal | None = None # peso/wm facturable usado base_cost: Decimal charges: list[CostChargeLine] = Field(default_factory=list) total_cost: Decimal transit_days: int | None = None detail: str | None = None class CostResult(BaseModel): request: CostRequest options: list[CostOption]