feat: update invoice and item tabs to use 'Datos Soriana' instead of 'Datos Sonana'
refactor: enhance package transportation tab to prevent infinite loops and load data only once fix: include credentials in fetch request for company data feat: implement loading of additional pedimento data in edit page, including contributions, packages, transport carriers, guides, seals, and containers add: create DTOs and models for pedimento contributions, packages, transport carriers, guides, seals, and containers
This commit is contained in:
@@ -23,6 +23,7 @@ class PedimentoConfigAdditionalBase(BaseModel):
|
||||
None, description="Send 502 validation file for consolidated"
|
||||
)
|
||||
add_remove_norms: Optional[bool] = Field(None, description="Add/remove norms")
|
||||
choose_invoice_cove: Optional[bool] = Field(None, description="Choose invoice COVE in items")
|
||||
|
||||
|
||||
class PedimentoConfigAdditionalCreate(PedimentoConfigAdditionalBase):
|
||||
@@ -40,6 +41,7 @@ class PedimentoConfigAdditionalUpdate(BaseModel):
|
||||
enable_import_invoice_recipient: Optional[bool] = None
|
||||
send_502_validation_file_for_consolidated: Optional[bool] = None
|
||||
add_remove_norms: Optional[bool] = None
|
||||
choose_invoice_cove: Optional[bool] = None
|
||||
|
||||
|
||||
class PedimentoConfigAdditionalResponse(PedimentoConfigAdditionalBase):
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
from decimal import Decimal
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
|
||||
class PedimentoContributionBase(BaseModel):
|
||||
"""Base schema for Pedimento Contribution"""
|
||||
|
||||
pedimento_id: Optional[int] = None
|
||||
contribucion: Optional[str] = None
|
||||
tipo_tasa: Optional[str] = None
|
||||
tasa: Optional[Decimal] = None
|
||||
forma_pago: Optional[str] = None
|
||||
importe: Optional[Decimal] = None
|
||||
gravamen: Optional[str] = None
|
||||
abreviacion: Optional[str] = None
|
||||
forma_pago_2: Optional[str] = None
|
||||
importe_2: Optional[Decimal] = None
|
||||
|
||||
|
||||
class PedimentoContributionCreate(PedimentoContributionBase):
|
||||
"""Schema for creating Pedimento Contribution"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class PedimentoContributionUpdate(BaseModel):
|
||||
"""Schema for updating Pedimento Contribution"""
|
||||
|
||||
contribucion: Optional[str] = None
|
||||
tipo_tasa: Optional[str] = None
|
||||
tasa: Optional[Decimal] = None
|
||||
forma_pago: Optional[str] = None
|
||||
importe: Optional[Decimal] = None
|
||||
gravamen: Optional[str] = None
|
||||
abreviacion: Optional[str] = None
|
||||
forma_pago_2: Optional[str] = None
|
||||
importe_2: Optional[Decimal] = None
|
||||
|
||||
|
||||
class PedimentoContributionResponse(PedimentoContributionBase):
|
||||
"""Schema for Pedimento Contribution response"""
|
||||
|
||||
id: int
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
@@ -9,7 +9,7 @@ class PedimentoDatesBase(BaseModel):
|
||||
|
||||
entry_date: Optional[datetime] = Field(None, description="Entry date")
|
||||
pedimento_date: Optional[datetime] = Field(None, description="Pedimento date")
|
||||
payment_date: datetime = Field(..., description="Payment date")
|
||||
payment_date: Optional[datetime] = Field(None, description="Payment date")
|
||||
rectification_payment_date: Optional[datetime] = Field(
|
||||
None, description="Rectification payment date"
|
||||
)
|
||||
@@ -26,7 +26,7 @@ class PedimentoDatesCreate(BaseModel):
|
||||
|
||||
entry_date: Optional[datetime] = Field(None, description="Entry date")
|
||||
pedimento_date: Optional[datetime] = Field(None, description="Pedimento date")
|
||||
payment_date: datetime = Field(..., description="Payment date")
|
||||
payment_date: Optional[datetime] = Field(None, description="Payment date")
|
||||
rectification_payment_date: Optional[datetime] = Field(None, description="Rectification payment date")
|
||||
extraction_date: Optional[datetime] = Field(None, description="Extraction date")
|
||||
submission_date: Optional[datetime] = Field(None, description="Submission date")
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
|
||||
class PedimentoPackagesBase(BaseModel):
|
||||
"""Base schema for Pedimento Packages"""
|
||||
|
||||
pedimento_id: Optional[int] = None
|
||||
quantity: Optional[int] = None
|
||||
brand: Optional[str] = None
|
||||
number: Optional[str] = None
|
||||
vehicles: Optional[int] = None
|
||||
|
||||
|
||||
class PedimentoPackagesCreate(PedimentoPackagesBase):
|
||||
"""Schema for creating Pedimento Packages"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class PedimentoPackagesUpdate(BaseModel):
|
||||
"""Schema for updating Pedimento Packages"""
|
||||
|
||||
quantity: Optional[int] = None
|
||||
brand: Optional[str] = None
|
||||
number: Optional[str] = None
|
||||
vehicles: Optional[int] = None
|
||||
|
||||
|
||||
class PedimentoPackagesResponse(PedimentoPackagesBase):
|
||||
"""Schema for Pedimento Packages response"""
|
||||
|
||||
id: int
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class PedimentoTransportCarrierBase(BaseModel):
|
||||
"""Base schema for Pedimento Transport Carrier"""
|
||||
|
||||
pedimento_id: Optional[int] = None
|
||||
carrier: Optional[str] = None
|
||||
rfc: Optional[str] = None
|
||||
curp: Optional[str] = None
|
||||
name: Optional[str] = None
|
||||
address: Optional[str] = None
|
||||
city: Optional[str] = None
|
||||
state: Optional[str] = None
|
||||
country: Optional[str] = None
|
||||
tax_id: Optional[str] = None
|
||||
total_packages: Optional[int] = None
|
||||
identification: Optional[str] = None
|
||||
|
||||
|
||||
class PedimentoTransportCarrierCreate(PedimentoTransportCarrierBase):
|
||||
"""Schema for creating Pedimento Transport Carrier"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class PedimentoTransportCarrierUpdate(BaseModel):
|
||||
"""Schema for updating Pedimento Transport Carrier"""
|
||||
|
||||
carrier: Optional[str] = None
|
||||
rfc: Optional[str] = None
|
||||
curp: Optional[str] = None
|
||||
name: Optional[str] = None
|
||||
address: Optional[str] = None
|
||||
city: Optional[str] = None
|
||||
state: Optional[str] = None
|
||||
country: Optional[str] = None
|
||||
tax_id: Optional[str] = None
|
||||
total_packages: Optional[int] = None
|
||||
identification: Optional[str] = None
|
||||
|
||||
|
||||
class PedimentoTransportCarrierResponse(PedimentoTransportCarrierBase):
|
||||
"""Schema for Pedimento Transport Carrier response"""
|
||||
|
||||
id: int
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class PedimentoSealBase(BaseModel):
|
||||
"""Base schema for Pedimento Seal"""
|
||||
|
||||
pedimento_id: Optional[int] = None
|
||||
number: Optional[str] = None
|
||||
identification: Optional[str] = None
|
||||
|
||||
|
||||
class PedimentoSealCreate(PedimentoSealBase):
|
||||
"""Schema for creating Pedimento Seal"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class PedimentoSealUpdate(BaseModel):
|
||||
"""Schema for updating Pedimento Seal"""
|
||||
|
||||
number: Optional[str] = None
|
||||
identification: Optional[str] = None
|
||||
|
||||
|
||||
class PedimentoSealResponse(PedimentoSealBase):
|
||||
"""Schema for Pedimento Seal response"""
|
||||
|
||||
id: int
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class PedimentoContainerBase(BaseModel):
|
||||
"""Base schema for Pedimento Container"""
|
||||
|
||||
pedimento_id: Optional[int] = None
|
||||
number: Optional[str] = None
|
||||
identification: Optional[str] = None
|
||||
type: Optional[str] = None
|
||||
|
||||
|
||||
class PedimentoContainerCreate(PedimentoContainerBase):
|
||||
"""Schema for creating Pedimento Container"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class PedimentoContainerUpdate(BaseModel):
|
||||
"""Schema for updating Pedimento Container"""
|
||||
|
||||
number: Optional[str] = None
|
||||
identification: Optional[str] = None
|
||||
type: Optional[str] = None
|
||||
|
||||
|
||||
class PedimentoContainerResponse(PedimentoContainerBase):
|
||||
"""Schema for Pedimento Container response"""
|
||||
|
||||
id: int
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class PedimentoGuideBase(BaseModel):
|
||||
"""Base schema for Pedimento Guide"""
|
||||
|
||||
pedimento_id: Optional[int] = None
|
||||
guide: Optional[str] = None
|
||||
identifier: Optional[str] = None
|
||||
|
||||
|
||||
class PedimentoGuideCreate(PedimentoGuideBase):
|
||||
"""Schema for creating Pedimento Guide"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class PedimentoGuideUpdate(BaseModel):
|
||||
"""Schema for updating Pedimento Guide"""
|
||||
|
||||
guide: Optional[str] = None
|
||||
identifier: Optional[str] = None
|
||||
|
||||
|
||||
class PedimentoGuideResponse(PedimentoGuideBase):
|
||||
"""Schema for Pedimento Guide response"""
|
||||
|
||||
id: int
|
||||
created_at: datetime
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
@@ -16,6 +16,22 @@ from .pedimento_dates import PedimentoDatesCreate, PedimentoDatesResponse
|
||||
from .pedimento_decrementables import PedimentoDecrementablesCreate, PedimentoDecrementablesResponse
|
||||
from .pedimento_incrementables import PedimentoIncrementablesCreate, PedimentoIncrementablesResponse
|
||||
from .pedimento_indexes import PedimentoIndexesCreate, PedimentoIndexesResponse
|
||||
from .pedimento_packages_transport import (
|
||||
PedimentoContainerCreate,
|
||||
PedimentoContainerResponse,
|
||||
PedimentoPackagesCreate,
|
||||
PedimentoPackagesResponse,
|
||||
PedimentoSealCreate,
|
||||
PedimentoSealResponse,
|
||||
PedimentoTransportCarrierCreate,
|
||||
PedimentoTransportCarrierResponse,
|
||||
PedimentoGuideCreate,
|
||||
PedimentoGuideResponse,
|
||||
)
|
||||
from .pedimento_contributions import (
|
||||
PedimentoContributionCreate,
|
||||
PedimentoContributionResponse,
|
||||
)
|
||||
from .pedimento_payments import PedimentoPaymentsCreate, PedimentoPaymentsResponse
|
||||
from .pedimento_rectification_destination import PedimentoRectificationDestinationCreate, PedimentoRectificationDestinationResponse
|
||||
from .pedimento_rectification_origin import PedimentoRectificationOriginCreate, PedimentoRectificationOriginResponse
|
||||
@@ -121,6 +137,12 @@ class PedimentosUpdate(BaseModel):
|
||||
pedimento_config_surcharges: Optional[PedimentoConfigSurchargesCreate] = None
|
||||
pedimento_config_update_rectification: Optional[PedimentoConfigUpdateRectificationCreate] = None
|
||||
pedimento_config_updates: Optional[PedimentoConfigUpdatesCreate] = None
|
||||
pedimento_packages: Optional[PedimentoPackagesCreate] = None
|
||||
pedimento_transport_carriers: Optional[list[PedimentoTransportCarrierCreate]] = None
|
||||
pedimento_guides: Optional[list[PedimentoGuideCreate]] = None
|
||||
pedimento_contributions: Optional[list[PedimentoContributionCreate]] = None
|
||||
pedimento_seals: Optional[list[PedimentoSealCreate]] = None
|
||||
pedimento_containers: Optional[list[PedimentoContainerCreate]] = None
|
||||
|
||||
|
||||
class PedimentosResponse(PedimentosBase):
|
||||
@@ -146,5 +168,11 @@ class PedimentosResponse(PedimentosBase):
|
||||
pedimento_config_surcharges: Optional[PedimentoConfigSurchargesResponse] = None
|
||||
pedimento_config_update_rectification: Optional[PedimentoConfigUpdateRectificationResponse] = None
|
||||
pedimento_config_updates: Optional[PedimentoConfigUpdatesResponse] = None
|
||||
pedimento_packages: Optional[PedimentoPackagesResponse] = None
|
||||
pedimento_transport_carriers: Optional[list[PedimentoTransportCarrierResponse]] = None
|
||||
pedimento_guides: Optional[list[PedimentoGuideResponse]] = None
|
||||
pedimento_contributions: Optional[list[PedimentoContributionResponse]] = None
|
||||
pedimento_seals: Optional[list[PedimentoSealResponse]] = None
|
||||
pedimento_containers: Optional[list[PedimentoContainerResponse]] = None
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
84
backend/api/v1/modules/a76/pedmientos/models/__init__.py
Normal file
84
backend/api/v1/modules/a76/pedmientos/models/__init__.py
Normal file
@@ -0,0 +1,84 @@
|
||||
"""Models for pedimentos module"""
|
||||
|
||||
# Import all models to ensure they are registered with SQLAlchemy
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_config_additional import (
|
||||
PedimentoConfigAdditional,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_config_calculations import (
|
||||
PedimentoConfigCalculations,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_config_parameters import (
|
||||
PedimentoConfigParameters,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_config_surcharges import (
|
||||
PedimentoConfigSurcharges,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_config_update_rectification import (
|
||||
PedimentoConfigUpdateRectification,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_config_updates import (
|
||||
PedimentoConfigUpdates,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_containers import (
|
||||
PedimentoContainers,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_contributions import (
|
||||
PedimentoContributions,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_customs_offices import (
|
||||
PedimentoCustomsOffices,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_dates import PedimentoDates
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_decrementables import (
|
||||
PedimentoDecrementables,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_incrementables import (
|
||||
PedimentoIncrementables,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_indexes import PedimentoIndexes
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_packages import PedimentoPackages
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_payments import PedimentoPayments
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_guides import PedimentoGuides
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_rectification_destination import (
|
||||
PedimentoRectificationDestination,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_rectification_origin import (
|
||||
PedimentoRectificationOrigin,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_seals import PedimentoSeals
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_transport_carriers import (
|
||||
PedimentoTransportCarriers,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_transport_means import (
|
||||
PedimentoTransportMeans,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_validation import (
|
||||
PedimentoValidation,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos
|
||||
|
||||
__all__ = [
|
||||
"Pedimentos",
|
||||
"PedimentoConfigAdditional",
|
||||
"PedimentoConfigCalculations",
|
||||
"PedimentoConfigParameters",
|
||||
"PedimentoConfigSurcharges",
|
||||
"PedimentoConfigUpdateRectification",
|
||||
"PedimentoConfigUpdates",
|
||||
"PedimentoContainers",
|
||||
"PedimentoContributions",
|
||||
"PedimentoCustomsOffices",
|
||||
"PedimentoDates",
|
||||
"PedimentoDecrementables",
|
||||
"PedimentoIncrementables",
|
||||
"PedimentoIndexes",
|
||||
"PedimentoPackages",
|
||||
"PedimentoGuides",
|
||||
"PedimentoPayments",
|
||||
"PedimentoRectificationDestination",
|
||||
"PedimentoRectificationOrigin",
|
||||
"PedimentoSeals",
|
||||
"PedimentoTransportCarriers",
|
||||
"PedimentoTransportMeans",
|
||||
"PedimentoValidation",
|
||||
]
|
||||
@@ -43,6 +43,7 @@ class PedimentoConfigAdditional(Base, TenantScopedMixin, TimestampMixin):
|
||||
enable_import_invoice_recipient: Mapped[bool] = mapped_column(Boolean, default=False)
|
||||
send_502_validation_file_for_consolidated: Mapped[bool] = mapped_column(Boolean, default=False)
|
||||
add_remove_norms: Mapped[bool] = mapped_column(Boolean, default=False)
|
||||
choose_invoice_cove: Mapped[bool] = mapped_column(Boolean, default=False)
|
||||
|
||||
pedimento: Mapped["Pedimentos"] = relationship(
|
||||
"Pedimentos", back_populates="pedimento_config_additional"
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from api.v1.common.base_models import TenantScopedMixin, TimestampMixin
|
||||
from core.database import Base
|
||||
from sqlalchemy import (
|
||||
ForeignKeyConstraint,
|
||||
Integer,
|
||||
PrimaryKeyConstraint,
|
||||
String,
|
||||
)
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos
|
||||
|
||||
|
||||
class PedimentoContainers(Base, TenantScopedMixin, TimestampMixin):
|
||||
__tablename__ = "pedimento_containers"
|
||||
__table_args__ = (
|
||||
PrimaryKeyConstraint("id", name="pedimento_containers_pkey"),
|
||||
ForeignKeyConstraint(
|
||||
["pedimento_id"],
|
||||
["a76.pedimentos.id"],
|
||||
ondelete="CASCADE",
|
||||
name="fk_pedimento_containers",
|
||||
),
|
||||
{"schema": "a76"},
|
||||
)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer)
|
||||
pedimento_id: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
|
||||
number: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
||||
identification: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
||||
type: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
||||
|
||||
pedimento: Mapped["Pedimentos"] = relationship(
|
||||
"Pedimentos", back_populates="pedimento_containers"
|
||||
)
|
||||
@@ -0,0 +1,46 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from api.v1.common.base_models import TenantScopedMixin, TimestampMixin
|
||||
from core.database import Base
|
||||
from sqlalchemy import (
|
||||
ForeignKeyConstraint,
|
||||
Integer,
|
||||
Numeric,
|
||||
PrimaryKeyConstraint,
|
||||
String,
|
||||
)
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos
|
||||
|
||||
|
||||
class PedimentoContributions(Base, TenantScopedMixin, TimestampMixin):
|
||||
__tablename__ = "pedimento_contributions"
|
||||
__table_args__ = (
|
||||
PrimaryKeyConstraint("id", name="pedimento_contributions_pkey"),
|
||||
ForeignKeyConstraint(
|
||||
["pedimento_id"],
|
||||
["a76.pedimentos.id"],
|
||||
ondelete="CASCADE",
|
||||
name="fk_pedimento_contributions",
|
||||
),
|
||||
{"schema": "a76"},
|
||||
)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer)
|
||||
pedimento_id: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
|
||||
contribucion: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
||||
tipo_tasa: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
||||
tasa: Mapped[Numeric | None] = mapped_column(Numeric(15, 8), nullable=True)
|
||||
forma_pago: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
||||
importe: Mapped[Numeric | None] = mapped_column(Numeric(17, 2), nullable=True)
|
||||
gravamen: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
||||
abreviacion: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
||||
forma_pago_2: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
||||
importe_2: Mapped[Numeric | None] = mapped_column(Numeric(17, 2), nullable=True)
|
||||
|
||||
pedimento: Mapped["Pedimentos"] = relationship(
|
||||
"Pedimentos", back_populates="pedimento_contributions"
|
||||
)
|
||||
@@ -44,7 +44,7 @@ class PedimentoDates(Base, TenantScopedMixin, TimestampMixin):
|
||||
|
||||
entry_date: Mapped[Optional[datetime]] = mapped_column(DateTime)
|
||||
pedimento_date: Mapped[Optional[datetime]] = mapped_column(DateTime)
|
||||
payment_date: Mapped[datetime] = mapped_column(DateTime)
|
||||
payment_date: Mapped[Optional[datetime]] = mapped_column(DateTime)
|
||||
rectification_payment_date: Mapped[Optional[datetime]] = mapped_column(DateTime)
|
||||
extraction_date: Mapped[Optional[datetime]] = mapped_column(DateTime)
|
||||
submission_date: Mapped[Optional[datetime]] = mapped_column(DateTime)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from decimal import Decimal
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from api.v1.common.base_models import TenantScopedMixin, TimestampMixin
|
||||
from core.database import Base
|
||||
@@ -40,15 +40,15 @@ class PedimentoDecrementables(Base, TenantScopedMixin, TimestampMixin):
|
||||
id: Mapped[int] = mapped_column(Integer)
|
||||
pedimento_id: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
|
||||
freight: Mapped[Decimal] = mapped_column(Numeric(13, 2))
|
||||
insurance: Mapped[Decimal] = mapped_column(Numeric(13, 2))
|
||||
loading: Mapped[Decimal] = mapped_column(Numeric(13, 2))
|
||||
unloading: Mapped[Decimal] = mapped_column(Numeric(13, 2))
|
||||
others: Mapped[Decimal] = mapped_column(Numeric(13, 2))
|
||||
currency: Mapped[str] = mapped_column(String(3))
|
||||
currency_factor: Mapped[Decimal] = mapped_column(Numeric(15, 8))
|
||||
not_affect_usd_value: Mapped[int] = mapped_column(SmallInteger)
|
||||
not_affect_customs_value: Mapped[int] = mapped_column(SmallInteger)
|
||||
freight: Mapped[Optional[Decimal]] = mapped_column(Numeric(13, 2))
|
||||
insurance: Mapped[Optional[Decimal]] = mapped_column(Numeric(13, 2))
|
||||
loading: Mapped[Optional[Decimal]] = mapped_column(Numeric(13, 2))
|
||||
unloading: Mapped[Optional[Decimal]] = mapped_column(Numeric(13, 2))
|
||||
others: Mapped[Optional[Decimal]] = mapped_column(Numeric(13, 2))
|
||||
currency: Mapped[Optional[str]] = mapped_column(String(3))
|
||||
currency_factor: Mapped[Optional[Decimal]] = mapped_column(Numeric(15, 8))
|
||||
not_affect_usd_value: Mapped[Optional[int]] = mapped_column(SmallInteger)
|
||||
not_affect_customs_value: Mapped[Optional[int]] = mapped_column(SmallInteger)
|
||||
|
||||
pedimento: Mapped["Pedimentos"] = relationship(
|
||||
"Pedimentos", back_populates="pedimento_decrementables"
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from api.v1.common.base_models import TenantScopedMixin, TimestampMixin
|
||||
from core.database import Base
|
||||
from sqlalchemy import (
|
||||
ForeignKeyConstraint,
|
||||
Integer,
|
||||
PrimaryKeyConstraint,
|
||||
String,
|
||||
)
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos
|
||||
|
||||
|
||||
class PedimentoGuides(Base, TenantScopedMixin, TimestampMixin):
|
||||
__tablename__ = "pedimento_guides"
|
||||
__table_args__ = (
|
||||
PrimaryKeyConstraint("id", name="pedimento_guides_pkey"),
|
||||
ForeignKeyConstraint(
|
||||
["pedimento_id"],
|
||||
["a76.pedimentos.id"],
|
||||
ondelete="CASCADE",
|
||||
name="fk_pedimento_guides",
|
||||
),
|
||||
{"schema": "a76"},
|
||||
)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer)
|
||||
pedimento_id: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
|
||||
guide: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
||||
identifier: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
||||
|
||||
pedimento: Mapped["Pedimentos"] = relationship(
|
||||
"Pedimentos", back_populates="pedimento_guides"
|
||||
)
|
||||
@@ -1,5 +1,5 @@
|
||||
from decimal import Decimal
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from api.v1.common.base_models import TenantScopedMixin, TimestampMixin
|
||||
from core.database import Base
|
||||
@@ -40,16 +40,16 @@ class PedimentoIncrementables(Base, TenantScopedMixin, TimestampMixin):
|
||||
id: Mapped[int] = mapped_column(Integer)
|
||||
pedimento_id: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
|
||||
insured_value: Mapped[Decimal] = mapped_column(Numeric(13, 2))
|
||||
freight: Mapped[Decimal] = mapped_column(Numeric(13, 2))
|
||||
insurance: Mapped[Decimal] = mapped_column(Numeric(13, 2))
|
||||
packaging: Mapped[Decimal] = mapped_column(Numeric(13, 2))
|
||||
others: Mapped[Decimal] = mapped_column(Numeric(13, 3))
|
||||
deductibles: Mapped[Decimal] = mapped_column(Numeric(13, 3))
|
||||
currency: Mapped[str] = mapped_column(String(3))
|
||||
currency_factor: Mapped[Decimal] = mapped_column(Numeric(15, 8))
|
||||
not_affect_usd_value: Mapped[int] = mapped_column(SmallInteger)
|
||||
not_affect_customs_value: Mapped[int] = mapped_column(SmallInteger)
|
||||
insured_value: Mapped[Optional[Decimal]] = mapped_column(Numeric(13, 2))
|
||||
freight: Mapped[Optional[Decimal]] = mapped_column(Numeric(13, 2))
|
||||
insurance: Mapped[Optional[Decimal]] = mapped_column(Numeric(13, 2))
|
||||
packaging: Mapped[Optional[Decimal]] = mapped_column(Numeric(13, 2))
|
||||
others: Mapped[Optional[Decimal]] = mapped_column(Numeric(13, 3))
|
||||
deductibles: Mapped[Optional[Decimal]] = mapped_column(Numeric(13, 3))
|
||||
currency: Mapped[Optional[str]] = mapped_column(String(3))
|
||||
currency_factor: Mapped[Optional[Decimal]] = mapped_column(Numeric(15, 8))
|
||||
not_affect_usd_value: Mapped[Optional[int]] = mapped_column(SmallInteger)
|
||||
not_affect_customs_value: Mapped[Optional[int]] = mapped_column(SmallInteger)
|
||||
|
||||
pedimento: Mapped["Pedimentos"] = relationship(
|
||||
"Pedimentos", back_populates="pedimento_incrementables"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from decimal import Decimal
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from api.v1.common.base_models import TenantScopedMixin, TimestampMixin
|
||||
from core.database import Base
|
||||
@@ -39,9 +39,9 @@ class PedimentoIndexes(Base, TenantScopedMixin, TimestampMixin):
|
||||
id: Mapped[int] = mapped_column(Integer)
|
||||
pedimento_id: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
|
||||
update_factor_type: Mapped[int] = mapped_column(SmallInteger)
|
||||
update_factor: Mapped[Decimal] = mapped_column(Numeric(7, 4))
|
||||
manual_update_factor: Mapped[int] = mapped_column(SmallInteger)
|
||||
update_factor_type: Mapped[Optional[int]] = mapped_column(SmallInteger)
|
||||
update_factor: Mapped[Optional[Decimal]] = mapped_column(Numeric(7, 4))
|
||||
manual_update_factor: Mapped[Optional[int]] = mapped_column(SmallInteger)
|
||||
|
||||
pedimento: Mapped["Pedimentos"] = relationship(
|
||||
"Pedimentos", back_populates="pedimento_indexes"
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from api.v1.common.base_models import TenantScopedMixin, TimestampMixin
|
||||
from core.database import Base
|
||||
from sqlalchemy import (
|
||||
ForeignKeyConstraint,
|
||||
Integer,
|
||||
Numeric,
|
||||
PrimaryKeyConstraint,
|
||||
String,
|
||||
UniqueConstraint,
|
||||
)
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos
|
||||
|
||||
|
||||
class PedimentoPackages(Base, TenantScopedMixin, TimestampMixin):
|
||||
__tablename__ = "pedimento_packages"
|
||||
__table_args__ = (
|
||||
PrimaryKeyConstraint("id", name="pedimento_packages_pkey"),
|
||||
ForeignKeyConstraint(
|
||||
["pedimento_id"],
|
||||
["a76.pedimentos.id"],
|
||||
ondelete="CASCADE",
|
||||
name="fk_pedimento_packages",
|
||||
),
|
||||
UniqueConstraint(
|
||||
"tenant_id",
|
||||
"company_id",
|
||||
"pedimento_id",
|
||||
name="pedimento_packages_pedimento_id_key",
|
||||
),
|
||||
{"schema": "a76"},
|
||||
)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer)
|
||||
pedimento_id: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
|
||||
quantity: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
||||
brand: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
||||
number: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
||||
vehicles: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
||||
|
||||
pedimento: Mapped["Pedimentos"] = relationship(
|
||||
"Pedimentos", back_populates="pedimento_packages"
|
||||
)
|
||||
@@ -0,0 +1,38 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from api.v1.common.base_models import TenantScopedMixin, TimestampMixin
|
||||
from core.database import Base
|
||||
from sqlalchemy import (
|
||||
ForeignKeyConstraint,
|
||||
Integer,
|
||||
PrimaryKeyConstraint,
|
||||
String,
|
||||
)
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos
|
||||
|
||||
|
||||
class PedimentoSeals(Base, TenantScopedMixin, TimestampMixin):
|
||||
__tablename__ = "pedimento_seals"
|
||||
__table_args__ = (
|
||||
PrimaryKeyConstraint("id", name="pedimento_seals_pkey"),
|
||||
ForeignKeyConstraint(
|
||||
["pedimento_id"],
|
||||
["a76.pedimentos.id"],
|
||||
ondelete="CASCADE",
|
||||
name="fk_pedimento_seals",
|
||||
),
|
||||
{"schema": "a76"},
|
||||
)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer)
|
||||
pedimento_id: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
|
||||
number: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
||||
identification: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
||||
|
||||
pedimento: Mapped["Pedimentos"] = relationship(
|
||||
"Pedimentos", back_populates="pedimento_seals"
|
||||
)
|
||||
@@ -0,0 +1,47 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from api.v1.common.base_models import TenantScopedMixin, TimestampMixin
|
||||
from core.database import Base
|
||||
from sqlalchemy import (
|
||||
ForeignKeyConstraint,
|
||||
Integer,
|
||||
PrimaryKeyConstraint,
|
||||
String,
|
||||
)
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos
|
||||
|
||||
|
||||
class PedimentoTransportCarriers(Base, TenantScopedMixin, TimestampMixin):
|
||||
__tablename__ = "pedimento_transport_carriers"
|
||||
__table_args__ = (
|
||||
PrimaryKeyConstraint("id", name="pedimento_transport_carriers_pkey"),
|
||||
ForeignKeyConstraint(
|
||||
["pedimento_id"],
|
||||
["a76.pedimentos.id"],
|
||||
ondelete="CASCADE",
|
||||
name="fk_pedimento_transport_carriers",
|
||||
),
|
||||
{"schema": "a76"},
|
||||
)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer)
|
||||
pedimento_id: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
|
||||
carrier: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
||||
rfc: Mapped[str | None] = mapped_column(String(20), nullable=True)
|
||||
curp: Mapped[str | None] = mapped_column(String(20), nullable=True)
|
||||
name: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
||||
address: Mapped[str | None] = mapped_column(String(300), nullable=True)
|
||||
city: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
||||
state: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
||||
country: Mapped[str | None] = mapped_column(String(3), nullable=True)
|
||||
tax_id: Mapped[str | None] = mapped_column(String(50), nullable=True)
|
||||
total_packages: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
||||
identification: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
||||
|
||||
pedimento: Mapped["Pedimentos"] = relationship(
|
||||
"Pedimentos", back_populates="pedimento_transport_carriers"
|
||||
)
|
||||
@@ -34,6 +34,9 @@ if TYPE_CHECKING:
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_config_updates import (
|
||||
PedimentoConfigUpdates,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_containers import (
|
||||
PedimentoContainers,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_customs_offices import (
|
||||
PedimentoCustomsOffices,
|
||||
)
|
||||
@@ -45,6 +48,15 @@ if TYPE_CHECKING:
|
||||
PedimentoIncrementables,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_indexes import PedimentoIndexes
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_packages import (
|
||||
PedimentoPackages,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_guides import (
|
||||
PedimentoGuides,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_contributions import (
|
||||
PedimentoContributions,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_payments import (
|
||||
PedimentoPayments,
|
||||
)
|
||||
@@ -54,6 +66,12 @@ if TYPE_CHECKING:
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_rectification_origin import (
|
||||
PedimentoRectificationOrigin,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_seals import (
|
||||
PedimentoSeals,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_transport_carriers import (
|
||||
PedimentoTransportCarriers,
|
||||
)
|
||||
from api.v1.modules.a76.pedmientos.models.pedimento_transport_means import (
|
||||
PedimentoTransportMeans,
|
||||
)
|
||||
@@ -167,3 +185,21 @@ class Pedimentos(Base, TenantScopedMixin, TimestampMixin):
|
||||
pedimento_validation: Mapped["PedimentoValidation"] = relationship(
|
||||
"PedimentoValidation", uselist=False, back_populates="pedimento", cascade="all, delete-orphan"
|
||||
)
|
||||
pedimento_packages: Mapped["PedimentoPackages"] = relationship(
|
||||
"PedimentoPackages", uselist=False, back_populates="pedimento", cascade="all, delete-orphan"
|
||||
)
|
||||
pedimento_transport_carriers: Mapped[list["PedimentoTransportCarriers"]] = relationship(
|
||||
"PedimentoTransportCarriers", back_populates="pedimento", cascade="all, delete-orphan"
|
||||
)
|
||||
pedimento_guides: Mapped[list["PedimentoGuides"]] = relationship(
|
||||
"PedimentoGuides", back_populates="pedimento", cascade="all, delete-orphan"
|
||||
)
|
||||
pedimento_contributions: Mapped[list["PedimentoContributions"]] = relationship(
|
||||
"PedimentoContributions", back_populates="pedimento", cascade="all, delete-orphan"
|
||||
)
|
||||
pedimento_seals: Mapped[list["PedimentoSeals"]] = relationship(
|
||||
"PedimentoSeals", back_populates="pedimento", cascade="all, delete-orphan"
|
||||
)
|
||||
pedimento_containers: Mapped[list["PedimentoContainers"]] = relationship(
|
||||
"PedimentoContainers", back_populates="pedimento", cascade="all, delete-orphan"
|
||||
)
|
||||
|
||||
@@ -48,6 +48,12 @@ from ..models.pedimento_config_parameters import PedimentoConfigParameters
|
||||
from ..models.pedimento_config_surcharges import PedimentoConfigSurcharges
|
||||
from ..models.pedimento_config_update_rectification import PedimentoConfigUpdateRectification
|
||||
from ..models.pedimento_config_updates import PedimentoConfigUpdates
|
||||
from ..models.pedimento_packages import PedimentoPackages
|
||||
from ..models.pedimento_transport_carriers import PedimentoTransportCarriers
|
||||
from ..models.pedimento_seals import PedimentoSeals
|
||||
from ..models.pedimento_containers import PedimentoContainers
|
||||
from ..models.pedimento_guides import PedimentoGuides
|
||||
from ..models.pedimento_contributions import PedimentoContributions
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -110,6 +116,12 @@ class PedimentosService:
|
||||
selectinload(Pedimentos.pedimento_config_surcharges),
|
||||
selectinload(Pedimentos.pedimento_config_update_rectification),
|
||||
selectinload(Pedimentos.pedimento_config_updates),
|
||||
selectinload(Pedimentos.pedimento_packages),
|
||||
selectinload(Pedimentos.pedimento_transport_carriers),
|
||||
selectinload(Pedimentos.pedimento_guides),
|
||||
selectinload(Pedimentos.pedimento_contributions),
|
||||
selectinload(Pedimentos.pedimento_seals),
|
||||
selectinload(Pedimentos.pedimento_containers),
|
||||
)
|
||||
.order_by(desc(Pedimentos.created_at))
|
||||
.offset(skip)
|
||||
@@ -160,6 +172,12 @@ class PedimentosService:
|
||||
selectinload(Pedimentos.pedimento_config_surcharges),
|
||||
selectinload(Pedimentos.pedimento_config_update_rectification),
|
||||
selectinload(Pedimentos.pedimento_config_updates),
|
||||
selectinload(Pedimentos.pedimento_packages),
|
||||
selectinload(Pedimentos.pedimento_transport_carriers),
|
||||
selectinload(Pedimentos.pedimento_guides),
|
||||
selectinload(Pedimentos.pedimento_contributions),
|
||||
selectinload(Pedimentos.pedimento_seals),
|
||||
selectinload(Pedimentos.pedimento_containers),
|
||||
)
|
||||
|
||||
return query.first()
|
||||
@@ -199,6 +217,12 @@ class PedimentosService:
|
||||
'pedimento_config_surcharges': pedimento_data.pedimento_config_surcharges,
|
||||
'pedimento_config_update_rectification': pedimento_data.pedimento_config_update_rectification,
|
||||
'pedimento_config_updates': pedimento_data.pedimento_config_updates,
|
||||
'pedimento_packages': pedimento_data.pedimento_packages,
|
||||
'pedimento_transport_carriers': pedimento_data.pedimento_transport_carriers,
|
||||
'pedimento_guides': pedimento_data.pedimento_guides,
|
||||
'pedimento_contributions': getattr(pedimento_data, 'pedimento_contributions', None),
|
||||
'pedimento_seals': pedimento_data.pedimento_seals,
|
||||
'pedimento_containers': pedimento_data.pedimento_containers,
|
||||
}
|
||||
|
||||
# Crear pedimento principal (excluyendo relaciones)
|
||||
@@ -209,7 +233,8 @@ class PedimentosService:
|
||||
'pedimento_rectification_origin', 'pedimento_transport_means',
|
||||
'pedimento_config_additional', 'pedimento_config_calculations',
|
||||
'pedimento_config_parameters', 'pedimento_config_surcharges',
|
||||
'pedimento_config_update_rectification', 'pedimento_config_updates'
|
||||
'pedimento_config_update_rectification', 'pedimento_config_updates',
|
||||
'pedimento_packages', 'pedimento_transport_carriers', 'pedimento_guides', 'pedimento_seals', 'pedimento_containers'
|
||||
})
|
||||
|
||||
pedimento = Pedimentos(**pedimento_dict)
|
||||
@@ -219,7 +244,7 @@ class PedimentosService:
|
||||
db.add(pedimento)
|
||||
db.flush() # Flush para obtener el ID sin commit
|
||||
|
||||
# Helper function para crear objetos relacionados
|
||||
# Helper function para crear objetos relacionados (uno a uno)
|
||||
def create_related(model_class, data, extra_fields=None):
|
||||
if data or extra_fields:
|
||||
# Inicializar obj_dict desde data si existe, sino como dict vacío
|
||||
@@ -274,6 +299,29 @@ class PedimentosService:
|
||||
create_related(PedimentoConfigUpdates,
|
||||
related_data['pedimento_config_updates'])
|
||||
|
||||
# Crear PedimentoPackages (uno a uno)
|
||||
create_related(PedimentoPackages, related_data['pedimento_packages'])
|
||||
|
||||
# Crear relaciones uno a muchos
|
||||
def create_many(model_class, items):
|
||||
if not items:
|
||||
return
|
||||
for item in items:
|
||||
obj_dict = item.model_dump(exclude_none=True)
|
||||
obj = model_class(**obj_dict)
|
||||
obj.pedimento_id = pedimento.id
|
||||
obj.tenant_id = tenant_id
|
||||
obj.company_id = company_id
|
||||
db.add(obj)
|
||||
|
||||
create_many(PedimentoTransportCarriers,
|
||||
related_data['pedimento_transport_carriers'])
|
||||
create_many(PedimentoGuides, related_data['pedimento_guides'])
|
||||
create_many(PedimentoContributions, related_data['pedimento_contributions'])
|
||||
create_many(PedimentoSeals, related_data['pedimento_seals'])
|
||||
create_many(PedimentoContainers,
|
||||
related_data['pedimento_containers'])
|
||||
|
||||
db.commit()
|
||||
db.refresh(pedimento)
|
||||
return pedimento
|
||||
@@ -323,7 +371,8 @@ class PedimentosService:
|
||||
'pedimento_rectification_origin', 'pedimento_transport_means',
|
||||
'pedimento_config_additional', 'pedimento_config_calculations',
|
||||
'pedimento_config_parameters', 'pedimento_config_surcharges',
|
||||
'pedimento_config_update_rectification', 'pedimento_config_updates'
|
||||
'pedimento_config_update_rectification', 'pedimento_config_updates',
|
||||
'pedimento_packages', 'pedimento_transport_carriers', 'pedimento_guides', 'pedimento_contributions', 'pedimento_seals', 'pedimento_containers'
|
||||
})
|
||||
|
||||
for field, value in update_data.items():
|
||||
@@ -343,8 +392,13 @@ class PedimentosService:
|
||||
if not data:
|
||||
return
|
||||
|
||||
existing = service_class.get_by_pedimento_id(
|
||||
db, pedimento_id, tenant_id, company_id)
|
||||
existing = None
|
||||
if service_class:
|
||||
existing = service_class.get_by_pedimento_id(
|
||||
db, pedimento_id, tenant_id, company_id)
|
||||
else:
|
||||
existing = getattr(pedimento, data_attr, None)
|
||||
|
||||
if existing:
|
||||
# Actualizar existente (excluir pedimento_id, tenant_id, company_id)
|
||||
for field, value in data.items():
|
||||
@@ -358,6 +412,28 @@ class PedimentosService:
|
||||
obj.company_id = company_id
|
||||
db.add(obj)
|
||||
|
||||
def upsert_one_to_many(model_class, data_attr):
|
||||
full_data = pedimento_data.model_dump()
|
||||
if data_attr not in full_data:
|
||||
return
|
||||
|
||||
items = full_data[data_attr]
|
||||
if items is None:
|
||||
return
|
||||
|
||||
# Reemplazar completamente la colección por simplicidad
|
||||
existing_items = getattr(pedimento, data_attr)
|
||||
if existing_items:
|
||||
for item in list(existing_items):
|
||||
db.delete(item)
|
||||
|
||||
for item in items:
|
||||
obj = model_class(**item)
|
||||
obj.pedimento_id = pedimento_id
|
||||
obj.tenant_id = tenant_id
|
||||
obj.company_id = company_id
|
||||
db.add(obj)
|
||||
|
||||
# Actualizar o crear tablas relacionadas
|
||||
update_or_create_related(
|
||||
PedimentoDatesService, PedimentoDates, 'pedimento_dates')
|
||||
@@ -392,6 +468,15 @@ class PedimentosService:
|
||||
update_or_create_related(
|
||||
PedimentoConfigUpdatesService, PedimentoConfigUpdates, 'pedimento_config_updates')
|
||||
|
||||
# Manejar nuevas relaciones
|
||||
update_or_create_related(None, PedimentoPackages, 'pedimento_packages')
|
||||
upsert_one_to_many(PedimentoTransportCarriers,
|
||||
'pedimento_transport_carriers')
|
||||
upsert_one_to_many(PedimentoGuides, 'pedimento_guides')
|
||||
upsert_one_to_many(PedimentoContributions, 'pedimento_contributions')
|
||||
upsert_one_to_many(PedimentoSeals, 'pedimento_seals')
|
||||
upsert_one_to_many(PedimentoContainers, 'pedimento_containers')
|
||||
|
||||
db.commit()
|
||||
db.refresh(pedimento)
|
||||
return pedimento
|
||||
|
||||
@@ -54,8 +54,11 @@ export interface PedimentoIncrementables {
|
||||
insured_value?: number | null;
|
||||
packaging?: number | null;
|
||||
freight?: number | null;
|
||||
insurance?: number | null;
|
||||
others?: number | null;
|
||||
deductibles?: number | null;
|
||||
currency?: string | null;
|
||||
currency_factor?: number | null;
|
||||
not_affect_usd_value?: boolean | null;
|
||||
not_affect_customs_value?: boolean | null;
|
||||
}
|
||||
@@ -83,6 +86,7 @@ export interface PedimentoConfigAdditional {
|
||||
enable_import_invoice_recipient?: boolean | null;
|
||||
send_502_validation_file_for_consolidated?: boolean | null;
|
||||
add_remove_norms?: boolean | null;
|
||||
choose_invoice_cove?: boolean | null;
|
||||
}
|
||||
|
||||
export interface PedimentoConfigCalculations {
|
||||
|
||||
@@ -629,7 +629,7 @@
|
||||
<Select.Item value="TasaEspecificaPreciosReferenciaUM">Tasa especifica sobre precios de referencia con UM</Select.Item>
|
||||
</Select.Content>
|
||||
</Select.Root>
|
||||
<Button size="icon" variant="outline">
|
||||
<Button size="icon" variant="outline" onclick={openNewContribGenInDialog}>
|
||||
<Plus class="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -166,26 +166,27 @@
|
||||
});
|
||||
|
||||
// Cuando cambia el Tipo de Operación
|
||||
// Optimizado: solo ejecutar cuando cambien los campos específicos relevantes
|
||||
$effect(() => {
|
||||
if (!formData) return;
|
||||
|
||||
// Solo rastrear los campos que realmente importan
|
||||
const currentType = formData.operation_type;
|
||||
const currentCode = formData.pedimento_code;
|
||||
const currentRegime = formData.regime;
|
||||
|
||||
// Detectar si el tipo de operación cambió
|
||||
const typeChanged = currentType !== previousOperationType;
|
||||
previousOperationType = currentType;
|
||||
|
||||
// Si no hay clave seleccionada, no hacer nada
|
||||
if (!formData.pedimento_code) return;
|
||||
|
||||
// Si el tipo es null/undefined, no hacer nada
|
||||
if (currentType === null || currentType === undefined) return;
|
||||
// Si no hay clave seleccionada o tipo no definido, salir temprano
|
||||
if (!currentCode || currentType === null || currentType === undefined) return;
|
||||
|
||||
const expectedTypeCode = operationTypeToTypeCode(currentType);
|
||||
|
||||
// Buscar matches para esta combinación de clave + tipo de operación
|
||||
const matches = codePedimentoRegimens.filter(r =>
|
||||
r.pedimento_code === formData.pedimento_code &&
|
||||
r.pedimento_code === currentCode &&
|
||||
r.type_code === expectedTypeCode
|
||||
);
|
||||
|
||||
@@ -195,7 +196,7 @@
|
||||
const validRegimens = new Set(matches.map(m => m.regimen_code).filter((code): code is string => code !== null));
|
||||
|
||||
// Si el tipo de operación cambió O el régimen actual no es válido, actualizar el régimen
|
||||
if (typeChanged || !formData.regime || !validRegimens.has(formData.regime)) {
|
||||
if (typeChanged || !currentRegime || !validRegimens.has(currentRegime)) {
|
||||
const firstMatch = matches[0];
|
||||
if (firstMatch?.regimen_code) {
|
||||
formData.regime = firstMatch.regimen_code;
|
||||
@@ -214,6 +215,11 @@
|
||||
// Inicializar formData con los valores del pedimento (o vacío si es null)
|
||||
if (!formData) {
|
||||
const datesData = pedimento?.pedimento_dates;
|
||||
const incrementablesData = pedimento?.pedimento_incrementables;
|
||||
const decrementablesData = pedimento?.pedimento_decrementables;
|
||||
const indexesData = pedimento?.pedimento_indexes;
|
||||
const configAdditionalData = pedimento?.pedimento_config_additional;
|
||||
|
||||
formData = {
|
||||
year: pedimento?.year || currentYear,
|
||||
customs_office: pedimento?.customs_office || '',
|
||||
@@ -236,39 +242,87 @@
|
||||
rectification_payment_date: datesData?.rectification_payment_date ? datesData.rectification_payment_date.substring(0, 10) : '',
|
||||
original_date: datesData?.original_date ? datesData.original_date.substring(0, 10) : '',
|
||||
payment_date: datesData?.payment_date ? datesData.payment_date.substring(0, 10) : '',
|
||||
// Incrementables fields
|
||||
valor_seguro: incrementablesData?.insured_value ?? null,
|
||||
embalajes: incrementablesData?.packaging ?? null,
|
||||
fletes: incrementablesData?.freight ?? null,
|
||||
seguros_incrementables: incrementablesData?.insurance ?? null,
|
||||
otros_incrementables: incrementablesData?.others ?? null,
|
||||
deducibles: incrementablesData?.deductibles ?? null,
|
||||
moneda_incrementables: incrementablesData?.currency ?? '',
|
||||
factor_moneda_incrementables: incrementablesData?.currency_factor ?? null,
|
||||
no_afectar_valor_dolares_inc: incrementablesData?.not_affect_usd_value ?? false,
|
||||
no_afectar_valor_aduana: incrementablesData?.not_affect_customs_value ?? false,
|
||||
// Decrementables fields
|
||||
fletes_decrementable: decrementablesData?.freight ?? null,
|
||||
seguros: decrementablesData?.insurance ?? null,
|
||||
carga: decrementablesData?.loading ?? null,
|
||||
descarga: decrementablesData?.unloading ?? null,
|
||||
otros: decrementablesData?.others ?? null,
|
||||
moneda_decrementable: decrementablesData?.currency ?? '',
|
||||
afectar_valor_dolares: decrementablesData?.not_affect_usd_value ?? false,
|
||||
// Indexes fields
|
||||
tipo_factor: indexesData?.update_factor_type === 1 ? 'INPC' : indexesData?.update_factor_type === 2 ? 'variacion_cambiaria' : null,
|
||||
factor_actualizacion: indexesData?.update_factor ?? null,
|
||||
factor_actualizacion_manual: indexesData?.manual_update_factor ?? false,
|
||||
// Config Additional fields
|
||||
anio_impresion: configAdditionalData?.manual_pedimento_year ?? '',
|
||||
agregar_po_auto: configAdditionalData?.add_po_identifier ?? false,
|
||||
no_eximir_normas: configAdditionalData?.do_not_exempt_norms_complement_x ?? false,
|
||||
activar_destinatario: configAdditionalData?.enable_import_invoice_recipient ?? false,
|
||||
agregar_registro_502: configAdditionalData?.send_502_validation_file_for_consolidated ?? false,
|
||||
agregar_quitar_normas: configAdditionalData?.add_remove_norms ?? false,
|
||||
facturar_cove: configAdditionalData?.choose_invoice_cove ?? false,
|
||||
// Campos de captura automática
|
||||
fecha_captura: currentDate,
|
||||
hora_captura: currentTime
|
||||
};
|
||||
}
|
||||
|
||||
// Asegurar que el año siempre esté actualizado con el año actual
|
||||
// Flag para evitar loops en actualización de año
|
||||
let yearInitialized = false;
|
||||
|
||||
// Asegurar que el año siempre esté actualizado con el año actual (solo una vez)
|
||||
$effect(() => {
|
||||
if (formData && !pedimento?.year) {
|
||||
if (formData && !pedimento?.year && !yearInitialized) {
|
||||
formData.year = currentYear;
|
||||
yearInitialized = true;
|
||||
}
|
||||
});
|
||||
|
||||
// Track para evitar loops en obtención de tipo de cambio
|
||||
let lastFetchedDate: string | null = null;
|
||||
let lastCompanyId: number | null = null;
|
||||
|
||||
// Obtener automáticamente el tipo de cambio cuando cambie la fecha de entrada
|
||||
$effect(() => {
|
||||
if (formData && formData.entry_date && companyStore.activeCompany) {
|
||||
console.log('🔍 [TIPO CAMBIO] Buscando para fecha:', formData.entry_date, 'Company ID:', companyStore.activeCompany.id);
|
||||
const entryDate = formData?.entry_date;
|
||||
const companyId = companyStore.activeCompany?.id;
|
||||
|
||||
// Solo ejecutar si los valores clave cambiaron
|
||||
if (formData && entryDate && companyId &&
|
||||
(entryDate !== lastFetchedDate || companyId !== lastCompanyId)) {
|
||||
|
||||
getExchangeRateByDate(formData.entry_date, companyStore.activeCompany.id)
|
||||
lastFetchedDate = entryDate;
|
||||
lastCompanyId = companyId;
|
||||
|
||||
console.log('🔍 [TIPO CAMBIO] Buscando para fecha:', entryDate, 'Company ID:', companyId);
|
||||
|
||||
getExchangeRateByDate(entryDate, companyId)
|
||||
.then(usdRate => {
|
||||
console.log('✅ [TIPO CAMBIO] Respuesta recibida:', usdRate);
|
||||
if (usdRate && formData) {
|
||||
formData.exchange_rate = usdRate.value;
|
||||
console.log('✅ [TIPO CAMBIO] Actualizado a:', usdRate.value);
|
||||
} else {
|
||||
console.warn('⚠️ [TIPO CAMBIO] No encontrado para fecha:', formData.entry_date);
|
||||
console.warn('⚠️ [TIPO CAMBIO] No encontrado para fecha:', entryDate);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('❌ [TIPO CAMBIO] Error:', err);
|
||||
});
|
||||
} else {
|
||||
console.log('⏭️ [TIPO CAMBIO] Saltado - formData:', !!formData, 'entry_date:', formData?.entry_date, 'company:', !!companyStore.activeCompany);
|
||||
console.log('⏭️ [TIPO CAMBIO] Saltado - Sin cambios en fecha o company');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -866,9 +920,10 @@
|
||||
<Label for="moneda_incrementables">Moneda</Label>
|
||||
<Input
|
||||
id="moneda_incrementables"
|
||||
type="number"
|
||||
type="text"
|
||||
maxlength={3}
|
||||
bind:value={formData.moneda_incrementables}
|
||||
placeholder="0.00"
|
||||
placeholder="USD"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -203,8 +203,8 @@
|
||||
alert('Reordenar facturas no implementado aún');
|
||||
}
|
||||
|
||||
function datosSonana() {
|
||||
alert('Datos Sonana no implementado aún');
|
||||
function datosSoriana() {
|
||||
alert('Datos Soriana no implementado aún');
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -273,9 +273,9 @@
|
||||
<ArrowUpDown class="mr-1.5" size={14} />
|
||||
Reordenar
|
||||
</Button>
|
||||
<Button size="sm" variant="outline" onclick={datosSonana}>
|
||||
<Button size="sm" variant="outline" onclick={datosSoriana}>
|
||||
<FileText class="mr-1.5" size={14} />
|
||||
Datos Sonana
|
||||
Datos Soriana
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -183,8 +183,8 @@
|
||||
alert('Detalles de Consolidación no implementado aún');
|
||||
}
|
||||
|
||||
function datosSonana() {
|
||||
alert('Datos Sonana no implementado aún');
|
||||
function datosSoriana() {
|
||||
alert('Datos Soriana no implementado aún');
|
||||
}
|
||||
|
||||
function refreshPartidas() {
|
||||
@@ -241,9 +241,9 @@
|
||||
<Info class="mr-1.5" size={14} />
|
||||
Detalles de Consolidación
|
||||
</Button>
|
||||
<Button size="sm" variant="outline" onclick={datosSonana}>
|
||||
<Button size="sm" variant="outline" onclick={datosSoriana}>
|
||||
<FileText class="mr-1.5" size={14} />
|
||||
Datos Sonana
|
||||
Datos Soriana
|
||||
</Button>
|
||||
<Button size="sm" variant="outline" onclick={refreshPartidas}>
|
||||
<RotateCw size={14} />
|
||||
|
||||
@@ -93,14 +93,27 @@
|
||||
};
|
||||
} = $props();
|
||||
|
||||
// Cargar datos del pedimento cuando está disponible
|
||||
// Flag para evitar loops infinitos al cargar datos
|
||||
let dataLoaded = false;
|
||||
let lastPedimentoId: number | null = null;
|
||||
|
||||
// Cargar datos del pedimento cuando está disponible (solo una vez)
|
||||
$effect(() => {
|
||||
if (pedimento) {
|
||||
const pedimentoId = pedimento?.id ?? null;
|
||||
|
||||
// Si el pedimento cambió, resetear el flag
|
||||
if (pedimentoId !== lastPedimentoId) {
|
||||
lastPedimentoId = pedimentoId;
|
||||
dataLoaded = false;
|
||||
}
|
||||
|
||||
if (pedimento && !dataLoaded) {
|
||||
dataLoaded = true;
|
||||
console.log('📦 Cargando datos del pedimento en package-transportation-tab-form');
|
||||
|
||||
// Cargar datos de bultos desde pedimento_bultos
|
||||
if (pedimento.pedimento_bultos) {
|
||||
const bultos = pedimento.pedimento_bultos;
|
||||
// Cargar datos de bultos desde pedimento_packages
|
||||
if (pedimento.pedimento_packages) {
|
||||
const bultos = pedimento.pedimento_packages;
|
||||
formData.bultos = {
|
||||
cantidad: bultos.quantity ?? 0,
|
||||
marcas: bultos.brand || 'S/M',
|
||||
@@ -109,9 +122,9 @@
|
||||
};
|
||||
}
|
||||
|
||||
// Cargar transportes desde pedimento_transport_means
|
||||
if (pedimento.pedimento_transport_means && Array.isArray(pedimento.pedimento_transport_means)) {
|
||||
formData.transportes = pedimento.pedimento_transport_means.map((t: any) => ({
|
||||
// Cargar transportes desde pedimento_transport_carriers
|
||||
if (pedimento.pedimento_transport_carriers && Array.isArray(pedimento.pedimento_transport_carriers)) {
|
||||
formData.transportes = pedimento.pedimento_transport_carriers.map((t: any) => ({
|
||||
id: t.id,
|
||||
transportista: t.carrier || '',
|
||||
rfc: t.rfc || '',
|
||||
@@ -126,6 +139,15 @@
|
||||
identificacion: t.identification || ''
|
||||
}));
|
||||
}
|
||||
|
||||
// Cargar guías desde pedimento_guides
|
||||
if (pedimento.pedimento_guides && Array.isArray(pedimento.pedimento_guides)) {
|
||||
formData.guias = pedimento.pedimento_guides.map((g: any) => ({
|
||||
id: g.id,
|
||||
guia: g.guide || '',
|
||||
identificador: g.identifier || ''
|
||||
}));
|
||||
}
|
||||
|
||||
// Cargar precintos desde pedimento_seals
|
||||
if (pedimento.pedimento_seals && Array.isArray(pedimento.pedimento_seals)) {
|
||||
@@ -155,20 +177,6 @@
|
||||
}
|
||||
});
|
||||
|
||||
// Log cuando el componente se monta/desmonta
|
||||
$effect(() => {
|
||||
console.log('🚀 BultosTransportesTabForm montado - Datos actuales:', {
|
||||
transportes: formData?.transportes?.length ?? 0,
|
||||
guias: formData?.guias?.length ?? 0,
|
||||
precintos: formData?.precintos?.length ?? 0,
|
||||
contenedores: formData?.contenedores?.length ?? 0
|
||||
});
|
||||
|
||||
return () => {
|
||||
console.log('💥 BultosTransportesTabForm desmontado');
|
||||
};
|
||||
});
|
||||
|
||||
// Cargar países al montar el componente
|
||||
onMount(async () => {
|
||||
try {
|
||||
|
||||
@@ -76,7 +76,9 @@ class CompanyStore {
|
||||
|
||||
this._loading = true;
|
||||
try {
|
||||
const response = await fetch('/api/v1/a76/company/my-companies');
|
||||
const response = await fetch('/api/v1/a76/company/my-companies', {
|
||||
credentials: 'include'
|
||||
});
|
||||
if (response.ok) {
|
||||
const newCompanies = await response.json();
|
||||
|
||||
|
||||
@@ -146,9 +146,24 @@
|
||||
agregar_entidad_federativa_proveedor: false
|
||||
});
|
||||
|
||||
// Flag para evitar loops infinitos en el effect
|
||||
let otrosDatosLoaded = false;
|
||||
let lastPedimentoId: number | null = null;
|
||||
|
||||
// Cargar datos del pedimento en otrosDatosFormData cuando data.pedimento está disponible
|
||||
// Solo ejecutar una vez cuando el pedimento cambia
|
||||
$effect(() => {
|
||||
if (data.pedimento && !data.isCreate) {
|
||||
// Solo rastrear data.pedimento?.id para evitar re-ejecuciones innecesarias
|
||||
const pedimentoId = data.pedimento?.id ?? null;
|
||||
|
||||
// Si el ID del pedimento cambió, resetear el flag
|
||||
if (pedimentoId !== lastPedimentoId) {
|
||||
lastPedimentoId = pedimentoId;
|
||||
otrosDatosLoaded = false;
|
||||
}
|
||||
|
||||
if (data.pedimento && !data.isCreate && !otrosDatosLoaded) {
|
||||
otrosDatosLoaded = true;
|
||||
const pedimento = data.pedimento;
|
||||
|
||||
// Mapear pedimento_config_calculations
|
||||
@@ -304,6 +319,15 @@
|
||||
exchange_rate: generalFormData?.exchange_rate || undefined
|
||||
};
|
||||
|
||||
// Helper function para convertir fecha YYYY-MM-DD a ISO datetime
|
||||
function dateToISO(dateString: string | null | undefined): string | null {
|
||||
if (!dateString) return null;
|
||||
// Si ya tiene formato ISO completo, retornarlo
|
||||
if (dateString.includes('T')) return dateString;
|
||||
// Si es solo fecha (YYYY-MM-DD), agregar tiempo medianoche
|
||||
return `${dateString}T00:00:00`;
|
||||
}
|
||||
|
||||
// Fechas - enviar si hay al menos un campo con valor
|
||||
if (generalFormData) {
|
||||
const hasDatesValue = generalFormData.entry_date || generalFormData.pedimento_date ||
|
||||
@@ -311,12 +335,12 @@
|
||||
generalFormData.original_date || generalFormData.payment_date;
|
||||
if (hasDatesValue) {
|
||||
payload.pedimento_dates = {
|
||||
entry_date: generalFormData.entry_date || null,
|
||||
pedimento_date: generalFormData.pedimento_date || null,
|
||||
payment_date: generalFormData.payment_date || null,
|
||||
rectification_payment_date: generalFormData.rectification_payment_date || null,
|
||||
extraction_date: generalFormData.extraction_date || null,
|
||||
original_date: generalFormData.original_date || null
|
||||
entry_date: dateToISO(generalFormData.entry_date),
|
||||
pedimento_date: dateToISO(generalFormData.pedimento_date),
|
||||
payment_date: dateToISO(generalFormData.payment_date),
|
||||
rectification_payment_date: dateToISO(generalFormData.rectification_payment_date),
|
||||
extraction_date: dateToISO(generalFormData.extraction_date),
|
||||
original_date: dateToISO(generalFormData.original_date)
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -397,16 +421,20 @@
|
||||
do_not_exempt_norms_complement_x: generalFormData.no_eximir_normas || false,
|
||||
enable_import_invoice_recipient: generalFormData.activar_destinatario || false,
|
||||
send_502_validation_file_for_consolidated: generalFormData.agregar_registro_502 || false,
|
||||
add_remove_norms: generalFormData.agregar_quitar_normas || false
|
||||
};
|
||||
}
|
||||
add_remove_norms: generalFormData.agregar_quitar_normas || false,
|
||||
choose_invoice_cove: generalFormData.facturar_cove || false
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Identificadores - enviar array de identificadores si existen
|
||||
// Identificadores - TEMPORALMENTE DESHABILITADO (no hay soporte en backend)
|
||||
// TODO: Implementar tabla de identificadores en el backend
|
||||
/*
|
||||
if (identificadoresFormData?.identificadores && identificadoresFormData.identificadores.length > 0) {
|
||||
payload.identificadores = identificadoresFormData.identificadores;
|
||||
}
|
||||
*/
|
||||
|
||||
// Config Calculations - configuraciones de cálculo DTA, IVA, prevalidación
|
||||
if (otrosDatosFormData) {
|
||||
@@ -502,6 +530,7 @@
|
||||
if (otrosDatosFormData) {
|
||||
const hasUpdatesValue = otrosDatosFormData.actualizar_iva !== undefined ||
|
||||
otrosDatosFormData.actualizar_advalorem !== undefined ||
|
||||
otrosDatosFormData.actualizar_dta !== undefined ||
|
||||
otrosDatosFormData.actualizar_cc !== undefined ||
|
||||
otrosDatosFormData.actualizar_ieps !== undefined;
|
||||
|
||||
@@ -538,6 +567,77 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Bultos/Transportes - enviar datos de paquetes, transportistas, guías, precintos y contenedores
|
||||
if (bultosTransportesFormData) {
|
||||
// Paquetes (pedimento_packages) - relación one-to-one
|
||||
const bultos = bultosTransportesFormData.bultos;
|
||||
if (bultos && (bultos.cantidad || bultos.marcas || bultos.numero || bultos.vehiculos)) {
|
||||
payload.pedimento_packages = {
|
||||
quantity: bultos.cantidad || null,
|
||||
brand: bultos.marcas || null,
|
||||
number: bultos.numero || null,
|
||||
vehicles: bultos.vehiculos || null
|
||||
};
|
||||
}
|
||||
|
||||
// Transportistas (pedimento_transport_carriers) - relación one-to-many
|
||||
if (bultosTransportesFormData.transportes && bultosTransportesFormData.transportes.length > 0) {
|
||||
payload.pedimento_transport_carriers = bultosTransportesFormData.transportes.map((t: any) => ({
|
||||
carrier: t.transportista || null,
|
||||
rfc: t.rfc || null,
|
||||
curp: t.curp || null,
|
||||
name: t.nombre || null,
|
||||
address: t.domicilio || null,
|
||||
city: t.ciudad || null,
|
||||
state: t.estado || null,
|
||||
country: t.pais || null,
|
||||
tax_id: t.identificacion_fiscal || null,
|
||||
total_packages: t.total_bultos || null,
|
||||
identification: t.identificacion || null
|
||||
}));
|
||||
}
|
||||
|
||||
// Guías (pedimento_guides) - relación one-to-many
|
||||
if (bultosTransportesFormData.guias && bultosTransportesFormData.guias.length > 0) {
|
||||
payload.pedimento_guides = bultosTransportesFormData.guias.map((g: any) => ({
|
||||
guide: g.guia || null,
|
||||
identifier: g.identificador || null
|
||||
}));
|
||||
}
|
||||
|
||||
// Precintos (pedimento_seals) - relación one-to-many
|
||||
if (bultosTransportesFormData.precintos && bultosTransportesFormData.precintos.length > 0) {
|
||||
payload.pedimento_seals = bultosTransportesFormData.precintos.map((p: any) => ({
|
||||
number: p.numero || null,
|
||||
identification: p.identificacion || null
|
||||
}));
|
||||
}
|
||||
|
||||
// Contenedores (pedimento_containers) - relación one-to-many
|
||||
if (bultosTransportesFormData.contenedores && bultosTransportesFormData.contenedores.length > 0) {
|
||||
payload.pedimento_containers = bultosTransportesFormData.contenedores.map((c: any) => ({
|
||||
number: c.numero || null,
|
||||
identification: c.identificacion || null,
|
||||
type: c.tipo || null
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// Contribuciones - enviar datos de contribuciones generales
|
||||
if (contribucionesFormData && contribucionesFormData.contribuciones && contribucionesFormData.contribuciones.length > 0) {
|
||||
payload.pedimento_contributions = contribucionesFormData.contribuciones.map((c: any) => ({
|
||||
contribucion: c.contribucion || null,
|
||||
tipo_tasa: c.tipo_tasa || null,
|
||||
tasa: c.tasa || null,
|
||||
forma_pago: c.forma_pago || null,
|
||||
importe: c.importe || null,
|
||||
gravamen: c.gravamen || null,
|
||||
abreviacion: c.abreviacion || null,
|
||||
forma_pago_2: c.forma_pago_2 || null,
|
||||
importe_2: c.importe_2 || null
|
||||
}));
|
||||
}
|
||||
|
||||
// Digitalización - solo enviar si hay digitalizaciones
|
||||
if (digitalizacionFormData && digitalizacionFormData.digitalizaciones && digitalizacionFormData.digitalizaciones.length > 0) {
|
||||
(payload as any).digitalizaciones = digitalizacionFormData.digitalizaciones.map((d: any) => ({
|
||||
@@ -692,9 +792,10 @@
|
||||
</Alert.Root>
|
||||
{/if}
|
||||
|
||||
<!-- Contenido de las tabs con padding inferior para el footer flotante -->
|
||||
<div class="pb-56">
|
||||
<Tabs.Root bind:value={activeTab} class="space-y-4">
|
||||
<!-- Tabs con footer fijo -->
|
||||
<Tabs.Root value={activeTab} onValueChange={(v) => { if (v) activeTab = v; }} class="space-y-4">
|
||||
<!-- Contenido de las tabs con padding inferior para el footer flotante -->
|
||||
<div class="pb-56">
|
||||
<Tabs.Content value="general">
|
||||
<GeneralTabForm
|
||||
pedimento={data.pedimento}
|
||||
@@ -765,20 +866,17 @@
|
||||
<Tabs.Content value="digitalizacion">
|
||||
<DigitalizacionTabForm bind:formData={digitalizacionFormData} />
|
||||
</Tabs.Content>
|
||||
</Tabs.Root>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer fijo en la parte inferior - Fuera del contenedor principal -->
|
||||
<Tabs.Root bind:value={activeTab}>
|
||||
<div
|
||||
class="fixed bottom-0 left-0 right-0 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 border-t shadow-lg z-[5] transition-[left] duration-200 ease-linear"
|
||||
style:left={sidebar.isMobile ? '0' : (sidebar.open ? 'var(--sidebar-width)' : '0')}
|
||||
>
|
||||
<div class="px-4 py-4 space-y-4 max-w-[1400px] mx-auto">
|
||||
<!-- Tabs Navigation -->
|
||||
<div class="w-full overflow-x-auto pb-2">
|
||||
<Tabs.List class="inline-flex w-full gap-1">
|
||||
<!-- Footer fijo en la parte inferior -->
|
||||
<div
|
||||
class="fixed bottom-0 left-0 right-0 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80 border-t shadow-lg z-[5] transition-[left] duration-200 ease-linear"
|
||||
style:left={sidebar.isMobile ? '0' : (sidebar.open ? 'var(--sidebar-width)' : '0')}
|
||||
>
|
||||
<div class="px-4 py-4 space-y-4 max-w-[1400px] mx-auto">
|
||||
<!-- Tabs Navigation -->
|
||||
<div class="w-full overflow-x-auto pb-2">
|
||||
<Tabs.List class="inline-flex w-full gap-1">
|
||||
<Tabs.Trigger value="general" class="flex items-center gap-1.5 px-2.5 py-1.5 text-sm">
|
||||
<FileText size={14} />
|
||||
<span>General</span>
|
||||
@@ -839,4 +937,5 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Tabs.Root>
|
||||
</Tabs.Root>
|
||||
</div>
|
||||
Reference in New Issue
Block a user