feat: Add new fields for invoice logistics and line items, enhance UI for class selection
This commit is contained in:
@@ -674,6 +674,32 @@ class InvoiceLogistics(Base, TenantScopedMixin, TimestampMixin):
|
||||
Boolean, default=False
|
||||
) # SETRATAPROCESOCTM / Se trata de proceso CTM
|
||||
|
||||
# Continuation Tab Fields
|
||||
equipment_reviewed: Mapped[Optional[bool]] = mapped_column(
|
||||
Boolean, default=False
|
||||
) # Fue revisado el equipo
|
||||
is_subdivision: Mapped[Optional[bool]] = mapped_column(
|
||||
Boolean, default=False
|
||||
) # Sub división
|
||||
acts_as_cd: Mapped[Optional[bool]] = mapped_column(
|
||||
Boolean, default=False
|
||||
) # Funge como CD
|
||||
pedimento_arrived: Mapped[Optional[bool]] = mapped_column(
|
||||
Boolean, default=False
|
||||
) # Llegó el pedimento
|
||||
green_light_mx: Mapped[Optional[bool]] = mapped_column(
|
||||
Boolean, default=False
|
||||
) # Semáforo verde México
|
||||
green_light_us: Mapped[Optional[bool]] = mapped_column(
|
||||
Boolean, default=False
|
||||
) # Semáforo verde USA
|
||||
red_light_mx: Mapped[Optional[bool]] = mapped_column(
|
||||
Boolean, default=False
|
||||
) # Semáforo rojo México
|
||||
red_light_us: Mapped[Optional[bool]] = mapped_column(
|
||||
Boolean, default=False
|
||||
) # Semáforo rojo USA
|
||||
|
||||
# Relationship
|
||||
header: Mapped["InvoiceHeader"] = relationship(back_populates="logistics")
|
||||
|
||||
|
||||
@@ -345,6 +345,15 @@ class InvoiceLogisticsBase(BaseModel):
|
||||
None, max_length=20, description="Payment receipt number"
|
||||
)
|
||||
is_ctm_process: Optional[bool] = Field(False, description="Is CTM process")
|
||||
# Continuation Tab Fields
|
||||
equipment_reviewed: Optional[bool] = Field(False, description="Equipment reviewed")
|
||||
is_subdivision: Optional[bool] = Field(False, description="Is subdivision")
|
||||
acts_as_cd: Optional[bool] = Field(False, description="Acts as CD")
|
||||
pedimento_arrived: Optional[bool] = Field(False, description="Pedimento arrived")
|
||||
green_light_mx: Optional[bool] = Field(False, description="Green light Mexico")
|
||||
green_light_us: Optional[bool] = Field(False, description="Green light USA")
|
||||
red_light_mx: Optional[bool] = Field(False, description="Red light Mexico")
|
||||
red_light_us: Optional[bool] = Field(False, description="Red light USA")
|
||||
|
||||
|
||||
class InvoiceSalesDetailsBase(BaseModel):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
from sqlalchemy import Boolean, String, Text, ForeignKey
|
||||
from sqlalchemy import Boolean, String, Text, Integer, ForeignKey
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
from core.database import Base
|
||||
|
||||
@@ -39,5 +39,13 @@ class LineDescription(Base):
|
||||
lot: Mapped[Optional[str]] = mapped_column(String(254)) # LOTE
|
||||
entry_number: Mapped[Optional[str]] = mapped_column(String(50)) # NUMENTRADA/NUMERODEENTRADA
|
||||
|
||||
# Eighth rule and A31 fields
|
||||
eighth_rule_fraction: Mapped[Optional[str]] = mapped_column(String(20)) # Eighth Rule Fraction
|
||||
eighth_rule_line: Mapped[Optional[int]] = mapped_column(Integer) # Eighth Rule Line
|
||||
consider_a31: Mapped[Optional[bool]] = mapped_column(Boolean, default=False) # Consider in A31
|
||||
|
||||
# Machinery location
|
||||
machinery_location: Mapped[Optional[str]] = mapped_column(String(200)) # Machinery and equipment location
|
||||
|
||||
# Relationship (one-to-one)
|
||||
line: Mapped["LineItem"] = relationship(back_populates="description")
|
||||
@@ -26,6 +26,14 @@ class LineDescriptionBase(BaseModel):
|
||||
# Lot and entry tracking
|
||||
lot: Optional[str] = Field(None, max_length=254, description="Lot (LOTE)")
|
||||
entry_number: Optional[str] = Field(None, max_length=50, description="Entry number (NUMENTRADA/NUMERODEENTRADA)")
|
||||
|
||||
# Eighth rule and A31 fields
|
||||
eighth_rule_fraction: Optional[str] = Field(None, max_length=20, description="Eighth Rule Fraction")
|
||||
eighth_rule_line: Optional[int] = Field(None, description="Eighth Rule Line")
|
||||
consider_a31: Optional[bool] = Field(False, description="Consider in A31")
|
||||
|
||||
# Machinery location
|
||||
machinery_location: Optional[str] = Field(None, max_length=200, description="Machinery and equipment location")
|
||||
|
||||
|
||||
class LineDescriptionCreate(LineDescriptionBase):
|
||||
|
||||
@@ -41,15 +41,15 @@ class LineItem(Base, TenantScopedMixin, TimestampMixin):
|
||||
component_part_number_id: Mapped[Optional[str]] = mapped_column(
|
||||
ForeignKey("a76.parts.id")
|
||||
) # NUMPARTECOM
|
||||
class_id: Mapped[Optional[str]] = mapped_column(
|
||||
class_id: Mapped[Optional[int]] = mapped_column(
|
||||
ForeignKey("a76.classes.id")
|
||||
) # CLASE
|
||||
|
||||
# Unit of measure
|
||||
unit_of_measure: Mapped[Optional[str]] = mapped_column(
|
||||
unit_of_measure: Mapped[Optional[int]] = mapped_column(
|
||||
ForeignKey("a76.units_of_measure.id")
|
||||
) # UNIDADMEDIDA/UNIMED
|
||||
alternate_unit: Mapped[Optional[str]] = mapped_column(
|
||||
alternate_unit: Mapped[Optional[int]] = mapped_column(
|
||||
ForeignKey("a76.units_of_measure.id")
|
||||
) # UNIMEDALTERNA
|
||||
uma_key: Mapped[Optional[str]] = mapped_column(String(2)) # CLAVEUMA
|
||||
@@ -173,11 +173,15 @@ class LineItem(Base, TenantScopedMixin, TimestampMixin):
|
||||
back_populates="line", cascade="all, delete-orphan", uselist=False
|
||||
)
|
||||
class_info: Mapped[Optional["Class"]] = relationship(
|
||||
foreign_keys=[class_id], viewonly=True
|
||||
"api.v1.modules.a76.classes.models.Class",
|
||||
foreign_keys=[class_id],
|
||||
viewonly=True
|
||||
)
|
||||
unit_of_measure_info: Mapped[Optional["UnitOfMeasure"]] = relationship(
|
||||
foreign_keys=[unit_of_measure], viewonly=True
|
||||
"api.v1.modules.a76.general_catalogs.units_of_measure.models.UnitOfMeasure",
|
||||
foreign_keys=[unit_of_measure],
|
||||
viewonly=True
|
||||
)
|
||||
fa_data: Mapped[Optional["FaLineItem"]] = relationship(
|
||||
"FaLineItem", back_populates="master_info", uselist=False
|
||||
"FaLineItem", back_populates="master_info", uselist=False, cascade="all, delete"
|
||||
)
|
||||
|
||||
@@ -53,24 +53,12 @@ class LineItemBase(BaseModel):
|
||||
)
|
||||
class_id: Optional[int] = Field(None, description="Class code")
|
||||
|
||||
@field_validator(
|
||||
"unit_of_measure",
|
||||
"alternate_unit",
|
||||
mode="before",
|
||||
)
|
||||
@classmethod
|
||||
def convert_to_string(cls, v):
|
||||
"""Convert integers to strings for FK fields"""
|
||||
if v is not None and not isinstance(v, str):
|
||||
return str(v)
|
||||
return v
|
||||
|
||||
# Unit of measure
|
||||
unit_of_measure: Optional[str] = Field(
|
||||
None, max_length=10, description="Unit of measure"
|
||||
unit_of_measure: Optional[int] = Field(
|
||||
None, description="Unit of measure"
|
||||
)
|
||||
alternate_unit: Optional[str] = Field(
|
||||
None, max_length=10, description="Alternate unit"
|
||||
alternate_unit: Optional[int] = Field(
|
||||
None, description="Alternate unit"
|
||||
)
|
||||
uma_key: Optional[str] = Field(None, max_length=2, description="UMA key")
|
||||
auxiliary_unit: Optional[str] = Field(
|
||||
|
||||
Reference in New Issue
Block a user