from decimal import Decimal from typing import Optional, TYPE_CHECKING from sqlalchemy import Boolean, String, Integer, Numeric, SmallInteger, ForeignKey from sqlalchemy.orm import Mapped, mapped_column, relationship from api.v1.common.base_models import TenantScopedMixin, TimestampMixin from core.database import Base from api.v1.modules.a76.classes.models import Class from api.v1.modules.a76.general_catalogs.units_of_measure.models import UnitOfMeasure if TYPE_CHECKING: from ..models import Item from ..line_financials.models import LineFinancial from ..line_quantities.models import LineQuantity from ..line_customs.models import LineCustom from ..line_descriptions.models import LineDescription from ..line_references.models import LineReference from api.v1.modules.a24.fa.fa_item_lines.models import FaLineItem class LineItem(Base, TenantScopedMixin, TimestampMixin): """ Unified line items for all items Consolidates all line-level data from Q and S tables """ __tablename__ = "item_lines" __table_args__ = { "schema": "a76", } id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True) item_id: Mapped[int] = mapped_column(ForeignKey("a76.items.id")) line_number: Mapped[int] = mapped_column(Integer) # LINEAIMPO/LINEAEXPO/LINEA # Part identification part_number: Mapped[Optional[str]] = mapped_column( ForeignKey("a76.parts.id") ) # NUMPARTE component_part_number: Mapped[Optional[str]] = mapped_column( ForeignKey("a76.parts.id") ) # NUMPARTECOM class_code: Mapped[Optional[str]] = mapped_column( ForeignKey("a76.classes.class_code") ) # CLASE # Unit of measure unit_of_measure: Mapped[Optional[str]] = mapped_column( ForeignKey("a76.units_of_measure.id") ) # UNIDADMEDIDA/UNIMED alternate_unit: Mapped[Optional[str]] = mapped_column( ForeignKey("a76.units_of_measure.id") ) # UNIMEDALTERNA uma_key: Mapped[Optional[str]] = mapped_column(String(2)) # CLAVEUMA auxiliary_unit: Mapped[Optional[str]] = mapped_column(String(5)) # UNIMEDAUXILIAR # Permits and certificates permit_number: Mapped[Optional[str]] = mapped_column(String(20)) # NUMPERMISO page_line: Mapped[Optional[str]] = mapped_column(String(10)) # PAGRENGLON has_certificate: Mapped[Optional[bool]] = mapped_column( Boolean ) # TIENECO/CERTORIGEN certificate_number: Mapped[Optional[str]] = mapped_column( String(10) ) # NOCERTIFICADO octave_permit: Mapped[Optional[str]] = mapped_column(String(20)) # PERMISOROCTAVA permits_ped: Mapped[Optional[str]] = mapped_column(String(500)) # PERMISOSPED # FDA has_fda_code: Mapped[Optional[bool]] = mapped_column(Boolean) # LLEVACODFDA fda_key: Mapped[Optional[str]] = mapped_column(String(10)) # CLAVEFDA # Special flags is_military_mcia: Mapped[Optional[bool]] = mapped_column(Boolean) # ESMCIAMILITAR # IV32 (Tax identification) iv32_type_key: Mapped[Optional[str]] = mapped_column(String(5)) # CLAVETIPOIV32 iv32_number: Mapped[Optional[str]] = mapped_column(String(35)) # NUMEROIV32 # IN CASE OF EXPO scrap_invoice: Mapped[Optional[str]] = mapped_column(String(15)) # FACTURASCRAP consecutive_destination: Mapped[Optional[int]] = mapped_column( Integer ) # CONSECUTIVODES ctm_section: Mapped[Optional[str]] = mapped_column(String(3)) # APARTADOCTM # Tax payment tax_payment: Mapped[Optional[bool]] = mapped_column(Boolean) # PAGOIMPUESTO payment_method: Mapped[Optional[str]] = mapped_column( String(9) ) # FORMAPAGO/FORMAPAGOTIGI igi_amount: Mapped[Optional[Decimal]] = mapped_column(Numeric(23, 8)) # MONTOIGI igi_payment_method: Mapped[Optional[str]] = mapped_column( String(9) ) # FORMAPAGOTIGI # FCC fcc_key: Mapped[Optional[str]] = mapped_column(String(30)) # CLAVEFCC # Valuation method valuation_method: Mapped[Optional[str]] = mapped_column(String(2)) # METVALOR valuation_determined_value: Mapped[Optional[Decimal]] = mapped_column( Numeric(29, 8) ) # METVALORVALORDETERMINADO/METVALORACIONVALORDETERMINADO valuation_reason: Mapped[Optional[str]] = mapped_column( String(500) ) # METVALORMOTIVODEUSO/METVALORACIONMOTIVODEUSO # Container rules container_rule: Mapped[Optional[str]] = mapped_column(String(50)) # CONTENEDORREGLA container_parts_ii: Mapped[Optional[str]] = mapped_column( String(50) ) # CONTENEDORPARTESII # APHIS consecutive_aphis: Mapped[Optional[int]] = mapped_column( Integer ) # CONSECUTIVOAPHIS # BOM/Commercial bom_version: Mapped[Optional[int]] = mapped_column(Integer) # VERSIONBOM bill_version: Mapped[Optional[int]] = mapped_column(Integer) # VERSIONBILL # TLCAN value tlcan_value: Mapped[Optional[Decimal]] = mapped_column(Numeric(23, 8)) # VALORTLCAN # Identifier identifier: Mapped[Optional[str]] = mapped_column(String(2)) # IDENTIFICADOR # Validation fields validation_zero: Mapped[Optional[int]] = mapped_column(Integer) # VALIDACIONZERO validation_one: Mapped[Optional[int]] = mapped_column(Integer) # VALIDACIONUNO # Material type material_type: Mapped[Optional[str]] = mapped_column( String(50) ) # TIPOMAT/TIPODENUMPARTE # Order concept order_type: Mapped[Optional[str]] = mapped_column(String(50)) # TIPODEORDEN line_concept: Mapped[Optional[str]] = mapped_column( String(50) ) # CONCEPTODELAPARTIDA # Review dispatch review_dispatch: Mapped[Optional[str]] = mapped_column(String(10)) # REVISARDESP # Take component from PT take_component_pt: Mapped[Optional[int]] = mapped_column(Integer) # TOMARCOMOPT # Pallet pallet2: Mapped[Optional[int]] = mapped_column(SmallInteger) # PALLET2 # Wildcard field wildcard_field: Mapped[Optional[str]] = mapped_column(String(100)) # CAMPOCOMODIN # Relationships item: Mapped["Item"] = relationship(back_populates="lines") financial: Mapped[Optional["LineFinancial"]] = relationship( back_populates="line", cascade="all, delete-orphan", uselist=False ) quantity: Mapped[Optional["LineQuantity"]] = relationship( back_populates="line", cascade="all, delete-orphan", uselist=False ) customs: Mapped[Optional["LineCustom"]] = relationship( back_populates="line", cascade="all, delete-orphan", uselist=False ) description: Mapped[Optional["LineDescription"]] = relationship( back_populates="line", cascade="all, delete-orphan", uselist=False ) reference: Mapped[Optional["LineReference"]] = relationship( back_populates="line", cascade="all, delete-orphan", uselist=False ) class_info: Mapped[Optional["Class"]] = relationship( foreign_keys=[class_code], viewonly=True ) unit_of_measure_info: Mapped[Optional["UnitOfMeasure"]] = relationship( foreign_keys=[unit_of_measure], viewonly=True ) fa_data: Mapped[Optional["FaLineItem"]] = relationship( "FaLineItem", back_populates="master_info", uselist=False )