""" DTOs (Data Transfer Objects) para módulo de clases SCAII y SCAF Reemplaza schemas.py siguiendo enfoque DDD y estilo NestJS """ from pydantic import BaseModel, Field from typing import Optional from datetime import datetime class ClassCreateDTO(BaseModel): """DTO para crear una clase""" client_id: int = Field(..., description="Client key") class_code: str = Field(..., max_length=8, description="Class code") description_spanish: Optional[str] = Field(None, max_length=500, description="Description in Spanish") description_english: Optional[str] = Field(None, max_length=500, description="Description in English") material_key: Optional[str] = Field(None, max_length=10, description="Material key (homologated TIPOMAT/TIPOMATEQUIPO)") unit_of_measure: Optional[str] = Field(None, max_length=5, description="Unit of measure (homologated UNIMEDIDA)") fraction: Optional[str] = Field(None, max_length=10, description="Mexican tariff fraction") us_fraction: Optional[str] = Field(None, max_length=16, description="US tariff fraction") sub_key: Optional[str] = Field(None, max_length=5, description="Sub classification key") physical_review: Optional[int] = Field(None, description="Physical review indicator") iva_exempt_fraction: Optional[str] = Field(None, max_length=4, description="IVA exempt fraction") class Config: from_attributes = True class ClassUpdateDTO(BaseModel): """DTO para actualizar una clase""" description_spanish: Optional[str] = Field(None, max_length=500, description="Description in Spanish") description_english: Optional[str] = Field(None, max_length=500, description="Description in English") material_key: Optional[str] = Field(None, max_length=10, description="Material key (homologated TIPOMAT/TIPOMATEQUIPO)") unit_of_measure: Optional[str] = Field(None, max_length=5, description="Unit of measure (homologated UNIMEDIDA)") fraction: Optional[str] = Field(None, max_length=10, description="Mexican tariff fraction") us_fraction: Optional[str] = Field(None, max_length=16, description="US tariff fraction") sub_key: Optional[str] = Field(None, max_length=5, description="Sub classification key") physical_review: Optional[int] = Field(None, description="Physical review indicator") iva_exempt_fraction: Optional[str] = Field(None, max_length=4, description="IVA exempt fraction") class Config: from_attributes = True class ClassResponseDTO(BaseModel): """DTO para respuesta de clase""" client_id: int class_code: str description_spanish: Optional[str] = None description_english: Optional[str] = None material_key: Optional[str] = None unit_of_measure: Optional[str] = None fraction: Optional[str] = None us_fraction: Optional[str] = None sub_key: Optional[str] = None physical_review: Optional[int] = None iva_exempt_fraction: Optional[str] = None class Config: from_attributes = True class ClassBasicDTO(BaseModel): """DTO para información básica de clase""" client_id: int class_code: str description_spanish: Optional[str] = None description_english: Optional[str] = None material_key: Optional[str] = None fraction: Optional[str] = None class Config: from_attributes = True class ClassListDTO(BaseModel): """DTO para lista de clases""" classes: list[ClassBasicDTO] total: int page: int size: int class Config: from_attributes = True class ClassSearchDTO(BaseModel): """DTO para búsqueda de clases""" client_id: Optional[int] = Field(None, description="Filter by client key") class_code: Optional[str] = Field(None, description="Search by class code") description: Optional[str] = Field(None, description="Search in descriptions") material_key: Optional[str] = Field(None, description="Filter by material key") fraction: Optional[str] = Field(None, description="Filter by tariff fraction") physical_review: Optional[int] = Field(None, description="Filter by physical review indicator") class Config: from_attributes = True