Merge pull request 'pedimentos' (#36) from pedimentos into development

Reviewed-on: ADUANASOFT/anexo76#36
This commit is contained in:
2025-12-31 14:24:57 +00:00
58 changed files with 941 additions and 362 deletions

View File

@@ -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

View File

@@ -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")

View File

@@ -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(

View File

@@ -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):

View File

@@ -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

View File

@@ -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):

View File

@@ -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):

View File

@@ -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(

View File

@@ -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"""

View File

@@ -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"
)

View File

@@ -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

View File

@@ -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):

View File

@@ -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):

View File

@@ -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):

View File

@@ -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"
)

View File

@@ -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"
)

View File

@@ -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"
)

View File

@@ -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")

View File

@@ -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"

View File

@@ -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

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"
)

View File

@@ -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 (

View File

@@ -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 (

View File

@@ -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 (

View File

@@ -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 (

View File

@@ -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 (

View File

@@ -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 (

View File

@@ -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 (

View File

@@ -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 (

View File

@@ -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 (

View File

@@ -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 (

View File

@@ -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 (

View File

@@ -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 (

View File

@@ -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 (

View File

@@ -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 (

View File

@@ -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}")