""" Modelos ORM para gestión de partes/componentes - Anexo 76 (Master Data) """ from datetime import datetime from decimal import Decimal from typing import TYPE_CHECKING, Optional, List from api.v1.common.base_models import TenantScopedMixin, TimestampMixin from core.database import Base from sqlalchemy import ( ForeignKeyConstraint, Integer, Numeric, PrimaryKeyConstraint, String, UniqueConstraint, Boolean, DateTime, ) # Importante usar relationship y Mapped from sqlalchemy.orm import Mapped, mapped_column, relationship from api.v1.modules.public.reference_data.currency_types.models import CurrencyType from api.v1.modules.a24.fa.fa_parts.models import FaPart from api.v1.modules.a24.inv.inv_parts.models import InvPart from api.v1.modules.a24.inv.bom.models import BillOfMaterial from api.v1.modules.a24.inv.part_countries.models import PartCountry if TYPE_CHECKING: from api.v1.modules.a76.classes.models import Class from api.v1.modules.a76.general_catalogs.units_of_measure.models import ( UnitOfMeasure, ) class Part(Base, TenantScopedMixin, TimestampMixin): __tablename__ = "parts" __table_args__ = ( PrimaryKeyConstraint("id", name="parts_pkey"), ForeignKeyConstraint( ["currency_key"], ["public.currency_types.code"], name="fk_parts_currency" ), ForeignKeyConstraint( ["unit_of_measure", "tenant_id", "company_id"], [ "a76.units_of_measure.code", "a76.units_of_measure.tenant_id", "a76.units_of_measure.company_id", ], ), # Puente hacia la tabla de clases ForeignKeyConstraint( ["part_class", "tenant_id", "company_id"], [ "a76.classes.class_code", "a76.classes.tenant_id", "a76.classes.company_id", ], name="fk_parts_class", ), UniqueConstraint( "tenant_id", "company_id", "part_number", name="client_part_ukey" ), {"schema": "a76"}, ) id: Mapped[int] = mapped_column(Integer, primary_key=True) client_id: Mapped[Optional[int]] = mapped_column(Integer, nullable=True) part_number: Mapped[str] = mapped_column(String(70)) commercial_part_number: Mapped[Optional[str]] = mapped_column(String(70)) description_spanish: Mapped[Optional[str]] = mapped_column(String(500)) description_english: Mapped[Optional[str]] = mapped_column(String(500)) part_class: Mapped[Optional[str]] = mapped_column(String(8)) unit_of_measure: Mapped[Optional[str]] = mapped_column(String(5)) unit_cost: Mapped[Optional[Decimal]] = mapped_column(Numeric(23, 8)) currency_type: Mapped[Optional[str]] = mapped_column(String(2)) currency_key: Mapped[Optional[str]] = mapped_column(String(3)) unit_weight: Mapped[Optional[Decimal]] = mapped_column(Numeric(19, 8)) weight_type: Mapped[Optional[str]] = mapped_column(String(6)) fraction: Mapped[Optional[str]] = mapped_column(String(10)) us_fraction: Mapped[Optional[str]] = mapped_column(String(16)) fda_key: Mapped[Optional[str]] = mapped_column(String(20)) fcc_key: Mapped[Optional[str]] = mapped_column(String(30)) license_code: Mapped[Optional[str]] = mapped_column(String(3)) eccn: Mapped[Optional[str]] = mapped_column(String(20)) export_code: Mapped[Optional[str]] = mapped_column(String(2)) exclusion_symbol: Mapped[Optional[str]] = mapped_column(String(19)) is_active: Mapped[Optional[bool]] = mapped_column( Boolean, default=True, server_default="true" ) part_photo: Mapped[Optional[str]] = mapped_column(String(255)) creation_date: Mapped[Optional[int]] = mapped_column() modification_date: Mapped[Optional[int]] = mapped_column() modification_date_iso: Mapped[Optional[datetime]] = mapped_column(DateTime) # --- RELACIONES --- currency: Mapped[Optional["CurrencyType"]] = relationship("CurrencyType") unit_of_measure_info: Mapped[Optional["UnitOfMeasure"]] = relationship( "UnitOfMeasure" ) part_class_info: Mapped[Optional["Class"]] = relationship( "Class", back_populates="parts", overlaps="unit_of_measure_info" ) # Extensiones Anexo 24 fa_data: Mapped[Optional["FaPart"]] = relationship( "FaPart", back_populates="master_info", uselist=False, cascade="all, delete-orphan", ) inv_data: Mapped[Optional["InvPart"]] = relationship( "InvPart", back_populates="master_info", uselist=False, cascade="all, delete-orphan", ) # Bom Components (as parent) bom_items: Mapped[List["BillOfMaterial"]] = relationship( "BillOfMaterial", foreign_keys=[BillOfMaterial.parent_part_id], cascade="all, delete-orphan", back_populates="parent_part" ) # Países Anexo 24 inv_countries: Mapped[List["PartCountry"]] = relationship( "PartCountry", cascade="all, delete-orphan", back_populates="part" ) def __repr__(self) -> str: return f""