""" Modelo ORM para datos específicos de Inventario y Manufactura (S-Partes) - Anexo 24 """ from typing import TYPE_CHECKING, Optional from decimal import Decimal from api.v1.common.base_models import TenantScopedMixin, TimestampMixin from core.database import Base from sqlalchemy import ( Integer, Numeric, PrimaryKeyConstraint, String, Boolean, ForeignKeyConstraint ) from sqlalchemy.orm import Mapped, mapped_column, relationship if TYPE_CHECKING: from api.v1.modules.a76.parts.models import Part class InvPart(Base, TenantScopedMixin, TimestampMixin): """ Tabla inv_partes: Extensión de Anexo 24 para Inventarios (SPartes). """ __tablename__ = "inv_partes" __table_args__ = ( PrimaryKeyConstraint("id", name="inv_partes_pkey"), ForeignKeyConstraint( ["id"], ["a76.parts.id"], name="fk_inv_partes_master" ), {"schema": "a24", "extend_existing": True}, ) # Relación 1:1 - El ID es el mismo de la tabla maestra id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=False) # --- 1. ATRIBUTOS PRINCIPALES DE INVENTARIO --- part_type: Mapped[Optional[str]] = mapped_column(String(10)) # TIPOPARTE material_type: Mapped[Optional[str]] = mapped_column(String(10)) # TIPOMAT reference_number: Mapped[Optional[str]] = mapped_column(String(70)) # NUMPARTEREF flex_reference_number: Mapped[Optional[str]] = mapped_column(String(120)) # NUMPARTEREFFLEX # Conversiones equivalent_uom: Mapped[Optional[str]] = mapped_column(String(5)) # UNIMEDEQUIV conversion_factor: Mapped[Optional[Decimal]] = mapped_column(Numeric(19, 8)) # FACTORCONV stock_uom: Mapped[Optional[str]] = mapped_column(String(5)) # UMEXISTENCIA alternate_uom: Mapped[Optional[str]] = mapped_column(String(5)) # UNIMEDALTERNA conversion_uom: Mapped[Optional[str]] = mapped_column(String(9)) # UMCONVERSION # Valor Agregado added_value: Mapped[Optional[Decimal]] = mapped_column(Numeric(23, 8)) # VALORAGREGADO added_value_type: Mapped[Optional[str]] = mapped_column(String(2)) # TIPOVA assigned_client: Mapped[Optional[str]] = mapped_column(String(50)) # CLIENTEASIGNADO supplier_code: Mapped[Optional[str]] = mapped_column(String(8)) # PROVEEDOR is_textile: Mapped[Optional[str]] = mapped_column(String(2)) # ESTEXTIL # --- 2. MANUFACTURA Y PELIGROSIDAD --- bom_version: Mapped[Optional[int]] = mapped_column(Integer) # VERSIONBOM / VERSIONBILL is_repair: Mapped[Optional[str]] = mapped_column(String(3)) # ESREPARACION is_hazardous: Mapped[Optional[str]] = mapped_column(String(1)) # ESMATPELIGROSO emergency_number: Mapped[Optional[str]] = mapped_column(String(30)) # NUMEMERGENCIA danger_class: Mapped[Optional[str]] = mapped_column(String(4)) # CLASEDEPELIGRO packaging_group: Mapped[Optional[str]] = mapped_column(String(3)) # GRUPOEMBALAJE # Dimensiones width: Mapped[Optional[str]] = mapped_column(String(50)) # ANCHURA thickness: Mapped[Optional[str]] = mapped_column(String(50)) # ESPESOR specification: Mapped[Optional[str]] = mapped_column(String(50)) # SPEC # --- 3. COSTOS DETALLADOS Y ADUANA US --- total_value: Mapped[Optional[Decimal]] = mapped_column(Numeric(23, 8)) # VALORTOTAL direct_labor: Mapped[Optional[Decimal]] = mapped_column(Numeric(23, 8)) # TRABAJODIREC general_expenses: Mapped[Optional[Decimal]] = mapped_column(Numeric(23, 8)) # GASTOGRALES total_expenses: Mapped[Optional[Decimal]] = mapped_column(Numeric(23, 8)) # TOTALGASTOS depreciation: Mapped[Optional[Decimal]] = mapped_column(Numeric(23, 8)) # DEPRECIACION tooling: Mapped[Optional[Decimal]] = mapped_column(Numeric(23, 8)) # TOOLING material_consumed: Mapped[Optional[Decimal]] = mapped_column(Numeric(23, 8)) # MATCONSUMED profit: Mapped[Optional[Decimal]] = mapped_column(Numeric(23, 8)) # GANANCIA # Fracciones Internacionales us_fraction_alt: Mapped[Optional[str]] = mapped_column(String(13)) # FRACEUA ca_fraction: Mapped[Optional[str]] = mapped_column(String(13)) # FRACCANADA ad_valorem_us: Mapped[Optional[Decimal]] = mapped_column(Numeric(5, 2)) # ADVALOREMAME # Nafta / USMCA nafta_result: Mapped[Optional[str]] = mapped_column(String(19)) # RESULTADOCALCULONAFTA nafta_percentage: Mapped[Optional[Decimal]] = mapped_column(Numeric(5, 2)) # PORCENTAJECALCULONAFTA # Impuestos Específicos (Derechos de Trámite Admon) dta: Mapped[Optional[str]] = mapped_column(String(19)) # DTA dtb: Mapped[Optional[str]] = mapped_column(String(19)) # DTB dtg: Mapped[Optional[str]] = mapped_column(String(19)) # DTG # --- RELACIÓN --- # Usamos string "Part" para evitar problemas de carga master_info: Mapped["Part"] = relationship("Part", back_populates="inv_data") def __repr__(self) -> str: return f""