276 lines
8.7 KiB
Python
276 lines
8.7 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 decimal import Decimal
|
|
from typing import Optional
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
|
|
class ClassCreateDTO(BaseModel):
|
|
"""DTO para crear una clase"""
|
|
|
|
class_code: str = Field(..., max_length=8, description="Class code")
|
|
description_es: str = Field(
|
|
..., max_length=500, description="Description in Spanish (required)"
|
|
)
|
|
description_en: Optional[str] = Field(
|
|
None, max_length=500, description="Description in English"
|
|
)
|
|
material_key: str = Field(
|
|
...,
|
|
max_length=10,
|
|
description="Material key - Fixed Asset Type (required)",
|
|
)
|
|
unit_of_measure: str = Field(
|
|
..., max_length=5, description="Unit of measure - U.M. comercial (required)"
|
|
)
|
|
stock_unit_of_measure: Optional[str] = Field(
|
|
None,
|
|
max_length=5,
|
|
description="UM Existencia - solo SCAII/inventory (UMEXISTENCIA)",
|
|
)
|
|
fraction: str = Field(
|
|
..., max_length=20, description="Mexican tariff fraction (required)"
|
|
)
|
|
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"
|
|
)
|
|
is_active: Optional[bool] = Field(
|
|
True, description="Indicates if the class is active (default: true)"
|
|
)
|
|
system: str = Field(
|
|
default="fixed_asset", max_length=12,
|
|
description="Sistema: 'fixed_asset' (SCAF) o 'inventory' (SCAII)"
|
|
)
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class ClassCreateDTOFA(ClassCreateDTO):
|
|
"""DTO para crear una clase de activo fijo (clase base + extensión FA)"""
|
|
|
|
# Campos específicos de activos fijos (a24.fa_classes)
|
|
import_tariff_code: Optional[str] = Field(
|
|
None, max_length=10, description="Código de fracción de importación"
|
|
)
|
|
import_tariff_type: Optional[str] = Field(
|
|
None, max_length=6, description="Tipo de fracción de importación"
|
|
)
|
|
export_tariff_code: Optional[str] = Field(
|
|
None, max_length=10, description="Código de fracción de exportación"
|
|
)
|
|
export_tariff_type: Optional[str] = Field(
|
|
None, max_length=6, description="Tipo de fracción de exportación"
|
|
)
|
|
depreciation_rate: Optional[Decimal] = Field(
|
|
None, ge=0, le=100, description="Tasa de depreciación anual (%)"
|
|
)
|
|
fda_code: Optional[str] = Field(
|
|
None, max_length=20, description="Código FDA"
|
|
)
|
|
eccn_code: Optional[str] = Field(
|
|
None, max_length=20, description="Código ECCN"
|
|
)
|
|
class_enabled: Optional[bool] = Field(
|
|
True, description="Indica si la clase está habilitada"
|
|
)
|
|
is_active: Optional[bool] = Field(
|
|
True, description="Indicates if the class is active (default: true)"
|
|
)
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
class ClassUpdateDTO(BaseModel):
|
|
"""DTO para actualizar una clase"""
|
|
|
|
class_code: Optional[str] = Field(
|
|
None, 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)"
|
|
)
|
|
stock_unit_of_measure: Optional[str] = Field(
|
|
None,
|
|
max_length=5,
|
|
description="UM Existencia - solo SCAII/inventory (UMEXISTENCIA)",
|
|
)
|
|
fraction: Optional[str] = Field(
|
|
None, max_length=20, 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"
|
|
)
|
|
is_active: Optional[bool] = Field(
|
|
True, description="Indicates if the class is active (default: true)"
|
|
)
|
|
system: Optional[str] = Field(
|
|
None, max_length=12,
|
|
description="Sistema: 'fixed_asset' (SCAF) o 'inventory' (SCAII)"
|
|
)
|
|
|
|
model_config = ConfigDict(from_attributes=True, extra='forbid') # Explicitly forbid extra fields
|
|
|
|
|
|
class ClassResponseDTO(BaseModel):
|
|
"""DTO para respuesta de clase"""
|
|
|
|
id: int
|
|
tenant_id: int
|
|
company_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
|
|
stock_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
|
|
is_active: Optional[bool] = None
|
|
system: str = "fixed_asset"
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class ClassResponseDTOFA(ClassResponseDTO):
|
|
"""DTO para respuesta de clase de activo fijo (incluye campos FA)"""
|
|
|
|
# Campos de a24.fa_classes
|
|
fa_id: Optional[int] = None
|
|
import_tariff_code: Optional[str] = None
|
|
import_tariff_type: Optional[str] = None
|
|
export_tariff_code: Optional[str] = None
|
|
export_tariff_type: Optional[str] = None
|
|
depreciation_rate: Optional[Decimal] = None
|
|
fda_code: Optional[str] = None
|
|
eccn_code: Optional[str] = None
|
|
class_enabled: Optional[bool] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class ClassBasicDTO(BaseModel):
|
|
"""DTO para información básica de clase"""
|
|
|
|
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"""
|
|
|
|
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
|
|
|
|
|
|
class ClassWithFADataResponse(BaseModel):
|
|
"""DTO para respuesta de clase con datos FA embebidos (para fixed-asset-classes)"""
|
|
|
|
# Base class fields
|
|
id: int
|
|
tenant_id: int
|
|
company_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
|
|
stock_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
|
|
system: str = "fixed_asset"
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
# FA-specific fields (embedded from a24.fa_classes)
|
|
fa_class_id: Optional[int] = None
|
|
import_tariff_code: Optional[str] = None
|
|
import_tariff_type: Optional[str] = None
|
|
export_tariff_code: Optional[str] = None
|
|
export_tariff_type: Optional[str] = None
|
|
depreciation_rate: Optional[Decimal] = None
|
|
fda_code: Optional[str] = None
|
|
eccn_code: Optional[str] = None
|
|
class_enabled: Optional[bool] = None
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
class ClassWithFADataPaginatedResponse(BaseModel):
|
|
"""Lista paginada de clases con datos FA (fixed-asset-classes)"""
|
|
|
|
items: list[ClassWithFADataResponse]
|
|
total: int
|
|
page: int
|
|
page_size: int
|
|
|
|
model_config = ConfigDict(from_attributes=True) |