diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_additional.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_additional.py index 36dc50c4..641a9b77 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_additional.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_additional.py @@ -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): diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_contributions.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_contributions.py new file mode 100644 index 00000000..e2f5795c --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_contributions.py @@ -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) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_dates.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_dates.py index c9c4cb62..e2825f6a 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_dates.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_dates.py @@ -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") diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_packages_transport.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_packages_transport.py new file mode 100644 index 00000000..e8dd3800 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_packages_transport.py @@ -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) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimentos.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimentos.py index c9d55786..b52c34eb 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimentos.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimentos.py @@ -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) diff --git a/backend/api/v1/modules/a76/pedmientos/models/__init__.py b/backend/api/v1/modules/a76/pedmientos/models/__init__.py new file mode 100644 index 00000000..8e5d83ca --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/__init__.py @@ -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", +] diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_additional.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_additional.py index 28fff3a1..d3469979 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_additional.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_additional.py @@ -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" diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_containers.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_containers.py new file mode 100644 index 00000000..702002ae --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_containers.py @@ -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" + ) diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_contributions.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_contributions.py new file mode 100644 index 00000000..8aac377f --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_contributions.py @@ -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" + ) diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_dates.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_dates.py index fe8a5d0a..495acb43 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_dates.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_dates.py @@ -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) diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_decrementables.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_decrementables.py index 732800f2..27ecda48 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_decrementables.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_decrementables.py @@ -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" diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_guides.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_guides.py new file mode 100644 index 00000000..23e14a2f --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_guides.py @@ -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" + ) diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_incrementables.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_incrementables.py index d13e660b..04a40423 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_incrementables.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_incrementables.py @@ -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" diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_indexes.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_indexes.py index 9f0cbd68..4bfb8e91 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_indexes.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_indexes.py @@ -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" diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_packages.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_packages.py new file mode 100644 index 00000000..4b313d0d --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_packages.py @@ -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" + ) diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_seals.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_seals.py new file mode 100644 index 00000000..aa5d3199 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_seals.py @@ -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" + ) diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_transport_carriers.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_transport_carriers.py new file mode 100644 index 00000000..63396a33 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_transport_carriers.py @@ -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" + ) diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimentos.py b/backend/api/v1/modules/a76/pedmientos/models/pedimentos.py index a7950792..2ee63de2 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimentos.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimentos.py @@ -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" + ) diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimentos.py b/backend/api/v1/modules/a76/pedmientos/services/pedimentos.py index 89f4e91c..e5d69ef4 100644 --- a/backend/api/v1/modules/a76/pedmientos/services/pedimentos.py +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimentos.py @@ -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 diff --git a/frontend/src/lib/api/dashboard/a76/pedimentos.ts b/frontend/src/lib/api/dashboard/a76/pedimentos.ts index e80c24d5..b6a611c7 100644 --- a/frontend/src/lib/api/dashboard/a76/pedimentos.ts +++ b/frontend/src/lib/api/dashboard/a76/pedimentos.ts @@ -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 { diff --git a/frontend/src/lib/components/dashboard/pedimentos/edit/contributions-tab-form.svelte b/frontend/src/lib/components/dashboard/pedimentos/edit/contributions-tab-form.svelte index 41ebc60c..b34f3e11 100644 --- a/frontend/src/lib/components/dashboard/pedimentos/edit/contributions-tab-form.svelte +++ b/frontend/src/lib/components/dashboard/pedimentos/edit/contributions-tab-form.svelte @@ -629,7 +629,7 @@ Tasa especifica sobre precios de referencia con UM - diff --git a/frontend/src/lib/components/dashboard/pedimentos/edit/general-tab-form.svelte b/frontend/src/lib/components/dashboard/pedimentos/edit/general-tab-form.svelte index c5d7d51d..bc4f361b 100644 --- a/frontend/src/lib/components/dashboard/pedimentos/edit/general-tab-form.svelte +++ b/frontend/src/lib/components/dashboard/pedimentos/edit/general-tab-form.svelte @@ -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 @@ diff --git a/frontend/src/lib/components/dashboard/pedimentos/edit/invoices-tab-form.svelte b/frontend/src/lib/components/dashboard/pedimentos/edit/invoices-tab-form.svelte index 11b3d105..a11e2196 100644 --- a/frontend/src/lib/components/dashboard/pedimentos/edit/invoices-tab-form.svelte +++ b/frontend/src/lib/components/dashboard/pedimentos/edit/invoices-tab-form.svelte @@ -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'); } @@ -273,9 +273,9 @@ Reordenar - diff --git a/frontend/src/lib/components/dashboard/pedimentos/edit/items-tab-form.svelte b/frontend/src/lib/components/dashboard/pedimentos/edit/items-tab-form.svelte index 6e90abf8..410c8b01 100644 --- a/frontend/src/lib/components/dashboard/pedimentos/edit/items-tab-form.svelte +++ b/frontend/src/lib/components/dashboard/pedimentos/edit/items-tab-form.svelte @@ -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 @@ Detalles de Consolidación -