from typing import Optional from pydantic import BaseModel, Field, field_validator class TrailerBaseDTO(BaseModel): trailer_number: str = Field(..., description="Trailer number (primary identifier)") trailer_id: Optional[int] = Field(None, description="Internal trailer integer ID") ace_trailer_number: Optional[str] = None trailer_type_key: Optional[str] = None seal: Optional[str] = None entity_code: Optional[str] = None plate_number: Optional[str] = None state: Optional[str] = None country: Optional[str] = None container_key: Optional[str] = None @field_validator("trailer_number", mode="before") @classmethod def strip_trailer_number(cls, v: object) -> object: if isinstance(v, str): return v.strip() return v @field_validator("trailer_type_key", mode="before") @classmethod def trailer_type_key_optional_fk(cls, v: object) -> Optional[str]: """Empty string from JSON must become NULL for FK; normalize case for catalog match.""" if v is None: return None if not isinstance(v, str): return None s = v.strip().upper() return None if s == "" else s @field_validator( "ace_trailer_number", "seal", "entity_code", "plate_number", "state", "country", "container_key", mode="before", ) @classmethod def empty_optional_str_to_none(cls, v: object) -> Optional[str]: """JSON often sends ''; nullable columns should get NULL, not ''.""" if v is None: return None if not isinstance(v, str): return None s = v.strip() return None if s == "" else s class TrailerCreateDTO(TrailerBaseDTO): """Schema for creating a trailer""" pass class TrailerUpdateDTO(TrailerBaseDTO): """Schema for updating a trailer""" trailer_number: Optional[str] = Field(None, description="Trailer number (cannot be modified)") class TrailerResponseDTO(TrailerBaseDTO): """Schema for trailer response""" company_id: int tenant_id: int class Config: from_attributes = True