""" Modelos ORM para gestión de partes/componentes """ from typing import TYPE_CHECKING, Optional from datetime import datetime from decimal import Decimal from sqlalchemy import Integer, String, Numeric, SmallInteger, ForeignKey, PrimaryKeyConstraint, ForeignKeyConstraint, UniqueConstraint from sqlalchemy.sql import func from sqlalchemy.orm import Mapped, mapped_column, relationship from core.database import Base if TYPE_CHECKING: from api.v1.modules.public.reference_data.countries.models import Country from api.v1.modules.public.reference_data.currency_types.models import CurrencyType from api.v1.modules.a76.classes.models import Class class Part(Base): """ 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) tenant_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True) company_id: Mapped[int] = mapped_column(Integer, nullable=False, index=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 enabled_disabled: Mapped[Optional[int]] = mapped_column(SmallInteger) 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""