diff --git a/backend/alembic/versions/3a012dff0274_increase_port_description_length.py b/backend/alembic/versions/3a012dff0274_increase_port_description_length.py deleted file mode 100644 index 802b6983..00000000 --- a/backend/alembic/versions/3a012dff0274_increase_port_description_length.py +++ /dev/null @@ -1,28 +0,0 @@ -"""increase_port_description_length - -Revision ID: 3a012dff0274 -Revises: 7937209f9718 -Create Date: 2025-12-24 10:24:49.927020 - -""" -from typing import Sequence, Union - -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision: str = '3a012dff0274' -down_revision: Union[str, Sequence[str], None] = '7937209f9718' -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade() -> None: - """Upgrade schema.""" - pass - - -def downgrade() -> None: - """Downgrade schema.""" - pass diff --git a/backend/api/v1/common/dto_mixins.py b/backend/api/v1/common/dto_mixins.py index f1e256f1..335af837 100644 --- a/backend/api/v1/common/dto_mixins.py +++ b/backend/api/v1/common/dto_mixins.py @@ -14,10 +14,10 @@ class CurrencyMixin: class AffectValueMixin: """Mixin for value affect flags""" - not_affect_usd_value: Optional[int] = Field( + not_affect_usd_value: Optional[bool] = Field( None, description="Not affect USD value" ) - not_affect_customs_value: Optional[int] = Field( + not_affect_customs_value: Optional[bool] = Field( None, description="Not affect customs value" ) @@ -25,7 +25,8 @@ class AffectValueMixin: class UpdateFlagsMixin: """Mixin for update flags""" - update_vat: Optional[int] = Field(None, description="Update VAT") - update_advalorem: Optional[int] = Field(None, description="Update advalorem") - update_cc: Optional[int] = Field(None, description="Update CC") - update_ieps: Optional[int] = Field(None, description="Update IEPS") + update_vat: Optional[bool] = Field(None, description="Update VAT") + update_advalorem: Optional[bool] = Field(None, description="Update advalorem") + update_dta: Optional[bool] = Field(None, description="Update DTA") + update_cc: Optional[bool] = Field(None, description="Update CC") + update_ieps: Optional[bool] = Field(None, description="Update IEPS") diff --git a/backend/api/v1/common/tenant_crud_routes.py b/backend/api/v1/common/tenant_crud_routes.py index 9a3c65ae..3ff9b0a0 100644 --- a/backend/api/v1/common/tenant_crud_routes.py +++ b/backend/api/v1/common/tenant_crud_routes.py @@ -301,8 +301,15 @@ class TenantCRUDRoutes( db, company_id, current_user) # For child resources, parent_id validation would go here - resource = self.service.create(db, data, tenant_id, company_id) - return resource + try: + resource = self.service.create(db, data, tenant_id, company_id) + return resource + except ValueError as e: + # Capturar errores de validación (como duplicados) + raise HTTPException(status_code=400, detail=str(e)) + except Exception as e: + # Re-lanzar otros errores + raise else: # Parent resource - no parent_id needed @@ -324,8 +331,15 @@ class TenantCRUDRoutes( ): tenant_id = validate_access_to_resource( db, company_id, current_user) - resource = self.service.create(db, data, tenant_id, company_id) - return resource + try: + resource = self.service.create(db, data, tenant_id, company_id) + return resource + except ValueError as e: + # Capturar errores de validación (como duplicados) + raise HTTPException(status_code=400, detail=str(e)) + except Exception as e: + # Re-lanzar otros errores + raise # PUT route # For parent resources: PUT /{id} @@ -353,9 +367,13 @@ class TenantCRUDRoutes( db, company_id, current_user) parent_id = path_params.get(self.parent_id_name) - resource = self.service.update( - db, parent_id, tenant_id, data, company_id - ) + try: + resource = self.service.update( + db, parent_id, tenant_id, data, company_id + ) + except ValueError as e: + # Capturar errores de validación (como duplicados) + raise HTTPException(status_code=400, detail=str(e)) if not resource: raise HTTPException( @@ -388,9 +406,13 @@ class TenantCRUDRoutes( tenant_id = validate_access_to_resource( db, company_id, current_user) - resource = self.service.update( - db, resource_id, tenant_id, data, company_id - ) + try: + resource = self.service.update( + db, resource_id, tenant_id, data, company_id + ) + except ValueError as e: + # Capturar errores de validación (como duplicados) + raise HTTPException(status_code=400, detail=str(e)) if not resource: raise HTTPException( 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 028a1dd4..36dc50c4 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 @@ -7,22 +7,22 @@ from pydantic import BaseModel, ConfigDict, Field class PedimentoConfigAdditionalBase(BaseModel): """Base schema for Pedimento Config Additional""" - pedimento_id: int = Field(..., description="Pedimento ID") - tenant_id: int = Field(..., description="Tenant ID") - add_po_identifier: Optional[int] = Field(None, description="Add PO identifier") - do_not_exempt_norms_complement_x: Optional[int] = Field( + pedimento_id: Optional[int] = Field(None, description="Pedimento ID") + tenant_id: Optional[int] = Field(None, description="Tenant ID") + add_po_identifier: Optional[bool] = Field(None, description="Add PO identifier") + do_not_exempt_norms_complement_x: Optional[bool] = Field( None, description="Do not exempt norms complement X" ) manual_pedimento_year: Optional[str] = Field( None, max_length=2, description="Manual pedimento year" ) - enable_import_invoice_recipient: Optional[int] = Field( + enable_import_invoice_recipient: Optional[bool] = Field( None, description="Enable import invoice recipient" ) - send_502_validation_file_for_consolidated: Optional[int] = Field( + send_502_validation_file_for_consolidated: Optional[bool] = Field( None, description="Send 502 validation file for consolidated" ) - add_remove_norms: Optional[int] = Field(None, description="Add/remove norms") + add_remove_norms: Optional[bool] = Field(None, description="Add/remove norms") class PedimentoConfigAdditionalCreate(PedimentoConfigAdditionalBase): @@ -34,12 +34,12 @@ class PedimentoConfigAdditionalCreate(PedimentoConfigAdditionalBase): class PedimentoConfigAdditionalUpdate(BaseModel): """Schema for updating a Pedimento Config Additional""" - add_po_identifier: Optional[int] = None - do_not_exempt_norms_complement_x: Optional[int] = None + add_po_identifier: Optional[bool] = None + do_not_exempt_norms_complement_x: Optional[bool] = None manual_pedimento_year: Optional[str] = Field(None, max_length=2) - enable_import_invoice_recipient: Optional[int] = None - send_502_validation_file_for_consolidated: Optional[int] = None - add_remove_norms: Optional[int] = None + enable_import_invoice_recipient: Optional[bool] = None + send_502_validation_file_for_consolidated: Optional[bool] = None + add_remove_norms: Optional[bool] = None class PedimentoConfigAdditionalResponse(PedimentoConfigAdditionalBase): diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_calculations.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_calculations.py index 692b9e9c..74fc640e 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_calculations.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_calculations.py @@ -7,24 +7,24 @@ from pydantic import BaseModel, ConfigDict, Field class PedimentoConfigCalculationsBase(BaseModel): """Base schema for Pedimento Config Calculations""" - pedimento_id: int = Field(..., description="Pedimento ID") - tenant_id: int = Field(..., description="Tenant ID") + pedimento_id: Optional[int] = Field(None, description="Pedimento ID") + tenant_id: Optional[int] = Field(None, description="Tenant ID") dta_type: Optional[str] = Field(None, max_length=1, description="DTA type") - dta_operation: Optional[int] = Field(None, description="DTA operation") - dta_vehicle_count: Optional[int] = Field(None, description="DTA vehicle count") - dta_mixed_rate_8permil: Optional[int] = Field( - None, description="DTA mixed rate 8 per mil" + dta_operation: Optional[bool] = Field(False, description="DTA operation") + dta_vehicle_count: Optional[int] = Field(0, description="DTA vehicle count") + dta_mixed_rate_8permil: Optional[bool] = Field( + False, description="DTA mixed rate 8 per mil" ) - pays_vat: Optional[int] = Field(None, description="Pays VAT") - pays_prevalidation: Optional[int] = Field(None, description="Pays prevalidation") - include_sagar_certificate_fee: Optional[int] = Field( - None, description="Include SAGAR certificate fee" + pays_vat: Optional[bool] = Field(False, description="Pays VAT") + pays_prevalidation: Optional[bool] = Field(False, description="Pays prevalidation") + include_sagar_certificate_fee: Optional[bool] = Field( + False, description="Include SAGAR certificate fee" ) - fixed_vehicle_dta_fee: Optional[int] = Field( - None, description="Fixed vehicle DTA fee" + fixed_vehicle_dta_fee: Optional[bool] = Field( + False, description="Fixed vehicle DTA fee" ) additional_fixed_fee: Optional[int] = Field( - None, description="Additional fixed fee" + 0, description="Additional fixed fee" ) additional_fixed_fee_payment_method: Optional[int] = Field( None, description="Additional fixed fee payment method" @@ -41,13 +41,13 @@ class PedimentoConfigCalculationsUpdate(BaseModel): """Schema for updating a Pedimento Config Calculations""" dta_type: Optional[str] = Field(None, max_length=1) - dta_operation: Optional[int] = None + dta_operation: Optional[bool] = None dta_vehicle_count: Optional[int] = None - dta_mixed_rate_8permil: Optional[int] = None - pays_vat: Optional[int] = None - pays_prevalidation: Optional[int] = None - include_sagar_certificate_fee: Optional[int] = None - fixed_vehicle_dta_fee: Optional[int] = None + dta_mixed_rate_8permil: Optional[bool] = None + pays_vat: Optional[bool] = None + pays_prevalidation: Optional[bool] = None + include_sagar_certificate_fee: Optional[bool] = None + fixed_vehicle_dta_fee: Optional[bool] = None additional_fixed_fee: Optional[int] = None additional_fixed_fee_payment_method: Optional[int] = None diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_parameters.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_parameters.py index 3f5f04ed..d04a03e4 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_parameters.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_parameters.py @@ -8,31 +8,31 @@ from pydantic import BaseModel, ConfigDict, Field class PedimentoConfigParametersBase(BaseModel): """Base schema for Pedimento Config Parameters""" - pedimento_id: int = Field(..., description="Pedimento ID") - tenant_id: int = Field(..., description="Tenant ID") - is_embassy: Optional[int] = Field(None, description="Is embassy") - embassy_dta: Optional[Decimal] = Field(None, description="Embassy DTA") - rule_3121_section_ii: Optional[int] = Field( - None, description="Rule 3.1.21 Section II" + pedimento_id: Optional[int] = Field(None, description="Pedimento ID") + tenant_id: Optional[int] = Field(None, description="Tenant ID") + is_embassy: Optional[bool] = Field(False, description="Is embassy") + embassy_dta: Optional[Decimal] = Field(Decimal('0.00'), description="Embassy DTA") + rule_3121_section_ii: Optional[bool] = Field( + False, description="Rule 3.1.21 Section II" ) - use_previous_tariff: Optional[int] = Field(None, description="Use previous tariff") - use_payment_date_fi: Optional[int] = Field(None, description="Use payment date FI") - add_state_supplier_record_505: Optional[int] = Field( - None, description="Add state supplier record 505" + use_previous_tariff: Optional[bool] = Field(False, description="Use previous tariff") + use_payment_date_fi: Optional[bool] = Field(False, description="Use payment date FI") + add_state_supplier_record_505: Optional[bool] = Field( + False, description="Add state supplier record 505" ) - customs_value_calculation: Optional[int] = Field( - None, description="Customs value calculation" + customs_value_calculation: Optional[bool] = Field( + False, description="Customs value calculation" ) - two_decimals_unit_value: Optional[int] = Field( - None, description="Two decimals unit value" + two_decimals_unit_value: Optional[bool] = Field( + False, description="Two decimals unit value" ) - customs_value_per_item: Optional[int] = Field( - None, description="Customs value per item" + customs_value_per_item: Optional[bool] = Field( + False, description="Customs value per item" ) - is_national_supplier: Optional[int] = Field( - None, description="Is national supplier" + is_national_supplier: Optional[bool] = Field( + False, description="Is national supplier" ) - is_consolidated: Optional[int] = Field(None, description="Is consolidated") + is_consolidated: Optional[bool] = Field(False, description="Is consolidated") class PedimentoConfigParametersCreate(PedimentoConfigParametersBase): @@ -44,17 +44,17 @@ class PedimentoConfigParametersCreate(PedimentoConfigParametersBase): class PedimentoConfigParametersUpdate(BaseModel): """Schema for updating a Pedimento Config Parameters""" - is_embassy: Optional[int] = None + is_embassy: Optional[bool] = None embassy_dta: Optional[Decimal] = None - rule_3121_section_ii: Optional[int] = None - use_previous_tariff: Optional[int] = None - use_payment_date_fi: Optional[int] = None - add_state_supplier_record_505: Optional[int] = None - customs_value_calculation: Optional[int] = None - two_decimals_unit_value: Optional[int] = None - customs_value_per_item: Optional[int] = None - is_national_supplier: Optional[int] = None - is_consolidated: Optional[int] = None + rule_3121_section_ii: Optional[bool] = None + use_previous_tariff: Optional[bool] = None + use_payment_date_fi: Optional[bool] = None + add_state_supplier_record_505: Optional[bool] = None + customs_value_calculation: Optional[bool] = None + two_decimals_unit_value: Optional[bool] = None + customs_value_per_item: Optional[bool] = None + is_national_supplier: Optional[bool] = None + is_consolidated: Optional[bool] = None class PedimentoConfigParametersResponse(PedimentoConfigParametersBase): diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_surcharges.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_surcharges.py index 385ebcf9..4337770c 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_surcharges.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_surcharges.py @@ -7,14 +7,14 @@ from pydantic import BaseModel, ConfigDict, Field class PedimentoConfigSurchargesBase(BaseModel): """Base schema for Pedimento Config Surcharges""" - pedimento_id: int = Field(..., description="Pedimento ID") - tenant_id: int = Field(..., description="Tenant ID") - surcharge_igi: Optional[int] = Field(None, description="Surcharge IGI") - surcharge_dta: Optional[int] = Field(None, description="Surcharge DTA") - surcharge_vat: Optional[int] = Field(None, description="Surcharge VAT") - surcharge_isan: Optional[int] = Field(None, description="Surcharge ISAN") - surcharge_ieps: Optional[int] = Field(None, description="Surcharge IEPS") - surcharge_cc: Optional[int] = Field(None, description="Surcharge CC") + pedimento_id: Optional[int] = Field(None, description="Pedimento ID") + tenant_id: Optional[int] = Field(None, description="Tenant ID") + surcharge_igi: Optional[bool] = Field(None, description="Surcharge IGI") + surcharge_dta: Optional[bool] = Field(None, description="Surcharge DTA") + surcharge_vat: Optional[bool] = Field(None, description="Surcharge VAT") + surcharge_isan: Optional[bool] = Field(None, description="Surcharge ISAN") + surcharge_ieps: Optional[bool] = Field(None, description="Surcharge IEPS") + surcharge_cc: Optional[bool] = Field(None, description="Surcharge CC") class PedimentoConfigSurchargesCreate(PedimentoConfigSurchargesBase): @@ -26,12 +26,12 @@ class PedimentoConfigSurchargesCreate(PedimentoConfigSurchargesBase): class PedimentoConfigSurchargesUpdate(BaseModel): """Schema for updating a Pedimento Config Surcharges""" - surcharge_igi: Optional[int] = None - surcharge_dta: Optional[int] = None - surcharge_vat: Optional[int] = None - surcharge_isan: Optional[int] = None - surcharge_ieps: Optional[int] = None - surcharge_cc: Optional[int] = None + surcharge_igi: Optional[bool] = None + surcharge_dta: Optional[bool] = None + surcharge_vat: Optional[bool] = None + surcharge_isan: Optional[bool] = None + surcharge_ieps: Optional[bool] = None + surcharge_cc: Optional[bool] = None class PedimentoConfigSurchargesResponse(PedimentoConfigSurchargesBase): diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_update_rectification.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_update_rectification.py index 62bbf8f7..6255e781 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_update_rectification.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_update_rectification.py @@ -9,9 +9,9 @@ from api.v1.common.dto_mixins import UpdateFlagsMixin class PedimentoConfigUpdateRectificationBase(BaseModel, UpdateFlagsMixin): """Base schema for Pedimento Config Update Rectification""" - pedimento_id: int = Field(..., description="Pedimento ID") - tenant_id: int = Field(..., description="Tenant ID") - calculate_surcharge: Optional[int] = Field(None, description="Calculate surcharge") + pedimento_id: Optional[int] = Field(None, description="Pedimento ID") + tenant_id: Optional[int] = Field(None, description="Tenant ID") + calculate_surcharge: Optional[bool] = Field(None, description="Calculate surcharge") class PedimentoConfigUpdateRectificationCreate(PedimentoConfigUpdateRectificationBase): @@ -23,7 +23,7 @@ class PedimentoConfigUpdateRectificationCreate(PedimentoConfigUpdateRectificatio class PedimentoConfigUpdateRectificationUpdate(BaseModel, UpdateFlagsMixin): """Schema for updating a Pedimento Config Update Rectification""" - calculate_surcharge: Optional[int] = None + calculate_surcharge: Optional[bool] = None class PedimentoConfigUpdateRectificationResponse( diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_updates.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_updates.py index b3098972..0931d66c 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_updates.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_updates.py @@ -9,8 +9,8 @@ from api.v1.common.dto_mixins import UpdateFlagsMixin class PedimentoConfigUpdatesBase(BaseModel, UpdateFlagsMixin): """Base schema for Pedimento Config Updates""" - pedimento_id: int = Field(..., description="Pedimento ID") - tenant_id: int = Field(..., description="Tenant ID") + pedimento_id: Optional[int] = Field(None, description="Pedimento ID") + tenant_id: Optional[int] = Field(None, description="Tenant ID") class PedimentoConfigUpdatesCreate(PedimentoConfigUpdatesBase): """Schema for creating a new Pedimento Config Updates""" diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_customs_offices.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_customs_offices.py index 31444672..7c556e95 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_customs_offices.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_customs_offices.py @@ -7,8 +7,8 @@ from pydantic import BaseModel, ConfigDict, Field class PedimentoCustomsOfficesBase(BaseModel): """Base schema for Pedimento Customs Offices""" - pedimento_id: int = Field(..., description="Pedimento ID") - tenant_id: int = Field(..., description="Tenant ID") + pedimento_id: Optional[int] = Field(None, description="Pedimento ID") + tenant_id: Optional[int] = Field(None, description="Tenant ID") dispatch_customs: Optional[str] = Field( None, max_length=3, description="Dispatch customs" ) 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 dd7f048e..c9c4cb62 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_dates.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_dates.py @@ -7,7 +7,8 @@ from pydantic import BaseModel, ConfigDict, Field class PedimentoDatesBase(BaseModel): """Base schema for Pedimento Dates""" - entry_date: Optional[datetime] = Field(None, description="Entry date") + 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") rectification_payment_date: Optional[datetime] = Field( None, description="Rectification payment date" @@ -23,7 +24,8 @@ class PedimentoDatesBase(BaseModel): class PedimentoDatesCreate(BaseModel): """Schema for creating a new Pedimento Dates - pedimento_id and tenant_id are set by backend""" - entry_date: Optional[datetime] = Field(None, description="Entry date") + 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") rectification_payment_date: Optional[datetime] = Field(None, description="Rectification payment date") extraction_date: Optional[datetime] = Field(None, description="Extraction date") @@ -37,7 +39,8 @@ class PedimentoDatesCreate(BaseModel): class PedimentoDatesUpdate(BaseModel): """Schema for updating a Pedimento Dates""" - entry_date: Optional[datetime] = None + entry_date: Optional[datetime] = None + pedimento_date: Optional[datetime] = None payment_date: Optional[datetime] = None rectification_payment_date: Optional[datetime] = None extraction_date: Optional[datetime] = None diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_decrementables.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_decrementables.py index aabce8cf..796bfee1 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_decrementables.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_decrementables.py @@ -8,8 +8,8 @@ from pydantic import BaseModel, ConfigDict, Field class PedimentoDecrementablesBase(BaseModel): """Base schema for Pedimento Decrementables""" - pedimento_id: int = Field(..., description="Pedimento ID") - tenant_id: int = Field(..., description="Tenant ID") + pedimento_id: Optional[int] = Field(None, description="Pedimento ID") + tenant_id: Optional[int] = Field(None, description="Tenant ID") freight: Optional[Decimal] = Field(None, description="Freight") insurance: Optional[Decimal] = Field(None, description="Insurance") loading: Optional[Decimal] = Field(None, description="Loading") @@ -17,10 +17,10 @@ class PedimentoDecrementablesBase(BaseModel): others: Optional[Decimal] = Field(None, description="Others") currency: Optional[str] = Field(None, max_length=3, description="Currency") currency_factor: Optional[Decimal] = Field(None, description="Currency factor") - not_affect_usd_value: Optional[int] = Field( + not_affect_usd_value: Optional[bool] = Field( None, description="Not affect USD value" ) - not_affect_customs_value: Optional[int] = Field( + not_affect_customs_value: Optional[bool] = Field( None, description="Not affect customs value" ) @@ -41,8 +41,8 @@ class PedimentoDecrementablesUpdate(BaseModel): others: Optional[Decimal] = None currency: Optional[str] = Field(None, max_length=3) currency_factor: Optional[Decimal] = None - not_affect_usd_value: Optional[int] = None - not_affect_customs_value: Optional[int] = None + not_affect_usd_value: Optional[bool] = None + not_affect_customs_value: Optional[bool] = None class PedimentoDecrementablesResponse(PedimentoDecrementablesBase): diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_incrementables.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_incrementables.py index 59beceb2..c8100d01 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_incrementables.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_incrementables.py @@ -8,8 +8,8 @@ from pydantic import BaseModel, ConfigDict, Field class PedimentoIncrementablesBase(BaseModel): """Base schema for Pedimento Incrementables""" - pedimento_id: int = Field(..., description="Pedimento ID") - tenant_id: int = Field(..., description="Tenant ID") + pedimento_id: Optional[int] = Field(None, description="Pedimento ID") + tenant_id: Optional[int] = Field(None, description="Tenant ID") insured_value: Optional[Decimal] = Field(None, description="Insured value") freight: Optional[Decimal] = Field(None, description="Freight") insurance: Optional[Decimal] = Field(None, description="Insurance") @@ -18,10 +18,10 @@ class PedimentoIncrementablesBase(BaseModel): deductibles: Optional[Decimal] = Field(None, description="Deductibles") currency: Optional[str] = Field(None, max_length=3, description="Currency") currency_factor: Optional[Decimal] = Field(None, description="Currency factor") - not_affect_usd_value: Optional[int] = Field( + not_affect_usd_value: Optional[bool] = Field( None, description="Not affect USD value" ) - not_affect_customs_value: Optional[int] = Field( + not_affect_customs_value: Optional[bool] = Field( None, description="Not affect customs value" ) @@ -43,8 +43,8 @@ class PedimentoIncrementablesUpdate(BaseModel): deductibles: Optional[Decimal] = None currency: Optional[str] = Field(None, max_length=3) currency_factor: Optional[Decimal] = None - not_affect_usd_value: Optional[int] = None - not_affect_customs_value: Optional[int] = None + not_affect_usd_value: Optional[bool] = None + not_affect_customs_value: Optional[bool] = None class PedimentoIncrementablesResponse(PedimentoIncrementablesBase): diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_indexes.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_indexes.py index b304abee..55edc40f 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_indexes.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_indexes.py @@ -8,11 +8,11 @@ from pydantic import BaseModel, ConfigDict, Field class PedimentoIndexesBase(BaseModel): """Base schema for Pedimento Indexes""" - pedimento_id: int = Field(..., description="Pedimento ID") - tenant_id: int = Field(..., description="Tenant ID") + pedimento_id: Optional[int] = Field(None, description="Pedimento ID") + tenant_id: Optional[int] = Field(None, description="Tenant ID") update_factor_type: Optional[int] = Field(None, description="Update factor type") update_factor: Optional[Decimal] = Field(None, description="Update factor") - manual_update_factor: Optional[int] = Field( + manual_update_factor: Optional[bool] = Field( None, description="Manual update factor" ) @@ -28,7 +28,7 @@ class PedimentoIndexesUpdate(BaseModel): update_factor_type: Optional[int] = None update_factor: Optional[Decimal] = None - manual_update_factor: Optional[int] = None + manual_update_factor: Optional[bool] = None class PedimentoIndexesResponse(PedimentoIndexesBase): diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_payments.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_payments.py index bdd98381..992e02d7 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_payments.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_payments.py @@ -9,8 +9,8 @@ from pydantic import BaseModel, ConfigDict, Field class PedimentoPaymentsBase(BaseModel): """Base schema for Pedimento Payments""" - pedimento_id: int = Field(..., description="Pedimento ID") - tenant_id: int = Field(..., description="Tenant ID") + pedimento_id: Optional[int] = Field(None, description="Pedimento ID") + tenant_id: Optional[int] = Field(None, description="Tenant ID") acknowledgment: Optional[str] = Field( None, max_length=20, description="Acknowledgment" ) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_rectification_destination.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_rectification_destination.py index b021cc11..7a39e104 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_rectification_destination.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_rectification_destination.py @@ -6,8 +6,8 @@ from pydantic import BaseModel, ConfigDict, Field class PedimentoRectificationDestinationBase(BaseModel): """Base schema for Pedimento Rectification Destination""" - pedimento_id: int = Field(..., description="Pedimento ID") - tenant_id: int = Field(..., description="Tenant ID") + pedimento_id: Optional[int] = Field(None, description="Pedimento ID") + tenant_id: Optional[int] = Field(None, description="Tenant ID") destination_pedimento_year: Optional[str] = Field( None, max_length=2, description="Destination pedimento year" ) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_rectification_origin.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_rectification_origin.py index 93caf94f..8cc56bb3 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_rectification_origin.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_rectification_origin.py @@ -7,8 +7,8 @@ from pydantic import BaseModel, ConfigDict, Field class PedimentoRectificationOriginBase(BaseModel): """Base schema for Pedimento Rectification Origin""" - pedimento_id: int = Field(..., description="Pedimento ID") - tenant_id: int = Field(..., description="Tenant ID") + pedimento_id: Optional[int] = Field(None, description="Pedimento ID") + tenant_id: Optional[int] = Field(None, description="Tenant ID") original_pedimento_year: Optional[str] = Field( None, max_length=2, description="Original pedimento year" ) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_transport_means.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_transport_means.py index da6fb6aa..ba86131a 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_transport_means.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_transport_means.py @@ -7,8 +7,8 @@ from pydantic import BaseModel, ConfigDict, Field class PedimentoTransportMeansBase(BaseModel): """Base schema for Pedimento Transport Means""" - pedimento_id: int = Field(..., description="Pedimento ID") - tenant_id: int = Field(..., description="Tenant ID") + pedimento_id: Optional[int] = Field(None, description="Pedimento ID") + tenant_id: Optional[int] = Field(None, description="Tenant ID") destination: Optional[int] = Field(None, description="Destination") entry_exit: Optional[str] = Field(None, max_length=2, description="Entry/exit") arrival: str = Field(..., max_length=2, description="Arrival") diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_validation.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_validation.py index 649ce3cb..7be73678 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_validation.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_validation.py @@ -7,8 +7,8 @@ from pydantic import BaseModel, ConfigDict, Field class PedimentoValidationBase(BaseModel): """Base schema for Pedimento Validation""" - pedimento_id: int = Field(..., description="Pedimento ID") - tenant_id: int = Field(..., description="Tenant ID") + pedimento_id: Optional[int] = Field(None, description="Pedimento ID") + tenant_id: Optional[int] = Field(None, description="Tenant ID") validator: Optional[str] = Field(None, max_length=3, description="Validator") validation_ack: Optional[str] = Field( None, max_length=8, description="Validation acknowledgment" diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimentos.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimentos.py index 32598d75..c9d55786 100644 --- a/backend/api/v1/modules/a76/pedmientos/dtos/pedimentos.py +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimentos.py @@ -50,7 +50,8 @@ class PedimentosBase(BaseModel): usd_value: Optional[Decimal] = Field(None, description="USD value") paid_price: Optional[Decimal] = Field(None, description="Paid price") gross_weight: Optional[Decimal] = Field(None, description="Gross weight") - exchange_rate: Optional[Decimal] = Field(None, description="Exchange rate") + exchange_rate: Optional[Decimal] = Field(None, description="Exchange rate") + observations: Optional[str] = Field(None, description="Observations") class PedimentosCreate(PedimentosBase): """Schema for creating a new Pedimento""" @@ -61,13 +62,11 @@ class PedimentosCreate(PedimentosBase): license: str = Field(..., max_length=4, description="License") pedimento_number: str = Field(..., max_length=7, description="Pedimento number") client_id: int = Field(..., description="Client ID") - operation_type: int = Field(..., description="Operation type") - pedimento_type: str = Field(..., max_length=20, description="Pedimento type") + # operation_type, pedimento_type, status son opcionales - se pueden llenar después pedimento_code: str = Field( ..., max_length=2, description="Pedimento key" ) - regime: str = Field(..., max_length=3, description="Regime") - status: str = Field(..., max_length=30, description="Status") + regime: str = Field(..., max_length=3, description="Regime") pedimento_dates: Optional[PedimentoDatesCreate] = None pedimento_decrementables: Optional[PedimentoDecrementablesCreate] = None @@ -103,6 +102,7 @@ class PedimentosUpdate(BaseModel): paid_price: Optional[Decimal] = None gross_weight: Optional[Decimal] = None exchange_rate: Optional[Decimal] = None + observations: Optional[str] = None # Sub-resources pedimento_dates: Optional[PedimentoDatesCreate] = None diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_calculations.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_calculations.py index 013768fe..3dcb2859 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_calculations.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_calculations.py @@ -1,8 +1,9 @@ -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 from sqlalchemy import ( + Boolean, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, @@ -38,16 +39,16 @@ class PedimentoConfigCalculations(Base, TenantScopedMixin, TimestampMixin): id: Mapped[int] = mapped_column(Integer) pedimento_id: Mapped[int] = mapped_column(Integer, nullable=False) - dta_type: Mapped[str] = mapped_column(String(1)) - dta_operation: Mapped[int] = mapped_column(SmallInteger) - dta_vehicle_count: Mapped[int] = mapped_column(SmallInteger) - dta_mixed_rate_8permil: Mapped[int] = mapped_column(SmallInteger) - pays_vat: Mapped[int] = mapped_column(SmallInteger) - pays_prevalidation: Mapped[int] = mapped_column(SmallInteger) - include_sagar_certificate_fee: Mapped[int] = mapped_column(SmallInteger) - fixed_vehicle_dta_fee: Mapped[int] = mapped_column(SmallInteger) - additional_fixed_fee: Mapped[int] = mapped_column(SmallInteger) - additional_fixed_fee_payment_method: Mapped[int] = mapped_column(SmallInteger) + dta_type: Mapped[Optional[str]] = mapped_column(String(1), nullable=True) + dta_operation: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + dta_vehicle_count: Mapped[int] = mapped_column(SmallInteger, default=0, server_default='0') + dta_mixed_rate_8permil: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + pays_vat: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + pays_prevalidation: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + include_sagar_certificate_fee: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + fixed_vehicle_dta_fee: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + additional_fixed_fee: Mapped[int] = mapped_column(SmallInteger, default=0, server_default='0') + additional_fixed_fee_payment_method: Mapped[Optional[int]] = mapped_column(SmallInteger, nullable=True) pedimento: Mapped["Pedimentos"] = relationship( "Pedimentos", back_populates="pedimento_config_calculations" diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_parameters.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_parameters.py index 875d46d8..d53bf32b 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_parameters.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_parameters.py @@ -4,6 +4,7 @@ from typing import TYPE_CHECKING from api.v1.common.base_models import TenantScopedMixin, TimestampMixin from core.database import Base from sqlalchemy import ( + Boolean, ForeignKeyConstraint, Integer, Numeric, @@ -39,17 +40,17 @@ class PedimentoConfigParameters(Base, TenantScopedMixin, TimestampMixin): id: Mapped[int] = mapped_column(Integer) pedimento_id: Mapped[int] = mapped_column(Integer, nullable=False) - is_embassy: Mapped[int] = mapped_column(SmallInteger) - embassy_dta: Mapped[Decimal] = mapped_column(Numeric(11, 2)) - rule_3121_section_ii: Mapped[int] = mapped_column(SmallInteger) - use_previous_tariff: Mapped[int] = mapped_column(SmallInteger) - use_payment_date_fi: Mapped[int] = mapped_column(SmallInteger) - add_state_supplier_record_505: Mapped[int] = mapped_column(SmallInteger) - customs_value_calculation: Mapped[int] = mapped_column(SmallInteger) - two_decimals_unit_value: Mapped[int] = mapped_column(SmallInteger) - customs_value_per_item: Mapped[int] = mapped_column(SmallInteger) - is_national_supplier: Mapped[int] = mapped_column(SmallInteger) - is_consolidated: Mapped[int] = mapped_column(SmallInteger) + is_embassy: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + embassy_dta: Mapped[Decimal] = mapped_column(Numeric(11, 2), default=Decimal('0.00'), server_default='0.00') + rule_3121_section_ii: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + use_previous_tariff: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + use_payment_date_fi: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + add_state_supplier_record_505: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + customs_value_calculation: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + two_decimals_unit_value: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + customs_value_per_item: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + is_national_supplier: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + is_consolidated: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') pedimento: Mapped["Pedimentos"] = relationship( "Pedimentos", back_populates="pedimento_config_parameters" diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_update_rectification.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_update_rectification.py index a8ebe936..a6552902 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_update_rectification.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_update_rectification.py @@ -3,10 +3,10 @@ from typing import TYPE_CHECKING from api.v1.common.base_models import TenantScopedMixin, TimestampMixin from core.database import Base from sqlalchemy import ( + Boolean, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, - SmallInteger, UniqueConstraint, ) from sqlalchemy.orm import Mapped, mapped_column, relationship @@ -37,11 +37,12 @@ class PedimentoConfigUpdateRectification(Base, TenantScopedMixin, TimestampMixin id: Mapped[int] = mapped_column(Integer) pedimento_id: Mapped[int] = mapped_column(Integer, nullable=False) - update_vat: Mapped[int] = mapped_column(SmallInteger) - update_advalorem: Mapped[int] = mapped_column(SmallInteger) - update_cc: Mapped[int] = mapped_column(SmallInteger) - update_ieps: Mapped[int] = mapped_column(SmallInteger) - calculate_surcharge: Mapped[int] = mapped_column(SmallInteger) + update_vat: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + update_advalorem: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + update_dta: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + update_cc: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + update_ieps: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + calculate_surcharge: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') pedimento: Mapped["Pedimentos"] = relationship( "Pedimentos", back_populates="pedimento_config_update_rectification" diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_updates.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_updates.py index d652b699..0e1a5a79 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_updates.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_updates.py @@ -3,10 +3,10 @@ from typing import TYPE_CHECKING from api.v1.common.base_models import TenantScopedMixin, TimestampMixin from core.database import Base from sqlalchemy import ( + Boolean, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, - SmallInteger, UniqueConstraint, ) from sqlalchemy.orm import Mapped, mapped_column, relationship @@ -37,10 +37,11 @@ class PedimentoConfigUpdates(Base, TenantScopedMixin, TimestampMixin): id: Mapped[int] = mapped_column(Integer) pedimento_id: Mapped[int] = mapped_column(Integer, nullable=False) - update_vat: Mapped[int] = mapped_column(SmallInteger) - update_advalorem: Mapped[int] = mapped_column(SmallInteger) - update_cc: Mapped[int] = mapped_column(SmallInteger) - update_ieps: Mapped[int] = mapped_column(SmallInteger) + update_vat: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + update_advalorem: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + update_dta: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + update_cc: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') + update_ieps: Mapped[bool] = mapped_column(Boolean, default=False, server_default='false') pedimento: Mapped["Pedimentos"] = relationship( "Pedimentos", back_populates="pedimento_config_updates" diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimentos.py b/backend/api/v1/modules/a76/pedmientos/models/pedimentos.py index 3f414f1c..a7950792 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimentos.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimentos.py @@ -10,6 +10,7 @@ from sqlalchemy import ( Numeric, PrimaryKeyConstraint, String, + Text, UniqueConstraint, ) from sqlalchemy.orm import Mapped, mapped_column, relationship @@ -102,65 +103,67 @@ class Pedimentos(Base, TenantScopedMixin, TimestampMixin): pedimento_type: Mapped[str] = mapped_column(String(20)) pedimento_code: Mapped[str] = mapped_column(String(2)) regime: Mapped[str] = mapped_column(String(3)) - status: Mapped[str] = mapped_column(String(30)) + status: Mapped[Optional[str]] = mapped_column(String(30)) usd_value: Mapped[Optional[Decimal]] = mapped_column(Numeric(17, 6)) paid_price: Mapped[Optional[Decimal]] = mapped_column(Numeric(17, 6)) gross_weight: Mapped[Optional[Decimal]] = mapped_column(Numeric(19, 3)) exchange_rate: Mapped[Optional[Decimal]] = mapped_column(Numeric(9, 5)) + observations: Mapped[Optional[str]] = mapped_column(Text) pedimento_config_additional: Mapped["PedimentoConfigAdditional"] = relationship( - "PedimentoConfigAdditional", uselist=False, back_populates="pedimento" + "PedimentoConfigAdditional", uselist=False, back_populates="pedimento", cascade="all, delete-orphan" ) pedimento_config_calculations: Mapped["PedimentoConfigCalculations"] = relationship( - "PedimentoConfigCalculations", uselist=False, back_populates="pedimento" + "PedimentoConfigCalculations", uselist=False, back_populates="pedimento", cascade="all, delete-orphan" ) pedimento_config_parameters: Mapped["PedimentoConfigParameters"] = relationship( - "PedimentoConfigParameters", uselist=False, back_populates="pedimento" + "PedimentoConfigParameters", uselist=False, back_populates="pedimento", cascade="all, delete-orphan" ) pedimento_config_surcharges: Mapped["PedimentoConfigSurcharges"] = relationship( - "PedimentoConfigSurcharges", uselist=False, back_populates="pedimento" + "PedimentoConfigSurcharges", uselist=False, back_populates="pedimento", cascade="all, delete-orphan" ) pedimento_config_update_rectification: Mapped[ "PedimentoConfigUpdateRectification" ] = relationship( - "PedimentoConfigUpdateRectification", uselist=False, back_populates="pedimento" + "PedimentoConfigUpdateRectification", uselist=False, back_populates="pedimento", cascade="all, delete-orphan" ) pedimento_config_updates: Mapped["PedimentoConfigUpdates"] = relationship( - "PedimentoConfigUpdates", uselist=False, back_populates="pedimento" + "PedimentoConfigUpdates", uselist=False, back_populates="pedimento", cascade="all, delete-orphan" ) pedimento_customs_offices: Mapped["PedimentoCustomsOffices"] = relationship( - "PedimentoCustomsOffices", uselist=False, back_populates="pedimento" + "PedimentoCustomsOffices", uselist=False, back_populates="pedimento", cascade="all, delete-orphan" ) pedimento_dates: Mapped["PedimentoDates"] = relationship( - "PedimentoDates", uselist=False, back_populates="pedimento" + "PedimentoDates", uselist=False, back_populates="pedimento", cascade="all, delete-orphan" ) pedimento_decrementables: Mapped["PedimentoDecrementables"] = relationship( - "PedimentoDecrementables", uselist=False, back_populates="pedimento" + "PedimentoDecrementables", uselist=False, back_populates="pedimento", cascade="all, delete-orphan" ) pedimento_incrementables: Mapped["PedimentoIncrementables"] = relationship( - "PedimentoIncrementables", uselist=False, back_populates="pedimento" + "PedimentoIncrementables", uselist=False, back_populates="pedimento", cascade="all, delete-orphan" ) pedimento_indexes: Mapped["PedimentoIndexes"] = relationship( - "PedimentoIndexes", uselist=False, back_populates="pedimento" + "PedimentoIndexes", uselist=False, back_populates="pedimento", cascade="all, delete-orphan" ) pedimento_payments: Mapped["PedimentoPayments"] = relationship( - "PedimentoPayments", uselist=False, back_populates="pedimento" + "PedimentoPayments", uselist=False, back_populates="pedimento", cascade="all, delete-orphan" ) pedimento_rectification_destination: Mapped["PedimentoRectificationDestination"] = ( relationship( "PedimentoRectificationDestination", uselist=False, back_populates="pedimento", + cascade="all, delete-orphan" ) ) pedimento_rectification_origin: Mapped["PedimentoRectificationOrigin"] = ( relationship( - "PedimentoRectificationOrigin", uselist=False, back_populates="pedimento" + "PedimentoRectificationOrigin", uselist=False, back_populates="pedimento", cascade="all, delete-orphan" ) ) pedimento_transport_means: Mapped["PedimentoTransportMeans"] = relationship( - "PedimentoTransportMeans", uselist=False, back_populates="pedimento" + "PedimentoTransportMeans", uselist=False, back_populates="pedimento", cascade="all, delete-orphan" ) pedimento_validation: Mapped["PedimentoValidation"] = relationship( - "PedimentoValidation", uselist=False, back_populates="pedimento" + "PedimentoValidation", uselist=False, back_populates="pedimento", cascade="all, delete-orphan" ) diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_parameters.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_parameters.py index b3a7fab5..321836c0 100644 --- a/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_parameters.py +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_parameters.py @@ -18,7 +18,7 @@ class PedimentoConfigParametersService: @staticmethod def get_by_pedimento_id( - db: Session, pedimento_id: int, tenant_id: int + db: Session, pedimento_id: int, tenant_id: int, company_id: int = None ) -> Optional[PedimentoConfigParameters]: """Get config by pedimento ID""" return ( diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_surcharges.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_surcharges.py index 95f15752..a1f13e17 100644 --- a/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_surcharges.py +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_surcharges.py @@ -18,7 +18,7 @@ class PedimentoConfigSurchargesService: @staticmethod def get_by_pedimento_id( - db: Session, pedimento_id: int, tenant_id: int + db: Session, pedimento_id: int, tenant_id: int, company_id: int = None ) -> Optional[PedimentoConfigSurcharges]: """Get config by pedimento ID""" return ( diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_update_rectification.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_update_rectification.py index 27fb724a..65f0360f 100644 --- a/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_update_rectification.py +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_update_rectification.py @@ -20,7 +20,7 @@ class PedimentoConfigUpdateRectificationService: @staticmethod def get_by_pedimento_id( - db: Session, pedimento_id: int, tenant_id: int + db: Session, pedimento_id: int, tenant_id: int, company_id: int = None ) -> Optional[PedimentoConfigUpdateRectification]: """Get config by pedimento ID""" return ( diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_updates.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_updates.py index b602f8f6..562a4a3e 100644 --- a/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_updates.py +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_updates.py @@ -18,7 +18,7 @@ class PedimentoConfigUpdatesService: @staticmethod def get_by_pedimento_id( - db: Session, pedimento_id: int, tenant_id: int + db: Session, pedimento_id: int, tenant_id: int, company_id: int = None ) -> Optional[PedimentoConfigUpdates]: """Get config by pedimento ID""" return ( diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_customs_offices.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_customs_offices.py index 8f8db39e..1cb07a17 100644 --- a/backend/api/v1/modules/a76/pedmientos/services/pedimento_customs_offices.py +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_customs_offices.py @@ -18,7 +18,7 @@ class PedimentoCustomsOfficesService: @staticmethod def get_by_pedimento_id( - db: Session, pedimento_id: int, tenant_id: int + db: Session, pedimento_id: int, tenant_id: int, company_id: int = None ) -> Optional[PedimentoCustomsOffices]: """Get customs offices by pedimento ID""" return ( diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_dates.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_dates.py index 59e6c75a..1736ea2a 100644 --- a/backend/api/v1/modules/a76/pedmientos/services/pedimento_dates.py +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_dates.py @@ -18,7 +18,7 @@ class PedimentoDatesService: @staticmethod def get_by_pedimento_id( - db: Session, pedimento_id: int, tenant_id: int + db: Session, pedimento_id: int, tenant_id: int, company_id: int = None ) -> Optional[PedimentoDates]: """Get dates by pedimento ID""" return ( diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_decrementables.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_decrementables.py index 73b7d690..c7855ea8 100644 --- a/backend/api/v1/modules/a76/pedmientos/services/pedimento_decrementables.py +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_decrementables.py @@ -18,7 +18,7 @@ class PedimentoDecrementablesService: @staticmethod def get_by_pedimento_id( - db: Session, pedimento_id: int, tenant_id: int + db: Session, pedimento_id: int, tenant_id: int, company_id: int = None ) -> Optional[PedimentoDecrementables]: """Get decrementables by pedimento ID""" return ( diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_incrementables.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_incrementables.py index 2cdffadc..9125d295 100644 --- a/backend/api/v1/modules/a76/pedmientos/services/pedimento_incrementables.py +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_incrementables.py @@ -18,7 +18,7 @@ class PedimentoIncrementablesService: @staticmethod def get_by_pedimento_id( - db: Session, pedimento_id: int, tenant_id: int + db: Session, pedimento_id: int, tenant_id: int, company_id: int = None ) -> Optional[PedimentoIncrementables]: """Get incrementables by pedimento ID""" return ( diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_indexes.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_indexes.py index f671a27c..2bce8ed0 100644 --- a/backend/api/v1/modules/a76/pedmientos/services/pedimento_indexes.py +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_indexes.py @@ -15,7 +15,7 @@ class PedimentoIndexesService: @staticmethod def get_by_pedimento_id( - db: Session, pedimento_id: int, tenant_id: int + db: Session, pedimento_id: int, tenant_id: int, company_id: int = None ) -> Optional[PedimentoIndexes]: """Get indexes by pedimento ID""" return ( diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_payments.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_payments.py index 1b56e2b9..a4b8539b 100644 --- a/backend/api/v1/modules/a76/pedmientos/services/pedimento_payments.py +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_payments.py @@ -15,7 +15,7 @@ class PedimentoPaymentsService: @staticmethod def get_by_pedimento_id( - db: Session, pedimento_id: int, tenant_id: int + db: Session, pedimento_id: int, tenant_id: int, company_id: int = None ) -> Optional[PedimentoPayments]: """Get payments by pedimento ID""" return ( diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_rectification_destination.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_rectification_destination.py index de32adfc..b6538b9c 100644 --- a/backend/api/v1/modules/a76/pedmientos/services/pedimento_rectification_destination.py +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_rectification_destination.py @@ -20,7 +20,7 @@ class PedimentoRectificationDestinationService: @staticmethod def get_by_pedimento_id( - db: Session, pedimento_id: int, tenant_id: int + db: Session, pedimento_id: int, tenant_id: int, company_id: int = None ) -> Optional[PedimentoRectificationDestination]: """Get rectification destination by pedimento ID""" return ( diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_rectification_origin.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_rectification_origin.py index 080bec9f..b92db00e 100644 --- a/backend/api/v1/modules/a76/pedmientos/services/pedimento_rectification_origin.py +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_rectification_origin.py @@ -18,7 +18,7 @@ class PedimentoRectificationOriginService: @staticmethod def get_by_pedimento_id( - db: Session, pedimento_id: int, tenant_id: int + db: Session, pedimento_id: int, tenant_id: int, company_id: int = None ) -> Optional[PedimentoRectificationOrigin]: """Get rectification origin by pedimento ID""" return ( diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_transport_means.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_transport_means.py index ae88a3d1..0c6c5e3a 100644 --- a/backend/api/v1/modules/a76/pedmientos/services/pedimento_transport_means.py +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_transport_means.py @@ -18,7 +18,7 @@ class PedimentoTransportMeansService: @staticmethod def get_by_pedimento_id( - db: Session, pedimento_id: int, tenant_id: int + db: Session, pedimento_id: int, tenant_id: int, company_id: int = None ) -> Optional[PedimentoTransportMeans]: """Get transport means by pedimento ID""" return ( diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_validation.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_validation.py index ecb17148..ceea59e2 100644 --- a/backend/api/v1/modules/a76/pedmientos/services/pedimento_validation.py +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_validation.py @@ -18,7 +18,7 @@ class PedimentoValidationService: @staticmethod def get_by_pedimento_id( - db: Session, pedimento_id: int, tenant_id: int + db: Session, pedimento_id: int, tenant_id: int, company_id: int = None ) -> Optional[PedimentoValidation]: """Get validation by pedimento ID""" return ( diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimentos.py b/backend/api/v1/modules/a76/pedmientos/services/pedimentos.py index d6506226..89f4e91c 100644 --- a/backend/api/v1/modules/a76/pedmientos/services/pedimentos.py +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimentos.py @@ -8,6 +8,7 @@ from typing import Any, Dict, List, Optional from sqlalchemy import desc from sqlalchemy.orm import Session, joinedload from sqlalchemy.orm import selectinload +from sqlalchemy.exc import IntegrityError from datetime import datetime from ..dtos.pedimentos import PedimentosCreate, PedimentosUpdate @@ -222,10 +223,15 @@ class PedimentosService: 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 - obj_dict = data.model_dump() if data else {} + obj_dict = data.model_dump(exclude_none=True) if data else {} # Agregar campos extra si se proporcionan if extra_fields: obj_dict.update(extra_fields) + # Solo crear si hay datos significativos (más que solo IDs) + significant_fields = {k: v for k, v in obj_dict.items() + if k not in ('pedimento_id', 'tenant_id', 'company_id') and v is not None} + if not significant_fields and not extra_fields: + return obj = model_class(**obj_dict) obj.pedimento_id = pedimento.id obj.tenant_id = tenant_id @@ -272,6 +278,15 @@ class PedimentosService: db.refresh(pedimento) return pedimento + except IntegrityError as e: + db.rollback() + # Detectar si es un error de pedimento duplicado + error_msg = str(e.orig) + if 'pedimentos_unique_key' in error_msg or 'duplicate key value violates unique constraint' in error_msg: + logger.warning(f"Attempted to create duplicate pedimento: {e}") + raise ValueError("Ya existe un pedimento con estos datos (Año, Aduana, Patente, Número)") + logger.error(f"Integrity error creating pedimento: {e}") + raise except Exception as e: db.rollback() logger.error(f"Error creating pedimento with related data: {e}") @@ -329,11 +344,11 @@ class PedimentosService: return existing = service_class.get_by_pedimento_id( - db, pedimento_id, tenant_id) + db, pedimento_id, tenant_id, company_id) if existing: - # Actualizar existente + # Actualizar existente (excluir pedimento_id, tenant_id, company_id) for field, value in data.items(): - if hasattr(existing, field): + if hasattr(existing, field) and field not in ('pedimento_id', 'tenant_id', 'company_id'): setattr(existing, field, value) else: # Crear nuevo @@ -381,6 +396,15 @@ class PedimentosService: db.refresh(pedimento) return pedimento + except IntegrityError as e: + db.rollback() + # Detectar si es un error de pedimento duplicado + error_msg = str(e.orig) + if 'pedimentos_unique_key' in error_msg or 'duplicate key value violates unique constraint' in error_msg: + logger.warning(f"Attempted to update to duplicate pedimento: {e}") + raise ValueError("Ya existe otro pedimento con estos datos (Año, Aduana, Patente, Número)") + logger.error(f"Integrity error updating pedimento: {e}") + raise except Exception as e: db.rollback() logger.error(f"Error updating pedimento with related data: {e}") diff --git a/frontend/src/hooks.ts b/frontend/src/hooks.ts index e75600b3..3b0e6d0b 100644 --- a/frontend/src/hooks.ts +++ b/frontend/src/hooks.ts @@ -1,3 +1,4 @@ import { deLocalizeUrl } from '$lib/paraglide/runtime'; +import type { RequestEvent } from '@sveltejs/kit'; -export const reroute = (request) => deLocalizeUrl(request.url).pathname; +export const reroute = (request: { url: string }) => deLocalizeUrl(request.url).pathname; diff --git a/frontend/src/lib/api/dashboard/a76/exchange-rate.ts b/frontend/src/lib/api/dashboard/a76/exchange-rate.ts index 81b14e90..690d3e9c 100644 --- a/frontend/src/lib/api/dashboard/a76/exchange-rate.ts +++ b/frontend/src/lib/api/dashboard/a76/exchange-rate.ts @@ -26,23 +26,32 @@ export interface ExchangeRateListResponse { */ export async function getExchangeRateByDate(date: string, companyId: number): Promise { try { + console.log('📡 [API] Solicitando tipos de cambio para company_id:', companyId); // Get all exchange rates and filter by date on client side const response = await api.get(`/v1/a76/exchange-rate/?company_id=${companyId}`); + console.log('📡 [API] Respuesta recibida:', response.data?.total, 'tipos de cambio'); + if (response.data && response.data.items && response.data.items.length > 0) { // Filter by date and find USD exchange rate const dateOnly = date.split('T')[0]; // Get YYYY-MM-DD part + console.log('🔍 [API] Buscando fecha:', dateOnly, 'en', response.data.items.length, 'registros'); + const matchingRates = response.data.items.filter(rate => { const rateDate = rate.date.split('T')[0]; - return rateDate === dateOnly && rate.foreign_currency === 'USD'; + const matches = rateDate === dateOnly && rate.foreign_currency === 'USD'; + console.log(' - Comparando:', rateDate, '===', dateOnly, '&& USD ===', rate.foreign_currency, '→', matches); + return matches; }); + console.log('✅ [API] Encontrados', matchingRates.length, 'tipos de cambio que coinciden'); return matchingRates.length > 0 ? matchingRates[0] : null; } + console.log('⚠️ [API] No hay datos en la respuesta'); return null; } catch (error) { - console.error('Error fetching exchange rate:', error); + console.error('❌ [API] Error fetching exchange rate:', error); return null; } } diff --git a/frontend/src/lib/api/dashboard/a76/pedimentos.ts b/frontend/src/lib/api/dashboard/a76/pedimentos.ts index fea0001e..e80c24d5 100644 --- a/frontend/src/lib/api/dashboard/a76/pedimentos.ts +++ b/frontend/src/lib/api/dashboard/a76/pedimentos.ts @@ -56,8 +56,8 @@ export interface PedimentoIncrementables { freight?: number | null; deductibles?: number | null; currency?: string | null; - not_affect_usd_value?: number | null; - not_affect_customs_value?: number | null; + not_affect_usd_value?: boolean | null; + not_affect_customs_value?: boolean | null; } export interface PedimentoDecrementables { @@ -67,22 +67,86 @@ export interface PedimentoDecrementables { unloading?: number | null; others?: number | null; currency?: string | null; - not_affect_usd_value?: number | null; + not_affect_usd_value?: boolean | null; } export interface PedimentoIndexes { update_factor_type?: number | null; update_factor?: number | null; - manual_update_factor?: number | null; + manual_update_factor?: boolean | null; } export interface PedimentoConfigAdditional { manual_pedimento_year?: string | null; - add_po_identifier?: number | null; - do_not_exempt_norms_complement_x?: number | null; - enable_import_invoice_recipient?: number | null; - send_502_validation_file_for_consolidated?: number | null; - add_remove_norms?: number | null; + add_po_identifier?: boolean | null; + do_not_exempt_norms_complement_x?: boolean | null; + enable_import_invoice_recipient?: boolean | null; + send_502_validation_file_for_consolidated?: boolean | null; + add_remove_norms?: boolean | null; +} + +export interface PedimentoConfigCalculations { + dta_type?: string | null; + dta_operation?: boolean | null; + dta_vehicle_count?: boolean | null; + dta_mixed_rate_8permil?: boolean | null; + pays_vat?: boolean | null; + pays_prevalidation?: boolean | null; + include_sagar_certificate_fee?: boolean | null; + fixed_vehicle_dta_fee?: boolean | null; + additional_fixed_fee?: number | null; + additional_fixed_fee_payment_method?: number | null; +} + +export interface PedimentoConfigSurcharges { + surcharge_igi?: boolean | null; + surcharge_dta?: boolean | null; + surcharge_vat?: boolean | null; + surcharge_isan?: boolean | null; + surcharge_ieps?: boolean | null; + surcharge_cc?: boolean | null; +} + +export interface PedimentoConfigParameters { + is_embassy?: boolean | null; + embassy_dta?: string | null; + rule_3121_section_ii?: boolean | null; + use_previous_tariff?: boolean | null; + use_payment_date_fi?: boolean | null; + add_state_supplier_record_505?: boolean | null; + customs_value_calculation?: boolean | null; + two_decimals_unit_value?: boolean | null; + customs_value_per_item?: boolean | null; + is_national_supplier?: boolean | null; + is_consolidated?: boolean | null; +} + +export interface PedimentoConfigUpdates { + update_vat?: boolean | null; + update_advalorem?: boolean | null; + update_dta?: boolean | null; + update_cc?: boolean | null; + update_ieps?: boolean | null; +} + +export interface PedimentoConfigUpdateRectification { + update_vat?: boolean | null; + update_advalorem?: boolean | null; + update_dta?: boolean | null; + update_cc?: boolean | null; + update_ieps?: boolean | null; + calculate_surcharge?: boolean | null; +} + +export interface Identificador { + id?: number; + pedimento_id?: number; + caso: string; + complemento1: string; + complemento2: string; + complemento3: string; + nodo: string; + observaciones: string; } export interface Pedimento { @@ -102,7 +166,7 @@ export interface Pedimento { paid_price?: number | null; gross_weight?: number | null; exchange_rate?: number | null; - observaciones?: string | null; + observations?: string | null; created_at: string; // Sub-resources pedimento_dates?: PedimentoDates | null; @@ -113,6 +177,12 @@ export interface Pedimento { pedimento_decrementables?: PedimentoDecrementables | null; pedimento_indexes?: PedimentoIndexes | null; pedimento_config_additional?: PedimentoConfigAdditional | null; + pedimento_config_calculations?: PedimentoConfigCalculations | null; + pedimento_config_surcharges?: PedimentoConfigSurcharges | null; + pedimento_config_parameters?: PedimentoConfigParameters | null; + pedimento_config_updates?: PedimentoConfigUpdates | null; + pedimento_config_update_rectification?: PedimentoConfigUpdateRectification | null; + identificadores?: Identificador[] | null; } export interface PedimentoListResponse { @@ -137,7 +207,7 @@ export interface CreatePedimentoData { paid_price?: number | null; gross_weight?: number | null; exchange_rate?: number | null; - observaciones?: string | null; + observations?: string | null; // Sub-resources pedimento_dates?: PedimentoDates | null; pedimento_payments?: PedimentoPayments | null; @@ -147,6 +217,12 @@ export interface CreatePedimentoData { pedimento_decrementables?: PedimentoDecrementables | null; pedimento_indexes?: PedimentoIndexes | null; pedimento_config_additional?: PedimentoConfigAdditional | null; + pedimento_config_calculations?: PedimentoConfigCalculations | null; + pedimento_config_surcharges?: PedimentoConfigSurcharges | null; + pedimento_config_parameters?: PedimentoConfigParameters | null; + pedimento_config_updates?: PedimentoConfigUpdates | null; + pedimento_config_update_rectification?: PedimentoConfigUpdateRectification | null; + identificadores?: Identificador[] | null; } export interface UpdatePedimentoData { @@ -164,7 +240,7 @@ export interface UpdatePedimentoData { paid_price?: number | null; gross_weight?: number | null; exchange_rate?: number | null; - observaciones?: string | null; + observations?: string | null; // Sub-resources pedimento_dates?: PedimentoDates | null; pedimento_payments?: PedimentoPayments | null; @@ -174,6 +250,12 @@ export interface UpdatePedimentoData { pedimento_decrementables?: PedimentoDecrementables | null; pedimento_indexes?: PedimentoIndexes | null; pedimento_config_additional?: PedimentoConfigAdditional | null; + pedimento_config_calculations?: PedimentoConfigCalculations | null; + pedimento_config_surcharges?: PedimentoConfigSurcharges | null; + pedimento_config_parameters?: PedimentoConfigParameters | null; + pedimento_config_updates?: PedimentoConfigUpdates | null; + pedimento_config_update_rectification?: PedimentoConfigUpdateRectification | null; + identificadores?: Identificador[] | null; } export interface PedimentoFilters { diff --git a/frontend/src/lib/components/dashboard/pedimentos/columns.ts b/frontend/src/lib/components/dashboard/pedimentos/columns.ts index 4c4bb93e..340ea641 100644 --- a/frontend/src/lib/components/dashboard/pedimentos/columns.ts +++ b/frontend/src/lib/components/dashboard/pedimentos/columns.ts @@ -2,26 +2,7 @@ import type { ColumnDef } from "@tanstack/table-core"; import { renderComponent, renderSnippet } from "$lib/components/ui/data-table/index.js"; import { createRawSnippet } from "svelte"; import DataTableActions from "./data-table-actions.svelte"; - -export type Pedimento = { - id: number; - tenant_id: number; - year?: string | null; - customs_office?: string | null; - license?: string | null; - pedimento_number?: string | null; - client_id?: number | null; - operation_type?: number | null; - pedimento_type?: number | null; - pedimento_code?: string | null; - regime?: string | null; - status?: string | null; - usd_value?: number | null; - paid_price?: number | null; - gross_weight?: number | null; - exchange_rate?: number | null; - created_at: string; -}; +import type { Pedimento } from "$lib/api/dashboard/a76/pedimentos"; /** * Formatea un número como moneda diff --git a/frontend/src/lib/components/dashboard/pedimentos/data-table-actions.svelte b/frontend/src/lib/components/dashboard/pedimentos/data-table-actions.svelte index 1aa00270..f8a13e0a 100644 --- a/frontend/src/lib/components/dashboard/pedimentos/data-table-actions.svelte +++ b/frontend/src/lib/components/dashboard/pedimentos/data-table-actions.svelte @@ -2,6 +2,7 @@ import { Button } from "$lib/components/ui/button"; import * as DropdownMenu from "$lib/components/ui/dropdown-menu"; import { pedimentosApi, type Pedimento } from "$lib/api/dashboard/a76/pedimentos"; + import { companyStore } from "$lib/stores/company.svelte"; import { EllipsisVertical, Pencil, LoaderCircle, Trash2 } from 'lucide-svelte'; let { @@ -24,7 +25,8 @@ error = null; try { - const response = await pedimentosApi.delete(item.id); + const companyId = companyStore.activeCompany?.id; + const response = await pedimentosApi.delete(item.id, companyId); if (response.error) { if (response.status === 401) { diff --git a/frontend/src/lib/components/dashboard/pedimentos/edit/cuentas-compensacion-tab-form.svelte b/frontend/src/lib/components/dashboard/pedimentos/edit/accounts-compensation-tab-form.svelte similarity index 100% rename from frontend/src/lib/components/dashboard/pedimentos/edit/cuentas-compensacion-tab-form.svelte rename to frontend/src/lib/components/dashboard/pedimentos/edit/accounts-compensation-tab-form.svelte diff --git a/frontend/src/lib/components/dashboard/pedimentos/edit/contribuciones-tab-form.svelte b/frontend/src/lib/components/dashboard/pedimentos/edit/contributions-tab-form.svelte similarity index 99% rename from frontend/src/lib/components/dashboard/pedimentos/edit/contribuciones-tab-form.svelte rename to frontend/src/lib/components/dashboard/pedimentos/edit/contributions-tab-form.svelte index b781de36..8cbce24e 100644 --- a/frontend/src/lib/components/dashboard/pedimentos/edit/contribuciones-tab-form.svelte +++ b/frontend/src/lib/components/dashboard/pedimentos/edit/contributions-tab-form.svelte @@ -19,7 +19,7 @@ DialogTitle, DialogFooter } from '$lib/components/ui/dialog'; - import Checkbox from '$lib/components/ui/checkbox/checkbox.svelte'; + import { Checkbox } from '$lib/components/ui/checkbox'; import { Plus, Pencil, diff --git a/frontend/src/lib/components/dashboard/pedimentos/edit/dates-tab-form.svelte b/frontend/src/lib/components/dashboard/pedimentos/edit/dates-tab-form.svelte index 070c664b..2e52e1ce 100644 --- a/frontend/src/lib/components/dashboard/pedimentos/edit/dates-tab-form.svelte +++ b/frontend/src/lib/components/dashboard/pedimentos/edit/dates-tab-form.svelte @@ -17,14 +17,27 @@ pedimentoNumber?: string; } = $props(); - // Inicializar formData - if (!formData) { - formData = { - observaciones: pedimento?.observaciones || '' - }; - } - - exists = !!pedimento?.observaciones; + // Asegurar que formData siempre tenga un valor por defecto + formData = formData || { observaciones: '' }; + + // Variable para rastrear el último valor del servidor + let lastServerObservations = $state(null); + + // Actualizar formData solo cuando el pedimento cambie desde el servidor + $effect(() => { + const currentObservations = pedimento?.observations ?? null; + console.log('🔄 Pedimento changed in dates-tab-form:', currentObservations); + + // Solo actualizar si el valor del servidor cambió realmente + if (currentObservations !== lastServerObservations) { + lastServerObservations = currentObservations; + formData = { + observaciones: currentObservations || '' + }; + exists = !!currentObservations; + console.log('✅ Updated formData.observaciones:', formData.observaciones); + } + }); // Mapear el tipo de pedimento a un nombre legible const tipoPedimentoNombre = $derived.by(() => { diff --git a/frontend/src/lib/components/dashboard/pedimentos/edit/digitalizacion-tab-form.svelte b/frontend/src/lib/components/dashboard/pedimentos/edit/digitization-tab-form.svelte similarity index 100% rename from frontend/src/lib/components/dashboard/pedimentos/edit/digitalizacion-tab-form.svelte rename to frontend/src/lib/components/dashboard/pedimentos/edit/digitization-tab-form.svelte diff --git a/frontend/src/lib/components/dashboard/pedimentos/edit/descargas-tab-form.svelte b/frontend/src/lib/components/dashboard/pedimentos/edit/discharge-tab-form.svelte similarity index 100% rename from frontend/src/lib/components/dashboard/pedimentos/edit/descargas-tab-form.svelte rename to frontend/src/lib/components/dashboard/pedimentos/edit/discharge-tab-form.svelte 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 74c29207..c5d7d51d 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 @@ -11,10 +11,12 @@ import type { CustomsBroker } from '$lib/api/dashboard/a76/customs-brokers'; import type { ClientProvider } from '$lib/api/dashboard/a76/clients-providers'; import type { CodePedimentoRegimen } from '$lib/api/dashboard/refrence_data/code_pedimento_regimens'; + import IdentificadoresTabForm from './identifiers-tab-form.svelte'; let { pedimento, formData = $bindable(), + identificadoresFormData = $bindable(), pedimentoCodes = [], customsSections = [], customsBrokers = [], @@ -23,6 +25,7 @@ }: { pedimento: Pedimento | null; formData?: any; + identificadoresFormData?: any; pedimentoCodes?: PedimentoCode[]; customsSections?: CustomsSection[]; customsBrokers?: CustomsBroker[]; @@ -249,19 +252,23 @@ // Obtener automáticamente el tipo de cambio cuando cambie la fecha de entrada $effect(() => { if (formData && formData.entry_date && companyStore.activeCompany) { - console.log('Buscando tipo de cambio para fecha:', formData.entry_date); + console.log('🔍 [TIPO CAMBIO] Buscando para fecha:', formData.entry_date, 'Company ID:', companyStore.activeCompany.id); getExchangeRateByDate(formData.entry_date, companyStore.activeCompany.id) .then(usdRate => { - console.log('Tipo de cambio USD encontrado:', usdRate); + console.log('✅ [TIPO CAMBIO] Respuesta recibida:', usdRate); if (usdRate && formData) { formData.exchange_rate = usdRate.value; - console.log('Tipo de cambio actualizado a:', usdRate.value); + console.log('✅ [TIPO CAMBIO] Actualizado a:', usdRate.value); } else { - console.warn('No se encontró tipo de cambio USD para la fecha:', formData.entry_date); + console.warn('⚠️ [TIPO CAMBIO] No encontrado para fecha:', formData.entry_date); } }) - .catch(err => console.error('Error al obtener tipo de cambio:', err)); + .catch(err => { + console.error('❌ [TIPO CAMBIO] Error:', err); + }); + } else { + console.log('⏭️ [TIPO CAMBIO] Saltado - formData:', !!formData, 'entry_date:', formData?.entry_date, 'company:', !!companyStore.activeCompany); } }); @@ -417,10 +424,9 @@ {:else if activeSection === 'identificadores'} -
-

Campos de Identificadores - Por configurar

-
+ {:else if activeSection === 'indices'}
diff --git a/frontend/src/lib/components/dashboard/pedimentos/edit/identifiers-tab-form.svelte b/frontend/src/lib/components/dashboard/pedimentos/edit/identifiers-tab-form.svelte new file mode 100644 index 00000000..19463d1c --- /dev/null +++ b/frontend/src/lib/components/dashboard/pedimentos/edit/identifiers-tab-form.svelte @@ -0,0 +1,174 @@ + + + +
+
+

Identificadores

+ +
+ + {#if formData.identificadores.length === 0} +

+ No hay identificadores registrados +

+ {:else} + + + + Caso + Complemento 1 + Complemento 2 + Complemento 3 + Nodo + Observaciones + Acciones + + + + {#each formData.identificadores as identificador, index} + + {identificador.caso} + {identificador.complemento1} + {identificador.complemento2} + {identificador.complemento3} + {identificador.nodo} + {identificador.observaciones} + +
+ + +
+
+
+ {/each} +
+
+ {/if} +
+
+ + + + + + + {editingIdentificadorIndex !== null ? 'Editar' : 'Nuevo'} Identificador + + + +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +