""" Modelos ORM para gestión de partes/componentes """ from datetime import datetime from decimal import Decimal from typing import TYPE_CHECKING, Optional from api.v1.common.base_models import TenantScopedMixin from core.database import Base from sqlalchemy import ( ForeignKeyConstraint, Integer, Numeric, PrimaryKeyConstraint, SmallInteger, String, UniqueConstraint, Boolean, ) from sqlalchemy.orm import Mapped, mapped_column, relationship if TYPE_CHECKING: from api.v1.modules.a76.classes.models import Class from api.v1.modules.public.reference_data.countries.models import Country from api.v1.modules.public.reference_data.currency_types.models import CurrencyType class Part(Base, TenantScopedMixin): """ Modelo para la tabla GPartes - Información de partes en los sistemas SCAII (N), SCAF (S) Y WINSAAI (W) """ __tablename__ = "parts" __table_args__ = ( PrimaryKeyConstraint("id", name="parts_pkey"), ForeignKeyConstraint(["tenant_id"], ["a76.tenants.id"], name="fk_parts_tenant"), ForeignKeyConstraint( ["company_id"], ["a76.company.id"], name="fk_parts_company" ), ForeignKeyConstraint( ["country_of_origin"], ["public.countries.m3_key"], name="fk_parts_country" ), ForeignKeyConstraint( ["currency_key"], ["public.currency_types.code"], name="fk_parts_currency" ), UniqueConstraint( "tenant_id", "company_id", "part_number", name="client_part_ukey" ), {"schema": "a76"}, ) id: Mapped[int] = mapped_column(Integer, primary_key=True) # Unique constraint compuesta client_id: Mapped[int] = mapped_column(Integer) part_number: Mapped[str] = mapped_column(String(49)) # Basic information fraction: Mapped[Optional[str]] = mapped_column(String(10)) 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)) commercial_part_number: Mapped[Optional[str]] = mapped_column(String(70)) country_of_origin: Mapped[Optional[str]] = mapped_column(String(3)) # Pricing and currency 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)) # Weight information unit_weight: Mapped[Optional[Decimal]] = mapped_column(Numeric(19, 8)) weight_type: Mapped[Optional[str]] = mapped_column(String(6)) # Classification and regulatory us_fraction: Mapped[Optional[str]] = mapped_column(String(16)) # FRACCIONAME 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 Control Classification Number export_code: Mapped[Optional[str]] = mapped_column(String(2)) exclusion_symbol: Mapped[Optional[str]] = mapped_column(String(19)) # SIMBOLOEXCLIC # Additional information supplier: Mapped[Optional[str]] = mapped_column(String(14)) alternate_unit_measure: Mapped[Optional[str]] = mapped_column(String(14)) added_value: Mapped[Optional[Decimal]] = mapped_column(Numeric(23, 8)) # Status and dates is_active: Mapped[Optional[bool]] = mapped_column(Boolean) creation_date: Mapped[Optional[int]] = mapped_column() # FECHACREACIONPARTE modification_date: Mapped[Optional[int]] = mapped_column() # FECHAMODIFICA modification_date_iso: Mapped[Optional[datetime]] = ( mapped_column() ) # FECHAMODIFICA_ISO # Media part_photo: Mapped[Optional[str]] = mapped_column(String(255)) # Relationships country: Mapped[Optional["Country"]] = relationship( foreign_keys=[country_of_origin] ) currency: Mapped[Optional["CurrencyType"]] = relationship( foreign_keys=[currency_key] ) # Relationship with Class through composite foreign key # Note: This requires both client_id and part_class to match client_id and class_code in Class part_class_info: Mapped[Optional["Class"]] = relationship( primaryjoin="and_(Part.client_id == Class.client_id, Part.part_class == Class.class_code)", foreign_keys="[Part.client_id, Part.part_class]", viewonly=True, back_populates="parts", ) def __repr__(self) -> str: return f""