Files
plantillas-proyectos/backend/api/v1/modules/a76/classes/dto.py
KevinMrkz3221 99aff32eea feat: Convertir módulo de clases para usar TenantCRUDRoutes
Cambios en backend:
- Actualizado ClassResponseDTO con campos de tenant y timestamps
- Agregados métodos estáticos en servicio (get_all, get_by_id, create, update, delete)
- Reemplazados endpoints de rutas con inicialización de TenantCRUDRoutes
- Corregida ruta de importación del modelo Company en security.py
- Actualizados nombres de campos en DTO para coincidir con modelo (description_es/en)
- Agregada validación para constraint de foreign key de material_key
- Agregada validación de class_code duplicado en método create
- Agregado TimestampMixin al modelo Class
- Creada migración de Alembic para agregar columnas timestamp a tabla classes
- Corregido orden de parámetros en firma del método update

Cambios en frontend:
- Actualizados componentes de UI para módulo de clases
2025-11-15 20:05:29 -06:00

151 lines
4.4 KiB
Python

"""
DTOs (Data Transfer Objects) para módulo de clases SCAII y SCAF
Reemplaza schemas.py siguiendo enfoque DDD y estilo NestJS
"""
from datetime import datetime
from typing import Optional
from pydantic import BaseModel, ConfigDict, Field
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_es: Optional[str] = Field(
None, max_length=500, description="Description in Spanish"
)
description_en: 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_es: Optional[str] = Field(
None, max_length=500, description="Description in Spanish"
)
description_en: 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"""
id: int
tenant_id: int
company_id: int
client_id: int
class_code: str
description_es: Optional[str] = None
description_en: 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
created_at: datetime
updated_at: datetime
model_config = ConfigDict(from_attributes=True)
class ClassBasicDTO(BaseModel):
"""DTO para información básica de clase"""
client_id: int
class_code: str
description_es: Optional[str] = None
description_en: 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