From ef3924a41d4f36d26845fb3049d2e9602d9df770 Mon Sep 17 00:00:00 2001 From: acazares Date: Fri, 7 Nov 2025 12:17:26 -0600 Subject: [PATCH] Refactor models and services in A76 module - Updated GBultoService to use models.Package instead of models.GBulto. - Refactored Part model to use SQLAlchemy 2.0 style with Mapped and mapped_column. - Added timestamps (created_at, updated_at, deleted_at) to various pedimento models. - Improved relationships and foreign key constraints in pedimento models. - Updated PermissionRuleOct and Seal models to use Mapped and mapped_column. - Changed DTO configuration from orm_mode to from_attributes for better compatibility. - Removed obsolete models (models.py and models_ped.py) from the repository. --- backend/api/v1/modules/a76/classes/models.py | 55 ++++--- .../modules/a76/client_and_provider/models.py | 147 ++++++++++-------- backend/api/v1/modules/a76/company/models.py | 80 +++++----- .../v1/modules/a76/country_rule_oct/dto.py | 2 +- .../v1/modules/a76/country_rule_oct/models.py | 28 +++- .../api/v1/modules/a76/exchange_rate/dto.py | 2 +- .../v1/modules/a76/exchange_rate/models.py | 23 ++- .../modules/a76/fraction_rule_octave/dto.py | 10 +- .../a76/fraction_rule_octave/models.py | 22 ++- .../a76/fraction_rule_octave/routes.py | 34 ++-- .../a76/fraction_rule_octave/services.py | 18 +-- backend/api/v1/modules/a76/licenses/models.py | 12 +- backend/api/v1/modules/a76/package/dto.py | 2 +- backend/api/v1/modules/a76/package/models.py | 47 ++++-- backend/api/v1/modules/a76/package/routes.py | 20 +-- .../api/v1/modules/a76/package/services.py | 4 +- backend/api/v1/modules/a76/parts/models.py | 98 ++++++------ .../models/pedimento_config_additional.py | 14 +- .../models/pedimento_config_calculations.py | 13 +- .../models/pedimento_config_parameters.py | 13 +- .../models/pedimento_config_surcharges.py | 13 +- .../pedimento_config_update_rectification.py | 13 +- .../models/pedimento_config_updates.py | 13 +- .../models/pedimento_customs_offices.py | 13 +- .../a76/pedmientos/models/pedimento_dates.py | 13 +- .../models/pedimento_decrementables.py | 13 +- .../models/pedimento_incrementables.py | 13 +- .../pedmientos/models/pedimento_indexes.py | 13 +- .../pedmientos/models/pedimento_payments.py | 13 +- .../pedimento_rectification_destination.py | 4 + .../models/pedimento_rectification_origin.py | 4 + .../models/pedimento_transport_means.py | 4 + .../pedmientos/models/pedimento_validation.py | 13 +- .../a76/pedmientos/models/pedimentos.py | 28 +++- .../v1/modules/a76/permission_rule_oct/dto.py | 2 +- .../modules/a76/permission_rule_oct/models.py | 26 ++-- backend/api/v1/modules/a76/seal/dto.py | 2 +- backend/api/v1/modules/a76/seal/models.py | 18 ++- backend/api/v1/modules/a76/tenants/models.py | 7 +- models.py | 0 models_ped.py | 27 ---- 41 files changed, 565 insertions(+), 331 deletions(-) delete mode 100644 models.py delete mode 100644 models_ped.py diff --git a/backend/api/v1/modules/a76/classes/models.py b/backend/api/v1/modules/a76/classes/models.py index 9cd42b53..1257cf53 100644 --- a/backend/api/v1/modules/a76/classes/models.py +++ b/backend/api/v1/modules/a76/classes/models.py @@ -1,14 +1,10 @@ """ Modelos ORM para gestión de clases SCAII y SCAF """ -from sqlalchemy import Column, Integer, String, DateTime, Boolean, Text, Numeric, SmallInteger, ForeignKey -from sqlalchemy.sql import func -from sqlalchemy.orm import relationship +from typing import TYPE_CHECKING, Optional +from sqlalchemy import Integer, String, SmallInteger, ForeignKey, PrimaryKeyConstraint, ForeignKeyConstraint, UniqueConstraint +from sqlalchemy.orm import Mapped, mapped_column, relationship from core.database import Base -import enum - -# Importar modelos relacionados para type hints y relationships -from typing import TYPE_CHECKING, List, Optional if TYPE_CHECKING: from api.v1.modules.a76.parts.models import Part @@ -20,42 +16,51 @@ class Class(Base): Modelo para la tabla GClases - Información de clases en sistemas SCAII y SCAF """ __tablename__ = "classes" - __table_args__ = {"schema": "a76"} + __table_args__ = ( + PrimaryKeyConstraint('id', name='classes_pkey'), + UniqueConstraint('client_key', 'class_code', name='uq_classes_client_key_class_code'), + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], name='fk_classes_tenant'), + ForeignKeyConstraint(['material_key'], ['public.material_types.key'], name='fk_classes_material_type'), + {"schema": "a76"} + ) - # Primary key compuesta - client_key = Column(Integer, primary_key=True, nullable=False) - class_code = Column(String(8), primary_key=True, nullable=False) + id: Mapped[int] = mapped_column(Integer, primary_key=True) + + # Unique constraint compuesta + client_key: Mapped[int] = mapped_column() + class_code: Mapped[str] = mapped_column(String(8)) + + tenant_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True) # Basic information - description_spanish = Column(String(500), nullable=True) - description_english = Column(String(500), nullable=True) + description_es: Mapped[Optional[str]] = mapped_column(String(500)) + description_en: Mapped[Optional[str]] = mapped_column(String(500)) # Material and measurement - material_key = Column(String(10), ForeignKey('public.material_types.key'), nullable=True) # CLAVEMAT - homologated from TIPOMAT/TIPOMATEQUIPO - unit_of_measure = Column(String(5), nullable=True) # UNIMED - homologated from UNIMEDIDA + material_key: Mapped[Optional[str]] = mapped_column(String(10), ForeignKey('public.material_types.key')) # CLAVEMAT - homologated from TIPOMAT/TIPOMATEQUIPO + unit_of_measure: Mapped[Optional[str]] = mapped_column(String(5)) # UNIMED - homologated from UNIMEDIDA # Tariff fractions - fraction = Column(String(10), nullable=True) # Mexican tariff fraction - us_fraction = Column(String(16), nullable=True) # FRACCIONAME - US tariff fraction + fraction: Mapped[Optional[str]] = mapped_column(String(10)) # Mexican tariff fraction + us_fraction: Mapped[Optional[str]] = mapped_column(String(16)) # FRACCIONAME - US tariff fraction # Additional classification - sub_key = Column(String(5), nullable=True) # CLAVESUB - physical_review = Column(SmallInteger, nullable=True) # REVFISICA - iva_exempt_fraction = Column(String(4), nullable=True) # FRACCIONEXENTAIVA + sub_key: Mapped[Optional[str]] = mapped_column(String(5)) # CLAVESUB + physical_review: Mapped[Optional[int]] = mapped_column(SmallInteger) # REVFISICA + iva_exempt_fraction: Mapped[Optional[str]] = mapped_column(String(4)) # FRACCIONEXENTAIVA # Relationships - material_type = relationship("MaterialType", foreign_keys=[material_key]) + material_type: Mapped[Optional["MaterialType"]] = relationship(foreign_keys=[material_key]) # Inverse relationship with GParts that have this class - parts = relationship( - "Part", + parts: Mapped[list["Part"]] = relationship( primaryjoin="and_(Class.client_key == Part.client_key, Class.class_code == Part.part_class)", foreign_keys="[Part.client_key, Part.part_class]", viewonly=True, back_populates="part_class_info" ) - def __repr__(self): - return f"" + def __repr__(self) -> str: + return f"" diff --git a/backend/api/v1/modules/a76/client_and_provider/models.py b/backend/api/v1/modules/a76/client_and_provider/models.py index 44007a5f..4131749b 100644 --- a/backend/api/v1/modules/a76/client_and_provider/models.py +++ b/backend/api/v1/modules/a76/client_and_provider/models.py @@ -1,9 +1,10 @@ """ Modelos ORM para gestión de clientes y proveedores """ -from sqlalchemy import Column, Integer, String, SmallInteger, Numeric, ForeignKey -from sqlalchemy.sql import func -from sqlalchemy.orm import relationship +from typing import Optional +from decimal import Decimal +from sqlalchemy import Integer, String, SmallInteger, Numeric, ForeignKey, PrimaryKeyConstraint, ForeignKeyConstraint +from sqlalchemy.orm import Mapped, mapped_column, relationship from core.database import Base @@ -12,32 +13,36 @@ class ClientProvider(Base): Modelo para la tabla GClientesPro - Información de clientes y proveedores """ __tablename__ = "client_provider" - __table_args__ = {"schema": "a76"} + __table_args__ = ( + PrimaryKeyConstraint('client_id', name='client_provider_pkey'), + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], name='fk_client_provider_tenant'), + {"schema": "a76"} + ) # Primary key - client_id = Column(String(8), primary_key=True, nullable=False) + client_id: Mapped[int] = mapped_column(Integer, primary_key=True) # Basic information - type_nat_foreign = Column(String(1), nullable=True) # TIPO NACIONAL/EXTRANJERO - name = Column(String(256), nullable=True) - short_name = Column(String(10), nullable=True) - rfc = Column(String(30), nullable=True) - curp = Column(String(19), nullable=True) - client_or_provider = Column(String(1), nullable=True) - linking = Column(String(1), nullable=True) - transform_subassembly = Column(String(1), nullable=True) - extra_information = Column(String(399), nullable=True) - web_key = Column(String(40), nullable=True) - responsible = Column(String(80), nullable=True) - position = Column(String(30), nullable=True) - incoterm = Column(String(19), nullable=True) - is_national_provider = Column(String(2), nullable=True) - enabled_disabled = Column(SmallInteger, nullable=True) - tenant_id = Column(String, ForeignKey("a76.tenants.id"), nullable=False) + type_nat_foreign: Mapped[Optional[str]] = mapped_column(String(1)) # TIPO NACIONAL/EXTRANJERO + name: Mapped[Optional[str]] = mapped_column(String(256)) + short_name: Mapped[Optional[str]] = mapped_column(String(10)) + rfc: Mapped[Optional[str]] = mapped_column(String(30)) + curp: Mapped[Optional[str]] = mapped_column(String(19)) + client_or_provider: Mapped[Optional[str]] = mapped_column(String(1)) + linking: Mapped[Optional[str]] = mapped_column(String(1)) + transform_subassembly: Mapped[Optional[str]] = mapped_column(String(1)) + extra_information: Mapped[Optional[str]] = mapped_column(String(399)) + web_key: Mapped[Optional[str]] = mapped_column(String(40)) + responsible: Mapped[Optional[str]] = mapped_column(String(80)) + position: Mapped[Optional[str]] = mapped_column(String(30)) + incoterm: Mapped[Optional[str]] = mapped_column(String(19)) + is_national_provider: Mapped[Optional[str]] = mapped_column(String(2)) + enabled_disabled: Mapped[Optional[int]] = mapped_column(SmallInteger) + tenant_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True) # Relationships - address = relationship("ClientProviderAddress", back_populates="client_provider", uselist=False, cascade="all, delete-orphan") - programs = relationship("ClientProviderPrograms", back_populates="client_provider", uselist=False, cascade="all, delete-orphan") + address: Mapped[Optional["ClientProviderAddress"]] = relationship(back_populates="client_provider", uselist=False, cascade="all, delete-orphan") + programs: Mapped[Optional["ClientProviderPrograms"]] = relationship(back_populates="client_provider", uselist=False, cascade="all, delete-orphan") class ClientProviderAddress(Base): @@ -45,29 +50,37 @@ class ClientProviderAddress(Base): Modelo para la tabla GClientesPro_Direccion - Dirección de clientes y proveedores """ __tablename__ = "client_provider_address" - __table_args__ = {"schema": "a76"} + __table_args__ = ( + PrimaryKeyConstraint('id', name='client_provider_address_pkey'), + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], name='fk_client_provider_address_tenant'), + ForeignKeyConstraint(['client_id'], ['a76.client_provider.client_id'], ondelete='CASCADE', name='fk_client_provider_address_client'), + {"schema": "a76"} + ) # Primary key (foreign key) - client_id = Column(String(8), ForeignKey('a76.client_provider.client_id', ondelete='CASCADE'), primary_key=True, nullable=False) + id: Mapped[int] = mapped_column(Integer, primary_key=True) + client_id: Mapped[int] = mapped_column(Integer, ForeignKey('a76.client_provider.client_id', ondelete='CASCADE')) + + tenant_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True) # Address information - municipality = Column(String(150), nullable=True) - streets = Column(String(100), nullable=True) - neighborhood = Column(String(40), nullable=True) - interior_number = Column(String(20), nullable=True) - exterior_number = Column(String(20), nullable=True) - postal_code = Column(String(15), nullable=True) - city = Column(String(30), nullable=True) - state = Column(String(30), nullable=True) - country = Column(String(3), nullable=True) - phone = Column(String(30), nullable=True) - fax_number = Column(String(30), nullable=True) - email = Column(String(100), nullable=True) - contact = Column(String(50), nullable=True) - reference = Column(String(250), nullable=True) + municipality: Mapped[Optional[str]] = mapped_column(String(150)) + streets: Mapped[Optional[str]] = mapped_column(String(100)) + neighborhood: Mapped[Optional[str]] = mapped_column(String(40)) + interior_number: Mapped[Optional[str]] = mapped_column(String(20)) + exterior_number: Mapped[Optional[str]] = mapped_column(String(20)) + postal_code: Mapped[Optional[str]] = mapped_column(String(15)) + city: Mapped[Optional[str]] = mapped_column(String(30)) + state: Mapped[Optional[str]] = mapped_column(String(30)) + country: Mapped[Optional[str]] = mapped_column(String(3)) + phone: Mapped[Optional[str]] = mapped_column(String(30)) + fax_number: Mapped[Optional[str]] = mapped_column(String(30)) + email: Mapped[Optional[str]] = mapped_column(String(100)) + contact: Mapped[Optional[str]] = mapped_column(String(50)) + reference: Mapped[Optional[str]] = mapped_column(String(250)) # Relationship - client_provider = relationship("ClientProvider", back_populates="address") + client_provider: Mapped["ClientProvider"] = relationship(back_populates="address") class ClientProviderPrograms(Base): @@ -75,34 +88,42 @@ class ClientProviderPrograms(Base): Modelo para la tabla GClientesPro_Programas - Programas de clientes y proveedores """ __tablename__ = "client_provider_programs" - __table_args__ = {"schema": "a76"} + __table_args__ = ( + PrimaryKeyConstraint('id', name='client_provider_programs_pkey'), + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], name='fk_client_provider_programs_tenant'), + ForeignKeyConstraint(['client_id'], ['a76.client_provider.client_id'], ondelete='CASCADE', name='fk_client_provider_programs_client'), + {"schema": "a76"} + ) # Primary key (foreign key) - client_id = Column(String(8), ForeignKey('a76.client_provider.client_id', ondelete='CASCADE'), primary_key=True, nullable=False) + id: Mapped[int] = mapped_column(Integer, primary_key=True) + client_id: Mapped[int] = mapped_column(Integer, ForeignKey('a76.client_provider.client_id', ondelete='CASCADE')) + + tenant_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True) # Program information - program = Column(String(7), nullable=True) - program_number = Column(String(40), nullable=True) - prosec = Column(SmallInteger, nullable=True) - prosec_authorization = Column(String(20), nullable=True) - secon_auth_date = Column(Integer, nullable=True) - manufacturer_id = Column(String(25), nullable=True) - tax_id = Column(String(30), nullable=True) - broker = Column(String(6), nullable=True) - import_broker = Column(String(6), nullable=True) - transfer_key = Column(String(8), nullable=True) - secon_authorization = Column(String(20), nullable=True) - applied_proportion = Column(Numeric(7, 2), nullable=True) - is_certified_company = Column(String(1), nullable=True) - certified_company_registry = Column(String(40), nullable=True) - donation_auth_number = Column(String(50), nullable=True) - ctpat_svi = Column(String(100), nullable=True) - tax_registry_number = Column(String(40), nullable=True) - subassembly_service = Column(SmallInteger, nullable=True) - autse_dates = Column(Integer, nullable=True) - autse_number = Column(String(300), nullable=True) + program: Mapped[Optional[str]] = mapped_column(String(7)) + program_number: Mapped[Optional[str]] = mapped_column(String(40)) + prosec: Mapped[Optional[int]] = mapped_column(SmallInteger) + prosec_authorization: Mapped[Optional[str]] = mapped_column(String(20)) + secon_auth_date: Mapped[Optional[int]] = mapped_column(Integer) + manufacturer_id: Mapped[Optional[str]] = mapped_column(String(25)) + tax_id: Mapped[Optional[str]] = mapped_column(String(30)) + broker: Mapped[Optional[str]] = mapped_column(String(6)) + import_broker: Mapped[Optional[str]] = mapped_column(String(6)) + transfer_key: Mapped[Optional[str]] = mapped_column(String(8)) + secon_authorization: Mapped[Optional[str]] = mapped_column(String(20)) + applied_proportion: Mapped[Optional[Decimal]] = mapped_column(Numeric(7, 2)) + is_certified_company: Mapped[Optional[str]] = mapped_column(String(1)) + certified_company_registry: Mapped[Optional[str]] = mapped_column(String(40)) + donation_auth_number: Mapped[Optional[str]] = mapped_column(String(50)) + ctpat_svi: Mapped[Optional[str]] = mapped_column(String(100)) + tax_registry_number: Mapped[Optional[str]] = mapped_column(String(40)) + subassembly_service: Mapped[Optional[int]] = mapped_column(SmallInteger) + autse_dates: Mapped[Optional[int]] = mapped_column() + autse_number: Mapped[Optional[str]] = mapped_column(String(300)) # Relationship - client_provider = relationship("ClientProvider", back_populates="programs") + client_provider: Mapped["ClientProvider"] = relationship(back_populates="programs") diff --git a/backend/api/v1/modules/a76/company/models.py b/backend/api/v1/modules/a76/company/models.py index 50df9a03..0ff67f22 100644 --- a/backend/api/v1/modules/a76/company/models.py +++ b/backend/api/v1/modules/a76/company/models.py @@ -1,10 +1,12 @@ """ Modelos ORM para gestión de empresa """ -from sqlalchemy import Column, Integer, String, DateTime, Boolean, Text, SmallInteger, ForeignKey +from typing import Optional +from datetime import datetime +from sqlalchemy import DateTime, Integer, String, Boolean, SmallInteger, ForeignKey, PrimaryKeyConstraint, ForeignKeyConstraint from sqlalchemy.sql import func +from sqlalchemy.orm import Mapped, mapped_column from core.database import Base -import enum class Company(Base): @@ -12,60 +14,62 @@ class Company(Base): Modelo para la tabla Company - Información de la empresa """ __tablename__ = "company" - __table_args__ = {"schema": "a76"} + __table_args__ = ( + PrimaryKeyConstraint('id', name='company_pkey'), + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], name='fk_company_tenant'), + {"schema": "a76"} + ) # Primary key - id = Column(String(3), primary_key=True, default='EMP', nullable=False) - - # Control de registro único - consecutive = Column(Boolean, unique=True, default=True, nullable=False) + id: Mapped[int] = mapped_column(Integer, primary_key=True) # Información básica de la empresa - name = Column(String(255), nullable=True) - rfc = Column(String(30), nullable=True) - main_activity = Column(String(255), nullable=True) + name: Mapped[Optional[str]] = mapped_column(String(255)) + rfc: Mapped[Optional[str]] = mapped_column(String(30)) + main_activity: Mapped[Optional[str]] = mapped_column(String(255)) # Información del programa - program = Column(String(10), nullable=True) - program_number = Column(String(40), nullable=True) - prosec = Column(SmallInteger, nullable=True) - prosec_authorization = Column(String(20), nullable=True) + program: Mapped[Optional[str]] = mapped_column(String(10)) + program_number: Mapped[Optional[str]] = mapped_column(String(40)) + prosec: Mapped[Optional[int]] = mapped_column(SmallInteger) + prosec_authorization: Mapped[Optional[str]] = mapped_column(String(20)) # Identificadores - manufacturer_id = Column(String(25), nullable=True) - broker_company = Column(String(10), nullable=True) + manufacturer_id: Mapped[Optional[str]] = mapped_column(String(25)) + broker_company: Mapped[Optional[str]] = mapped_column(String(10)) # Responsable - responsible = Column(String(80), nullable=True) - responsible_name = Column(String(20), nullable=True) - responsible_last_name = Column(String(20), nullable=True) - responsible_mother_last_name = Column(String(20), nullable=True) - responsible_rfc = Column(String(30), nullable=True) - position = Column(String(30), nullable=True) + responsible: Mapped[Optional[str]] = mapped_column(String(80)) + responsible_name: Mapped[Optional[str]] = mapped_column(String(20)) + responsible_last_name: Mapped[Optional[str]] = mapped_column(String(20)) + responsible_mother_last_name: Mapped[Optional[str]] = mapped_column(String(20)) + responsible_rfc: Mapped[Optional[str]] = mapped_column(String(30)) + position: Mapped[Optional[str]] = mapped_column(String(30)) # Configuración - logo = Column(String(255), nullable=True) - has_express_line = Column(Boolean, nullable=True) - order_format_type = Column(String(19), nullable=True) - previous_code = Column(SmallInteger, nullable=True) - is_service_company = Column(Boolean, nullable=True) + logo: Mapped[Optional[str]] = mapped_column(String(255)) + has_express_line: Mapped[Optional[bool]] = mapped_column(Boolean) + order_format_type: Mapped[Optional[str]] = mapped_column(String(19)) + previous_code: Mapped[Optional[int]] = mapped_column(SmallInteger) + is_service_company: Mapped[Optional[bool]] = mapped_column(Boolean) # Cliente y submaquila - client_name = Column(String(300), nullable=True) - subassembly_mode = Column(String(7), nullable=True) + client_name: Mapped[Optional[str]] = mapped_column(String(300)) + subassembly_mode: Mapped[Optional[str]] = mapped_column(String(7)) # Información adicional - curp = Column(String(19), nullable=True) - inter_db_name = Column(String(100), nullable=True) - ctpat_svi = Column(String(100), nullable=True) - trusted_exporter_number = Column(String(50), nullable=True) - prevalidator_key = Column(String(20), nullable=True) - seventh_amendment = Column(Boolean, nullable=True) # FINALCONTADORAELECTRONICO renombrado + curp: Mapped[Optional[str]] = mapped_column(String(19)) + inter_db_name: Mapped[Optional[str]] = mapped_column(String(100)) + ctpat_svi: Mapped[Optional[str]] = mapped_column(String(100)) + trusted_exporter_number: Mapped[Optional[str]] = mapped_column(String(50)) + prevalidator_key: Mapped[Optional[str]] = mapped_column(String(20)) + seventh_amendment: Mapped[Optional[bool]] = mapped_column(Boolean) # FINALCONTADORAELECTRONICO renombrado # Timestamps - created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) - updated_at = Column(DateTime(timezone=True), onupdate=func.now(), nullable=True) + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) - tenant_id = Column(String, ForeignKey("a76.tenants.id"), nullable=False) + tenant_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True) diff --git a/backend/api/v1/modules/a76/country_rule_oct/dto.py b/backend/api/v1/modules/a76/country_rule_oct/dto.py index beb5dd76..0dd0d789 100644 --- a/backend/api/v1/modules/a76/country_rule_oct/dto.py +++ b/backend/api/v1/modules/a76/country_rule_oct/dto.py @@ -15,4 +15,4 @@ class CountryRuleOctCreateDTO(CountryRuleOctBaseDTO): class CountryRuleOctResponseDTO(CountryRuleOctBaseDTO): class Config: - orm_mode = True \ No newline at end of file + from_attributes = True \ No newline at end of file diff --git a/backend/api/v1/modules/a76/country_rule_oct/models.py b/backend/api/v1/modules/a76/country_rule_oct/models.py index 968103f3..b60ad7c5 100644 --- a/backend/api/v1/modules/a76/country_rule_oct/models.py +++ b/backend/api/v1/modules/a76/country_rule_oct/models.py @@ -1,12 +1,26 @@ -from sqlalchemy import Column, String, Integer, ForeignKey +from sqlalchemy import Integer, String, ForeignKey, PrimaryKeyConstraint, ForeignKeyConstraint, UniqueConstraint +from sqlalchemy.orm import Mapped, mapped_column from core.database import Base + class CountryRuleOct(Base): __tablename__ = "country_rule_oct" - __table_args__ = {"schema": "a76"} + __table_args__ = ( + PrimaryKeyConstraint('id', name='country_rule_oct_pkey'), + UniqueConstraint('permission', 'line', 'fraction', 'country_code', name='uq_country_rule_oct_permission_line_fraction_country'), + ForeignKeyConstraint( + ['permission', 'line', 'fraction'], + ['a76.fraction_rule_octave.permission', 'a76.fraction_rule_octave.line', 'a76.fraction_rule_octave.fraction'], + ondelete="CASCADE", + name='fk_country_rule_oct_frac_octava' + ), + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], name='fk_country_rule_oct_tenant'), + {"schema": "a76"} + ) - permission = Column(String(20), ForeignKey("a76.GFracROctava.permission", ondelete="CASCADE"), primary_key=True, nullable=False) - line = Column(Integer, ForeignKey("a76.GFracROctava.line", ondelete="CASCADE"), primary_key=True, nullable=False) - fraction = Column(String(10), ForeignKey("a76.GFracROctava.fraction", ondelete="CASCADE"), primary_key=True, nullable=False) - country_code = Column(String(3), primary_key=True, nullable=False) - tenant_id = Column(String, ForeignKey("a76.tenants.id"), nullable=False) \ No newline at end of file + id: Mapped[int] = mapped_column(Integer, primary_key=True) + permission: Mapped[str] = mapped_column(String(20)) + line: Mapped[int] = mapped_column() + fraction: Mapped[str] = mapped_column(String(10)) + country_code: Mapped[str] = mapped_column(String(3)) + tenant_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True) \ No newline at end of file diff --git a/backend/api/v1/modules/a76/exchange_rate/dto.py b/backend/api/v1/modules/a76/exchange_rate/dto.py index 942cf8b6..ffc520ea 100644 --- a/backend/api/v1/modules/a76/exchange_rate/dto.py +++ b/backend/api/v1/modules/a76/exchange_rate/dto.py @@ -12,4 +12,4 @@ class ExchangeRateCreateDTO(ExchangeRateBaseDTO): class ExchangeRateResponseDTO(ExchangeRateBaseDTO): class Config: - orm_mode = True \ No newline at end of file + from_attributes = True \ No newline at end of file diff --git a/backend/api/v1/modules/a76/exchange_rate/models.py b/backend/api/v1/modules/a76/exchange_rate/models.py index b086588d..00d77d87 100644 --- a/backend/api/v1/modules/a76/exchange_rate/models.py +++ b/backend/api/v1/modules/a76/exchange_rate/models.py @@ -1,11 +1,22 @@ -from sqlalchemy import Column, Integer, String, DECIMAL +from typing import Optional +from decimal import Decimal +from sqlalchemy import Integer, String, DECIMAL, PrimaryKeyConstraint, DateTime, ForeignKeyConstraint, UniqueConstraint, ForeignKey +from sqlalchemy.orm import Mapped, mapped_column from core.database import Base + class ExchangeRate(Base): __tablename__ = "exchange_rate" - __table_args__ = {"schema": "a76"} + __table_args__ = ( + PrimaryKeyConstraint('id', name='exchange_rate_pkey'), + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], name='fk_exchange_rate_tenant'), + UniqueConstraint('date', 'tenant_id', name='uq_exchange_rate_date_tenant'), + {"schema": "a76"} + ) - date = Column(Integer, primary_key=True, nullable=False) - value = Column(DECIMAL(13, 6), nullable=True) - local_currency = Column(String(7), nullable=True) - foreign_currency = Column(String(7), nullable=True) \ No newline at end of file + id: Mapped[int] = mapped_column(Integer, primary_key=True) + date: Mapped[int] = mapped_column(DateTime) + value: Mapped[Optional[Decimal]] = mapped_column(DECIMAL(13, 6)) + local_currency: Mapped[Optional[str]] = mapped_column(String(7)) + foreign_currency: Mapped[Optional[str]] = mapped_column(String(7)) + tenant_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True) \ No newline at end of file diff --git a/backend/api/v1/modules/a76/fraction_rule_octave/dto.py b/backend/api/v1/modules/a76/fraction_rule_octave/dto.py index 7ae60933..e5226499 100644 --- a/backend/api/v1/modules/a76/fraction_rule_octave/dto.py +++ b/backend/api/v1/modules/a76/fraction_rule_octave/dto.py @@ -1,11 +1,11 @@ """ -DTOs for GFracROctava. +DTOs for FractionRuleOctave. """ from pydantic import BaseModel from typing import Optional -class GFracROctavaBaseDTO(BaseModel): +class FractionRuleOctaveBaseDTO(BaseModel): PERMISSION: str LINE: int FRACTION: str @@ -16,9 +16,9 @@ class GFracROctavaBaseDTO(BaseModel): UNIT_COST_ME: Optional[float] UNIT_MEASURE: Optional[str] -class GFracROctavaCreateDTO(GFracROctavaBaseDTO): +class FractionRuleOctaveCreateDTO(FractionRuleOctaveBaseDTO): pass -class GFracROctavaResponseDTO(GFracROctavaBaseDTO): +class FractionRuleOctaveResponseDTO(FractionRuleOctaveBaseDTO): class Config: - orm_mode = True \ No newline at end of file + from_attributes = True \ No newline at end of file diff --git a/backend/api/v1/modules/a76/fraction_rule_octave/models.py b/backend/api/v1/modules/a76/fraction_rule_octave/models.py index ae9ef403..c277c9b5 100644 --- a/backend/api/v1/modules/a76/fraction_rule_octave/models.py +++ b/backend/api/v1/modules/a76/fraction_rule_octave/models.py @@ -1,11 +1,19 @@ -from sqlalchemy import Column, String, Integer, ForeignKey +from sqlalchemy import Integer, String, ForeignKey, PrimaryKeyConstraint, ForeignKeyConstraint, UniqueConstraint +from sqlalchemy.orm import Mapped, mapped_column from core.database import Base + class FractionRuleOctave(Base): __tablename__ = "fraction_rule_octave" - __table_args__ = {"schema": "a76"} - - permission = Column(String(20), primary_key=True, nullable=False) - line = Column(Integer, nullable=False) - fraction = Column(String(10), nullable=False) - tenant_id = Column(String, ForeignKey("a76.tenants.id"), nullable=False) \ No newline at end of file + __table_args__ = ( + PrimaryKeyConstraint('id', name='fraction_rule_octave_pkey'), + UniqueConstraint('permission', 'line', 'fraction', name='uq_fraction_rule_octave_permission_line_fraction'), + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], name='fk_fraction_rule_octave_tenant'), + {"schema": "a76"} + ) + + id: Mapped[int] = mapped_column(Integer, primary_key=True) + permission: Mapped[str] = mapped_column(String(20)) + line: Mapped[int] = mapped_column(Integer) + fraction: Mapped[str] = mapped_column(String(10)) + tenant_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True) \ No newline at end of file diff --git a/backend/api/v1/modules/a76/fraction_rule_octave/routes.py b/backend/api/v1/modules/a76/fraction_rule_octave/routes.py index 2c3a1c5e..43c24bc5 100644 --- a/backend/api/v1/modules/a76/fraction_rule_octave/routes.py +++ b/backend/api/v1/modules/a76/fraction_rule_octave/routes.py @@ -4,24 +4,24 @@ from typing import List from core.database import get_core_db from core.security import get_current_user -from .dto import GFracROctavaCreateDTO, GFracROctavaResponseDTO -from .services import GFracROctavaService +from .dto import FractionRuleOctaveCreateDTO, FractionRuleOctaveResponseDTO +from .services import FractionRuleOctaveService -router = APIRouter(prefix="/gfracroctava", tags=["GFracROctava"]) +router = APIRouter(prefix="/fraction_rule_octave", tags=["FractionRuleOctave"]) -@router.get("/", response_model=List[GFracROctavaResponseDTO]) +@router.get("/", response_model=List[FractionRuleOctaveResponseDTO]) async def list_fractions( db: Session = Depends(get_core_db), current_user: dict = Depends(get_current_user) ): """ - List all GFracROctava entries. + List all FractionRuleOctave entries. """ - return db.query(GFracROctavaService).all() + return db.query(FractionRuleOctaveService).all() -@router.get("/{permission}/{line}/{fraction}", response_model=GFracROctavaResponseDTO) +@router.get("/{permission}/{line}/{fraction}", response_model=FractionRuleOctaveResponseDTO) async def read_fraction( permission: str, line: int, @@ -30,24 +30,24 @@ async def read_fraction( current_user: dict = Depends(get_current_user) ): """ - Get a specific GFracROctava by its composite key. + Get a specific FractionRuleOctave by its composite key. """ - frac = GFracROctavaService.get_fraction_by_permission_line(db, permission, line, fraction) + frac = FractionRuleOctaveService.get_fraction_by_permission_line(db, permission, line, fraction) if not frac: - raise HTTPException(status_code=404, detail="GFracROctava not found") + raise HTTPException(status_code=404, detail="FractionRuleOctave not found") return frac -@router.post("/", response_model=GFracROctavaResponseDTO, status_code=status.HTTP_201_CREATED) +@router.post("/", response_model=FractionRuleOctaveResponseDTO, status_code=status.HTTP_201_CREATED) async def create_frac( - frac_data: GFracROctavaCreateDTO, + frac_data: FractionRuleOctaveCreateDTO, db: Session = Depends(get_core_db), current_user: dict = Depends(get_current_user) ): """ - Create a new GFracROctava entry. + Create a new FractionRuleOctave entry. """ - return GFracROctavaService.create_frac(db, frac_data) + return FractionRuleOctaveService.create_frac(db, frac_data) @router.delete("/{permission}/{line}/{fraction}", status_code=status.HTTP_204_NO_CONTENT) @@ -59,8 +59,8 @@ async def delete_fraction( current_user: dict = Depends(get_current_user) ): """ - Delete a GFracROctava by its composite key. + Delete a FractionRuleOctave by its composite key. """ - frac = GFracROctavaService.delete_fraction(db, permission, line, fraction) + frac = FractionRuleOctaveService.delete_fraction(db, permission, line, fraction) if not frac: - raise HTTPException(status_code=404, detail="GFracROctava not found") \ No newline at end of file + raise HTTPException(status_code=404, detail="FractionRuleOctave not found") \ No newline at end of file diff --git a/backend/api/v1/modules/a76/fraction_rule_octave/services.py b/backend/api/v1/modules/a76/fraction_rule_octave/services.py index 5cc7285c..0a1f2a16 100644 --- a/backend/api/v1/modules/a76/fraction_rule_octave/services.py +++ b/backend/api/v1/modules/a76/fraction_rule_octave/services.py @@ -2,21 +2,21 @@ from sqlalchemy.orm import Session from . import models, dto """ -Service layer for GFracROctava. +Service layer for FractionRuleOctave. """ -class GFracROctavaService: +class FractionRuleOctaveService: @staticmethod def get_fraction_by_permission_line(db: Session, permission: str, line: int, fraction: str): - return db.query(models.GFracROctava).filter( - models.GFracROctava.PERMISSION == permission, - models.GFracROctava.LINE == line, - models.GFracROctava.FRACTION == fraction + return db.query(models.FractionRuleOctave).filter( + models.FractionRuleOctave.permission == permission, + models.FractionRuleOctave.line == line, + models.FractionRuleOctave.fraction == fraction ).first() @staticmethod - def create_frac(db: Session, frac_data: dto.GFracROctavaCreateDTO): - new_frac = models.GFracROctava(**frac_data.dict()) + def create_frac(db: Session, frac_data: dto.FractionRuleOctaveCreateDTO): + new_frac = models.FractionRuleOctave(**frac_data.model_dump()) db.add(new_frac) db.commit() db.refresh(new_frac) @@ -24,7 +24,7 @@ class GFracROctavaService: @staticmethod def delete_fraction(db: Session, permission: str, line: int, fraction: str): - frac = GFracROctavaService.get_fraction_by_permission_line(db, permission, line, fraction) + frac = FractionRuleOctaveService.get_fraction_by_permission_line(db, permission, line, fraction) if frac: db.delete(frac) db.commit() diff --git a/backend/api/v1/modules/a76/licenses/models.py b/backend/api/v1/modules/a76/licenses/models.py index eb3ada1f..d1a6cad4 100644 --- a/backend/api/v1/modules/a76/licenses/models.py +++ b/backend/api/v1/modules/a76/licenses/models.py @@ -1,9 +1,11 @@ """ Modelos ORM para gestión de licencias """ +from datetime import datetime from sqlalchemy import Column, Integer, String, DateTime, Boolean, ForeignKey, Enum as SQLEnum from sqlalchemy.sql import func from sqlalchemy.orm import relationship +from sqlalchemy.orm import Mapped, mapped_column from core.database import Base import enum @@ -55,8 +57,9 @@ class License(Base): expires_at = Column(DateTime(timezone=True), nullable=False) # Timestamps - created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) - updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False) + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) def __repr__(self): return f"" @@ -82,8 +85,9 @@ class LicenseUsage(Base): api_calls_count = Column(Integer, default=0) # Timestamps - created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) - updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False) + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) def __repr__(self): return f"" diff --git a/backend/api/v1/modules/a76/package/dto.py b/backend/api/v1/modules/a76/package/dto.py index da27fa80..ba749ccb 100644 --- a/backend/api/v1/modules/a76/package/dto.py +++ b/backend/api/v1/modules/a76/package/dto.py @@ -32,4 +32,4 @@ class GBultoResponseDTO(GBultoBaseDTO): UPDATED_AT: Optional[str] class Config: - orm_mode = True \ No newline at end of file + from_attributes = True \ No newline at end of file diff --git a/backend/api/v1/modules/a76/package/models.py b/backend/api/v1/modules/a76/package/models.py index c7c4dc13..6d2b9fa7 100644 --- a/backend/api/v1/modules/a76/package/models.py +++ b/backend/api/v1/modules/a76/package/models.py @@ -1,22 +1,35 @@ -from sqlalchemy import Column, String, DECIMAL, DateTime, ForeignKey -from sqlalchemy.orm import declarative_base +from typing import Optional +from datetime import datetime +from decimal import Decimal +from sqlalchemy import DateTime, Integer, String, DECIMAL, ForeignKey, PrimaryKeyConstraint, ForeignKeyConstraint, UniqueConstraint from sqlalchemy.sql import func - +from sqlalchemy.orm import Mapped, mapped_column from core.database import Base -class GBulto(Base): - __tablename__ = "gbultos" - __table_args__ = {"schema": "a76"} - CLAVE = Column(String(5), primary_key=True, nullable=False) - DESCRIPTION = Column(String(40), nullable=True) - DESCRIPTIONI = Column(String(40), nullable=True) - WEIGHT_UNIT = Column(DECIMAL(19, 8), nullable=True) - PLURALS = Column(String(4), nullable=True) - PLURAL_IN = Column(String(4), nullable=True) - CODE_ACE = Column(String(4), nullable=True) - CODE_AAMEX = Column(String(9), nullable=True) - CREATED_AT = Column(DateTime, server_default=func.now(), nullable=False) - UPDATED_AT = Column(DateTime, server_default=func.now(), onupdate=func.now(), nullable=False) - tenant_id = Column(String, ForeignKey("a76.tenants.id"), nullable=False) +class Package(Base): + __tablename__ = "packages" # GBultos + __table_args__ = ( + PrimaryKeyConstraint('id', name='packages_pkey'), + UniqueConstraint('key', name='packages_key_ukey'), + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], name='fk_packages_tenant'), + {"schema": "a76"} + ) + + id: Mapped[int] = mapped_column(Integer, primary_key=True) + tenant_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True) + key: Mapped[str] = mapped_column(String(5)) + description_es: Mapped[Optional[str]] = mapped_column(String(40)) + description_en: Mapped[Optional[str]] = mapped_column(String(40)) + weight_unit: Mapped[Optional[Decimal]] = mapped_column(DECIMAL(19, 8)) + plurals: Mapped[Optional[str]] = mapped_column(String(4)) + plural_in: Mapped[Optional[str]] = mapped_column(String(4)) + code_ace: Mapped[Optional[str]] = mapped_column(String(4)) + code_aamex: Mapped[Optional[str]] = mapped_column(String(9)) + + # Timestamps + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) + diff --git a/backend/api/v1/modules/a76/package/routes.py b/backend/api/v1/modules/a76/package/routes.py index 6dfba7ff..c8b17ba7 100644 --- a/backend/api/v1/modules/a76/package/routes.py +++ b/backend/api/v1/modules/a76/package/routes.py @@ -4,11 +4,11 @@ from typing import List from core.database import get_core_db from core.security import get_current_user -from .models import GBulto +from .models import Package from .dto import GBultoCreateDTO, GBultoUpdateDTO, GBultoResponseDTO from .services import GBultoService -router = APIRouter(prefix="/gbultos", tags=["GBultos"]) +router = APIRouter(prefix="/bultos", tags=["GBultos"]) @router.get("/", response_model=List[GBultoResponseDTO]) @@ -21,7 +21,7 @@ async def list_bultos( """ List all GBultos with pagination. """ - return db.query(GBulto).offset(skip).limit(limit).all() + return db.query(Package).offset(skip).limit(limit).all() @router.get("/{code}", response_model=GBultoResponseDTO) @@ -31,11 +31,11 @@ async def read_bulto( current_user: dict = Depends(get_current_user) ): """ - Get a specific GBulto by its CODE. + Get a specific Package by its CODE. """ bulto = GBultoService.get_bulto_by_code(db, code) if not bulto: - raise HTTPException(status_code=404, detail="GBulto not found") + raise HTTPException(status_code=404, detail="Package not found") return bulto @@ -46,7 +46,7 @@ async def create_gbulto( current_user: dict = Depends(get_current_user) ): """ - Create a new GBulto. + Create a new Package. """ return GBultoService.create_gbulto(db, bulto_data) @@ -59,11 +59,11 @@ async def update_bulto( current_user: dict = Depends(get_current_user) ): """ - Update an existing GBulto. + Update an existing Package. """ bulto = GBultoService.update_bulto(db, code, bulto_data) if not bulto: - raise HTTPException(status_code=404, detail="GBulto not found") + raise HTTPException(status_code=404, detail="Package not found") return bulto @@ -74,8 +74,8 @@ async def delete_bulto( current_user: dict = Depends(get_current_user) ): """ - Delete a GBulto by its CODE. + Delete a Package by its CODE. """ bulto = GBultoService.delete_bulto(db, code) if not bulto: - raise HTTPException(status_code=404, detail="GBulto not found") \ No newline at end of file + raise HTTPException(status_code=404, detail="Package not found") \ No newline at end of file diff --git a/backend/api/v1/modules/a76/package/services.py b/backend/api/v1/modules/a76/package/services.py index 1fe7e922..1e22e92c 100644 --- a/backend/api/v1/modules/a76/package/services.py +++ b/backend/api/v1/modules/a76/package/services.py @@ -8,11 +8,11 @@ class GBultoService: @staticmethod def get_bulto_by_code(db: Session, code: str): - return db.query(models.GBulto).filter(models.GBulto.CODE == code).first() + return db.query(models.Package).filter(models.Package.CODE == code).first() @staticmethod def create_gbulto(db: Session, gbulto_data: dto.GBultoCreateDTO): - new_gbulto = models.GBulto(**gbulto_data.dict()) + new_gbulto = models.Package(**gbulto_data.dict()) db.add(new_gbulto) db.commit() db.refresh(new_gbulto) diff --git a/backend/api/v1/modules/a76/parts/models.py b/backend/api/v1/modules/a76/parts/models.py index 909076c9..8d17a177 100644 --- a/backend/api/v1/modules/a76/parts/models.py +++ b/backend/api/v1/modules/a76/parts/models.py @@ -1,14 +1,13 @@ """ Modelos ORM para gestión de partes/componentes """ -from sqlalchemy import Column, Integer, String, DateTime, Boolean, Text, Numeric, SmallInteger, ForeignKey -from sqlalchemy.sql import func -from sqlalchemy.orm import relationship -from core.database import Base -import enum - -# Importar modelos relacionados para type hints y relationships from typing import TYPE_CHECKING, Optional +from datetime import datetime +from decimal import Decimal +from sqlalchemy import Integer, String, Numeric, SmallInteger, ForeignKey, PrimaryKeyConstraint, ForeignKeyConstraint, UniqueConstraint +from sqlalchemy.sql import func +from sqlalchemy.orm import Mapped, mapped_column, relationship +from core.database import Base if TYPE_CHECKING: from api.v1.modules.public.reference_data.countries.models import Country @@ -21,70 +20,79 @@ class Part(Base): Modelo para la tabla GPartes - Información de partes en los sistemas SCAII (N), SCAF (S) Y WINSAAI (W) """ __tablename__ = "parts" - __table_args__ = {"schema": "a76"} + __table_args__ = ( + PrimaryKeyConstraint('id', name='parts_pkey'), + UniqueConstraint('client_key', 'part_number', name='client_part_ukey'), + ForeignKeyConstraint(['country_of_origin'], ['public.countries.m3_key'], name='fk_parts_country'), + ForeignKeyConstraint(['currency_key'], ['public.currency_types.code'], name='fk_parts_currency'), + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], name='fk_parts_tenant'), + {"schema": "a76"} + ) - # Primary key compuesta - client_key = Column(Integer, primary_key=True, nullable=False) - part_number = Column(String(49), primary_key=True, nullable=False) + id: Mapped[int] = mapped_column(Integer, primary_key=True) + + # Tenant + tenant_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True) + + # Unique constraint compuesta + client_key: Mapped[int] = mapped_column(Integer) + part_number: Mapped[str] = mapped_column(String(49)) # Basic information - fraction = Column(String(10), nullable=True) - description_spanish = Column(String(500), nullable=True) - description_english = Column(String(500), nullable=True) - part_class = Column(String(8), nullable=True) - unit_of_measure = Column(String(5), nullable=True) - commercial_part_number = Column(String(70), nullable=True) - country_of_origin = Column(String(3), ForeignKey('public.countries.m3_key'), nullable=True) + fraction: Mapped[Optional[str]] = mapped_column(String(10)) + description_spanish: Mapped[Optional[str]] = mapped_column(String(500)) + description_english: Mapped[Optional[str]] = mapped_column(String(500)) + part_class: Mapped[Optional[str]] = mapped_column(String(8)) + unit_of_measure: Mapped[Optional[str]] = mapped_column(String(5)) + commercial_part_number: Mapped[Optional[str]] = mapped_column(String(70)) + country_of_origin: Mapped[Optional[str]] = mapped_column(String(3)) # Pricing and currency - unit_cost = Column(Numeric(23, 8), nullable=True) - currency_type = Column(String(2), nullable=True) - currency_key = Column(String(3), ForeignKey('public.currency_types.code'), nullable=True) + unit_cost: Mapped[Optional[Decimal]] = mapped_column(Numeric(23, 8)) + currency_type: Mapped[Optional[str]] = mapped_column(String(2)) + currency_key: Mapped[Optional[str]] = mapped_column(String(3)) # Weight information - unit_weight = Column(Numeric(19, 8), nullable=True) - weight_type = Column(String(6), nullable=True) + unit_weight: Mapped[Optional[Decimal]] = mapped_column(Numeric(19, 8)) + weight_type: Mapped[Optional[str]] = mapped_column(String(6)) # Classification and regulatory - us_fraction = Column(String(16), nullable=True) # FRACCIONAME - fda_key = Column(String(20), nullable=True) - fcc_key = Column(String(30), nullable=True) - license_code = Column(String(3), nullable=True) - eccn = Column(String(20), nullable=True) # Export Control Classification Number - export_code = Column(String(2), nullable=True) - exclusion_symbol = Column(String(19), nullable=True) # SIMBOLOEXCLIC + us_fraction: Mapped[Optional[str]] = mapped_column(String(16)) # FRACCIONAME + fda_key: Mapped[Optional[str]] = mapped_column(String(20)) + fcc_key: Mapped[Optional[str]] = mapped_column(String(30)) + license_code: Mapped[Optional[str]] = mapped_column(String(3)) + eccn: Mapped[Optional[str]] = mapped_column(String(20)) # Export Control Classification Number + export_code: Mapped[Optional[str]] = mapped_column(String(2)) + exclusion_symbol: Mapped[Optional[str]] = mapped_column(String(19)) # SIMBOLOEXCLIC # Additional information - supplier = Column(String(14), nullable=True) - alternate_unit_measure = Column(String(14), nullable=True) - added_value = Column(Numeric(23, 8), nullable=True) + supplier: Mapped[Optional[str]] = mapped_column(String(14)) + alternate_unit_measure: Mapped[Optional[str]] = mapped_column(String(14)) + added_value: Mapped[Optional[Decimal]] = mapped_column(Numeric(23, 8)) # Status and dates - enabled_disabled = Column(SmallInteger, nullable=True) - creation_date = Column(Integer, nullable=True) # FECHACREACIONPARTE - modification_date = Column(Integer, nullable=True) # FECHAMODIFICA - modification_date_iso = Column(DateTime(timezone=True), nullable=True) # FECHAMODIFICA_ISO + enabled_disabled: Mapped[Optional[int]] = mapped_column(SmallInteger) + creation_date: Mapped[Optional[int]] = mapped_column() # FECHACREACIONPARTE + modification_date: Mapped[Optional[int]] = mapped_column() # FECHAMODIFICA + modification_date_iso: Mapped[Optional[datetime]] = mapped_column() # FECHAMODIFICA_ISO # Media - part_photo = Column(String(255), nullable=True) + part_photo: Mapped[Optional[str]] = mapped_column(String(255)) # Relationships - country = relationship("Country", foreign_keys=[country_of_origin]) - currency = relationship("CurrencyType", foreign_keys=[currency_key]) + country: Mapped[Optional["Country"]] = relationship(foreign_keys=[country_of_origin]) + currency: Mapped[Optional["CurrencyType"]] = relationship(foreign_keys=[currency_key]) # Relationship with Class through composite foreign key # Note: This requires both client_key and part_class to match client_key and class_code in Class - part_class_info = relationship( - "Class", + part_class_info: Mapped[Optional["Class"]] = relationship( primaryjoin="and_(Part.client_key == Class.client_key, Part.part_class == Class.class_code)", foreign_keys="[Part.client_key, Part.part_class]", viewonly=True, back_populates="parts" ) - - tenant_id = Column(String, ForeignKey("a76.tenants.id"), nullable=False) - def __repr__(self): + def __repr__(self) -> str: return f"" diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_additional.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_additional.py index 78ee3907..67f4ad96 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_additional.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_additional.py @@ -1,8 +1,14 @@ -from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, SmallInteger, String, UniqueConstraint, text +from typing import TYPE_CHECKING +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, SmallInteger, String, UniqueConstraint, func, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped +from datetime import datetime from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos + + class PedimentoConfigAdditional(Base): __tablename__ = 'pedimento_config_additional' __table_args__ = ( @@ -22,6 +28,10 @@ class PedimentoConfigAdditional(Base): enable_import_invoice_recipient = mapped_column(SmallInteger) send_502_validation_file_for_consolidated = mapped_column(SmallInteger) add_remove_norms = mapped_column(SmallInteger) - created_at = mapped_column(DateTime, server_default=text('CURRENT_TIMESTAMP')) + + # Timestamps + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) pedimento: Mapped['Pedimentos'] = relationship('Pedimentos', back_populates='pedimento_config_additional') \ No newline at end of file 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 da711625..d4b29047 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,13 @@ -from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, SmallInteger, String, UniqueConstraint, text +from typing import TYPE_CHECKING +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, SmallInteger, String, UniqueConstraint, func, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped +from datetime import datetime from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos + class PedimentoConfigCalculations(Base): __tablename__ = 'pedimento_config_calculations' __table_args__ = ( @@ -26,6 +31,10 @@ class PedimentoConfigCalculations(Base): fixed_vehicle_dta_fee = mapped_column(SmallInteger) additional_fixed_fee = mapped_column(SmallInteger) additional_fixed_fee_payment_method = mapped_column(SmallInteger) - created_at = mapped_column(DateTime, server_default=text('CURRENT_TIMESTAMP')) + + # Timestamps + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, 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 bce09458..a30e59ff 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 @@ -1,8 +1,13 @@ -from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, Numeric, PrimaryKeyConstraint, SmallInteger, UniqueConstraint, text +from typing import TYPE_CHECKING +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, Numeric, PrimaryKeyConstraint, SmallInteger, UniqueConstraint, func, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped +from datetime import datetime from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos + class PedimentoConfigParameters(Base): __tablename__ = 'pedimento_config_parameters' @@ -28,6 +33,10 @@ class PedimentoConfigParameters(Base): customs_value_per_item = mapped_column(SmallInteger) is_national_supplier = mapped_column(SmallInteger) is_consolidated = mapped_column(SmallInteger) - created_at = mapped_column(DateTime, server_default=text('CURRENT_TIMESTAMP')) + + # Timestamps + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) pedimento: Mapped['Pedimentos'] = relationship('Pedimentos', back_populates='pedimento_config_parameters') \ No newline at end of file diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_surcharges.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_surcharges.py index 1ba6e0d6..e36ef3d1 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_surcharges.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_surcharges.py @@ -1,8 +1,13 @@ -from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, SmallInteger, UniqueConstraint, text +from typing import TYPE_CHECKING +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, SmallInteger, UniqueConstraint, func, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped +from datetime import datetime from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos + class PedimentoConfigSurcharges(Base): __tablename__ = 'pedimento_config_surcharges' __table_args__ = ( @@ -22,6 +27,10 @@ class PedimentoConfigSurcharges(Base): surcharge_isan = mapped_column(SmallInteger) surcharge_ieps = mapped_column(SmallInteger) surcharge_cc = mapped_column(SmallInteger) - created_at = mapped_column(DateTime, server_default=text('CURRENT_TIMESTAMP')) + + # Timestamps + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) pedimento: Mapped['Pedimentos'] = relationship('Pedimentos', back_populates='pedimento_config_surcharges') \ No newline at end of file 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 f7e1ea42..29af4636 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 @@ -1,8 +1,13 @@ -from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, SmallInteger, UniqueConstraint, text +from typing import TYPE_CHECKING +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, SmallInteger, UniqueConstraint, func, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped +from datetime import datetime from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos + class PedimentoConfigUpdateRectification(Base): __tablename__ = 'pedimento_config_update_rectification' __table_args__ = ( @@ -21,6 +26,10 @@ class PedimentoConfigUpdateRectification(Base): update_cc = mapped_column(SmallInteger) update_ieps = mapped_column(SmallInteger) calculate_surcharge = mapped_column(SmallInteger) - created_at = mapped_column(DateTime, server_default=text('CURRENT_TIMESTAMP')) + + # Timestamps + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) pedimento: Mapped['Pedimentos'] = relationship('Pedimentos', back_populates='pedimento_config_update_rectification') \ No newline at end of file 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 1fcedb8c..7162fb1d 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 @@ -1,8 +1,13 @@ -from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, SmallInteger, UniqueConstraint, text +from typing import TYPE_CHECKING +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, SmallInteger, UniqueConstraint, func, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped +from datetime import datetime from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos + class PedimentoConfigUpdates(Base): __tablename__ = 'pedimento_config_updates' __table_args__ = ( @@ -20,6 +25,10 @@ class PedimentoConfigUpdates(Base): update_advalorem = mapped_column(SmallInteger) update_cc = mapped_column(SmallInteger) update_ieps = mapped_column(SmallInteger) - created_at = mapped_column(DateTime, server_default=text('CURRENT_TIMESTAMP')) + + # Timestamps + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) pedimento: Mapped['Pedimentos'] = relationship('Pedimentos', back_populates='pedimento_config_updates') \ No newline at end of file diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_customs_offices.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_customs_offices.py index f6af5419..5efc6fa0 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_customs_offices.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_customs_offices.py @@ -1,8 +1,13 @@ -from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, String, UniqueConstraint, text +from typing import TYPE_CHECKING +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, String, UniqueConstraint, func, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped +from datetime import datetime from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos + class PedimentoCustomsOffices(Base): __tablename__ = 'pedimento_customs_offices' __table_args__ = ( @@ -18,6 +23,10 @@ class PedimentoCustomsOffices(Base): tenant_id = mapped_column(Integer, nullable=False, index=True) dispatch_customs = mapped_column(String(3)) entry_exit_customs = mapped_column(String(3)) - created_at = mapped_column(DateTime, server_default=text('CURRENT_TIMESTAMP')) + + # Timestamps + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) pedimento: Mapped['Pedimentos'] = relationship('Pedimentos', back_populates='pedimento_customs_offices') \ No newline at end of file diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_dates.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_dates.py index 406974c2..6a4141e0 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_dates.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_dates.py @@ -1,8 +1,13 @@ -from sqlalchemy import DateTime, ForeignKeyConstraint, Index, Integer, PrimaryKeyConstraint, Time, UniqueConstraint, text +from typing import TYPE_CHECKING +from sqlalchemy import DateTime, ForeignKeyConstraint, Index, Integer, PrimaryKeyConstraint, Time, UniqueConstraint, func, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped +from datetime import datetime from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos + class PedimentoDates(Base): __tablename__ = 'pedimento_dates' __table_args__ = ( @@ -29,6 +34,10 @@ class PedimentoDates(Base): end_date = mapped_column(DateTime) capture_date = mapped_column(DateTime) capture_time = mapped_column(Time) - created_at = mapped_column(DateTime, server_default=text('CURRENT_TIMESTAMP')) + + # Timestamps + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) pedimento: Mapped['Pedimentos'] = relationship('Pedimentos', back_populates='pedimento_dates') \ No newline at end of file diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_decrementables.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_decrementables.py index 04376b85..1b55c1d4 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_decrementables.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_decrementables.py @@ -1,8 +1,13 @@ -from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, Numeric, PrimaryKeyConstraint, SmallInteger, String, UniqueConstraint, text +from typing import TYPE_CHECKING +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, Numeric, PrimaryKeyConstraint, SmallInteger, String, UniqueConstraint, func, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped +from datetime import datetime from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos + class PedimentoDecrementables(Base): __tablename__ = 'pedimento_decrementables' __table_args__ = ( @@ -25,6 +30,10 @@ class PedimentoDecrementables(Base): currency_factor = mapped_column(Numeric(15, 8)) not_affect_usd_value = mapped_column(SmallInteger) not_affect_customs_value = mapped_column(SmallInteger) - created_at = mapped_column(DateTime, server_default=text('CURRENT_TIMESTAMP')) + + # Timestamps + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) pedimento: Mapped['Pedimentos'] = relationship('Pedimentos', back_populates='pedimento_decrementables') \ No newline at end of file diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_incrementables.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_incrementables.py index 44c3f987..5889246d 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_incrementables.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_incrementables.py @@ -1,8 +1,13 @@ -from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, Numeric, PrimaryKeyConstraint, SmallInteger, String, UniqueConstraint, text +from typing import TYPE_CHECKING +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, Numeric, PrimaryKeyConstraint, SmallInteger, String, UniqueConstraint, func, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped +from datetime import datetime from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos + class PedimentoIncrementables(Base): __tablename__ = 'pedimento_incrementables' __table_args__ = ( @@ -26,6 +31,10 @@ class PedimentoIncrementables(Base): currency_factor = mapped_column(Numeric(15, 8)) not_affect_usd_value = mapped_column(SmallInteger) not_affect_customs_value = mapped_column(SmallInteger) - created_at = mapped_column(DateTime, server_default=text('CURRENT_TIMESTAMP')) + + # Timestamps + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) pedimento: Mapped['Pedimentos'] = relationship('Pedimentos', back_populates='pedimento_incrementables') \ No newline at end of file diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_indexes.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_indexes.py index 3704e981..0420b4a1 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_indexes.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_indexes.py @@ -1,8 +1,13 @@ -from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, Numeric, PrimaryKeyConstraint, SmallInteger, UniqueConstraint, text +from typing import TYPE_CHECKING +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, Numeric, PrimaryKeyConstraint, SmallInteger, UniqueConstraint, func, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped +from datetime import datetime from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos + class PedimentoIndexes(Base): __tablename__ = 'pedimento_indexes' __table_args__ = ( @@ -19,6 +24,10 @@ class PedimentoIndexes(Base): update_factor_type = mapped_column(SmallInteger) update_factor = mapped_column(Numeric(7, 4)) manual_update_factor = mapped_column(SmallInteger) - created_at = mapped_column(DateTime, server_default=text('CURRENT_TIMESTAMP')) + + # Timestamps + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) pedimento: Mapped['Pedimentos'] = relationship('Pedimentos', back_populates='pedimento_indexes') \ No newline at end of file diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_payments.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_payments.py index 5360af8b..f3a72e3a 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_payments.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_payments.py @@ -1,8 +1,13 @@ -from sqlalchemy import Date, DateTime, ForeignKeyConstraint, Index, Integer, PrimaryKeyConstraint, SmallInteger, String, Time, UniqueConstraint, text +from typing import TYPE_CHECKING +from sqlalchemy import Date, DateTime, ForeignKeyConstraint, Index, Integer, PrimaryKeyConstraint, SmallInteger, String, Time, UniqueConstraint, func, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped +from datetime import datetime from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos + class PedimentoPayments(Base): __tablename__ = 'pedimento_payments' __table_args__ = ( @@ -29,6 +34,10 @@ class PedimentoPayments(Base): counter_payment = mapped_column(SmallInteger) pece_code = mapped_column(String(5)) payment_id = mapped_column(Integer) - created_at = mapped_column(DateTime, server_default=text('CURRENT_TIMESTAMP')) + + # Timestamps + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) pedimento: Mapped['Pedimentos'] = relationship('Pedimentos', back_populates='pedimento_payments') \ No newline at end of file diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_rectification_destination.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_rectification_destination.py index 6b4a18fa..25d72f49 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_rectification_destination.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_rectification_destination.py @@ -1,8 +1,12 @@ +from typing import TYPE_CHECKING from sqlalchemy import ForeignKeyConstraint, Integer, PrimaryKeyConstraint, String, UniqueConstraint from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos + class PedimentoRectificationDestination(Base): __tablename__ = 'pedimento_rectification_destination' __table_args__ = ( diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_rectification_origin.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_rectification_origin.py index 951c66b2..3a02d4b6 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_rectification_origin.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_rectification_origin.py @@ -1,8 +1,12 @@ +from typing import TYPE_CHECKING from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, SmallInteger, String, UniqueConstraint from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos + class PedimentoRectificationOrigin(Base): __tablename__ = 'pedimento_rectification_origin' __table_args__ = ( diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_transport_means.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_transport_means.py index fa3d5508..f17baf99 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_transport_means.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_transport_means.py @@ -1,8 +1,12 @@ +from typing import TYPE_CHECKING from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, SmallInteger, String, UniqueConstraint, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos + class PedimentoTransportMeans(Base): __tablename__ = 'pedimento_transport_means' __table_args__ = ( diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_validation.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_validation.py index 9965c08a..c8f0ec68 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimento_validation.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_validation.py @@ -1,8 +1,13 @@ -from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, String, UniqueConstraint, text +from typing import TYPE_CHECKING +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, String, UniqueConstraint, func, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped +from datetime import datetime from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimentos import Pedimentos + class PedimentoValidation(Base): __tablename__ = 'pedimento_validation' #PedimentoValidacion __table_args__ = ( @@ -24,6 +29,10 @@ class PedimentoValidation(Base): certificate_number = mapped_column(String(99)) #numero_certificado validator_id = mapped_column(Integer) responsible_id = mapped_column(Integer) - created_at = mapped_column(DateTime, server_default=text('CURRENT_TIMESTAMP')) + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) + + pedimento: Mapped['Pedimentos'] = relationship('Pedimentos', back_populates='pedimento_validation') \ No newline at end of file diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimentos.py b/backend/api/v1/modules/a76/pedmientos/models/pedimentos.py index a984364f..0b2b79cf 100644 --- a/backend/api/v1/modules/a76/pedmientos/models/pedimentos.py +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimentos.py @@ -1,12 +1,32 @@ -from sqlalchemy import DateTime, ForeignKeyConstraint, Index, Integer, Numeric, PrimaryKeyConstraint, String, text +from typing import TYPE_CHECKING +from sqlalchemy import DateTime, ForeignKeyConstraint, Index, Integer, Numeric, PrimaryKeyConstraint, String, func, text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm.base import Mapped +from datetime import datetime from core.database import Base +if TYPE_CHECKING: + from api.v1.modules.a76.pedmientos.models.pedimento_config_additional import PedimentoConfigAdditional + from api.v1.modules.a76.pedmientos.models.pedimento_config_calculations import PedimentoConfigCalculations + from api.v1.modules.a76.pedmientos.models.pedimento_config_parameters import PedimentoConfigParameters + from api.v1.modules.a76.pedmientos.models.pedimento_config_surcharges import PedimentoConfigSurcharges + from api.v1.modules.a76.pedmientos.models.pedimento_config_update_rectification import PedimentoConfigUpdateRectification + from api.v1.modules.a76.pedmientos.models.pedimento_config_updates import PedimentoConfigUpdates + from api.v1.modules.a76.pedmientos.models.pedimento_customs_offices import PedimentoCustomsOffices + from api.v1.modules.a76.pedmientos.models.pedimento_dates import PedimentoDates + from api.v1.modules.a76.pedmientos.models.pedimento_decrementables import PedimentoDecrementables + from api.v1.modules.a76.pedmientos.models.pedimento_incrementables import PedimentoIncrementables + from api.v1.modules.a76.pedmientos.models.pedimento_indexes import PedimentoIndexes + from api.v1.modules.a76.pedmientos.models.pedimento_payments import PedimentoPayments + from api.v1.modules.a76.pedmientos.models.pedimento_rectification_destination import PedimentoRectificationDestination + from api.v1.modules.a76.pedmientos.models.pedimento_rectification_origin import PedimentoRectificationOrigin + from api.v1.modules.a76.pedmientos.models.pedimento_transport_means import PedimentoTransportMeans + from api.v1.modules.a76.pedmientos.models.pedimento_validation import PedimentoValidation class Pedimentos(Base): __tablename__ = 'pedimentos' __table_args__ = ( + ForeignKeyConstraint(['client_id'], ['public.client_and_providers.id']), ForeignKeyConstraint(['regime'], ['public.pedimento_regimens.code']), ForeignKeyConstraint(['pedimento_code'], ['public.pedimento_codes.code']), ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), @@ -33,7 +53,11 @@ class Pedimentos(Base): paid_price = mapped_column(Numeric(17, 6)) gross_weight = mapped_column(Numeric(19, 3)) exchange_rate = mapped_column(Numeric(9, 5)) - created_at = mapped_column(DateTime, server_default=text('CURRENT_TIMESTAMP')) + + # Timestamps + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) pedimento_config_additional: Mapped['PedimentoConfigAdditional'] = relationship('PedimentoConfigAdditional', uselist=False, back_populates='pedimento') pedimento_config_calculations: Mapped['PedimentoConfigCalculations'] = relationship('PedimentoConfigCalculations', uselist=False, back_populates='pedimento') diff --git a/backend/api/v1/modules/a76/permission_rule_oct/dto.py b/backend/api/v1/modules/a76/permission_rule_oct/dto.py index 6497c1c1..fc31095c 100644 --- a/backend/api/v1/modules/a76/permission_rule_oct/dto.py +++ b/backend/api/v1/modules/a76/permission_rule_oct/dto.py @@ -13,4 +13,4 @@ class PermissionRuleOctCreateDTO(PermissionRuleOctBaseDTO): class PermissionRuleOctResponseDTO(PermissionRuleOctBaseDTO): class Config: - orm_mode = True \ No newline at end of file + from_attributes = True \ No newline at end of file diff --git a/backend/api/v1/modules/a76/permission_rule_oct/models.py b/backend/api/v1/modules/a76/permission_rule_oct/models.py index f69a566d..dad79c9e 100644 --- a/backend/api/v1/modules/a76/permission_rule_oct/models.py +++ b/backend/api/v1/modules/a76/permission_rule_oct/models.py @@ -1,13 +1,21 @@ -from sqlalchemy import Column, String, Integer, ForeignKey +from typing import Optional +from sqlalchemy import Integer, String, ForeignKey, PrimaryKeyConstraint, ForeignKeyConstraint, UniqueConstraint +from sqlalchemy.orm import Mapped, mapped_column from core.database import Base + class PermissionRuleOct(Base): __tablename__ = "permission_rule_oct" - __table_args__ = {"schema": "a76"} - - permission = Column(String(20), primary_key=True, nullable=False) - start_date = Column(Integer, nullable=True) - end_date = Column(Integer, nullable=True) - sector = Column(String(8), nullable=True) - system = Column(String(5), nullable=True) - tenant_id = Column(String, ForeignKey("a76.tenants.id"), nullable=False) \ No newline at end of file + __table_args__ = ( + PrimaryKeyConstraint('id', name='permission_rule_oct_pkey'), + UniqueConstraint('permission', 'tenant_id', name='permission_rule_oct_permission_tenant_ukey'), + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], name='fk_permission_rule_oct_tenant'), + {"schema": "a76"} + ) + id: Mapped[int] = mapped_column(Integer, primary_key=True) + permission: Mapped[str] = mapped_column(String(20)) + start_date: Mapped[Optional[int]] = mapped_column() + end_date: Mapped[Optional[int]] = mapped_column() + sector: Mapped[Optional[str]] = mapped_column(String(8)) + system: Mapped[Optional[str]] = mapped_column(String(5)) + tenant_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True) \ No newline at end of file diff --git a/backend/api/v1/modules/a76/seal/dto.py b/backend/api/v1/modules/a76/seal/dto.py index 19f5ff9e..48fdd5d1 100644 --- a/backend/api/v1/modules/a76/seal/dto.py +++ b/backend/api/v1/modules/a76/seal/dto.py @@ -12,4 +12,4 @@ class SealCreateDTO(SealBaseDTO): class SealResponseDTO(SealBaseDTO): class Config: - orm_mode = True \ No newline at end of file + from_attributes = True \ No newline at end of file diff --git a/backend/api/v1/modules/a76/seal/models.py b/backend/api/v1/modules/a76/seal/models.py index 9091b9a9..52902408 100644 --- a/backend/api/v1/modules/a76/seal/models.py +++ b/backend/api/v1/modules/a76/seal/models.py @@ -1,9 +1,17 @@ -from sqlalchemy import Column, String, ForeignKey +from sqlalchemy import Integer, String, ForeignKey, PrimaryKeyConstraint, ForeignKeyConstraint, UniqueConstraint +from sqlalchemy.orm import Mapped, mapped_column from core.database import Base + class Seal(Base): __tablename__ = "seal" - __table_args__ = {"schema": "a76"} - - seal = Column(String(15), primary_key=True, nullable=False) - tenant_id = Column(String, ForeignKey("a76.tenants.id"), nullable=False) \ No newline at end of file + __table_args__ = ( + PrimaryKeyConstraint('id', name='seal_pkey'), + UniqueConstraint('seal', name='seal_ukey'), + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], name='fk_seal_tenant'), + {"schema": "a76"} + ) + + id: Mapped[int] = mapped_column(Integer, primary_key=True) + seal: Mapped[str] = mapped_column(String(15)) + tenant_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True) \ No newline at end of file diff --git a/backend/api/v1/modules/a76/tenants/models.py b/backend/api/v1/modules/a76/tenants/models.py index 3e564be9..b4ab9e72 100644 --- a/backend/api/v1/modules/a76/tenants/models.py +++ b/backend/api/v1/modules/a76/tenants/models.py @@ -3,6 +3,8 @@ Modelos ORM para gestión de tenants """ from sqlalchemy import Column, Integer, String, DateTime, Boolean, Text, Enum as SQLEnum from sqlalchemy.sql import func +from sqlalchemy.orm import Mapped, mapped_column +from datetime import datetime from core.database import Base import enum @@ -43,8 +45,9 @@ class Tenant(Base): is_active = Column(Boolean, default=True, nullable=False) # Timestamps - created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) - updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False) + created_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) + updated_at: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now(), onupdate=func.now()) + deleted_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True) def __repr__(self): return f"" diff --git a/models.py b/models.py deleted file mode 100644 index e69de29b..00000000 diff --git a/models_ped.py b/models_ped.py deleted file mode 100644 index 233407cf..00000000 --- a/models_ped.py +++ /dev/null @@ -1,27 +0,0 @@ -from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, SmallInteger, String, UniqueConstraint, text -from sqlalchemy.orm import Mapped, mapped_column, relationship -from sqlalchemy.orm.base import Mapped -from core.database import Base - -class PedimentoValidation(Base): - __tablename__ = 'pedimento_validation' - __table_args__ = ( - ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], ondelete='CASCADE', name='fk_pedimento_validation'), - PrimaryKeyConstraint('id', name='pedimento_validation_pkey'), - UniqueConstraint('pedimento_id', name='pedimento_validation_pedimento_id_key'), - {'schema': 'a76'} - ) - - id = mapped_column(Integer) - pedimento_id = mapped_column(Integer, nullable=False) - validator = mapped_column(String(3)) - validation_ack = mapped_column(String(8)) - pre_ack = mapped_column(String(8)) - line_signature = mapped_column(String(50)) - electronic_signature = mapped_column(String(999)) - certificate_number = mapped_column(String(99)) - validator_id = mapped_column(Integer) - responsible_id = mapped_column(Integer) - created_at = mapped_column(DateTime, server_default=text('CURRENT_TIMESTAMP')) - - pedimento: Mapped['Pedimentos'] = relationship('Pedimentos', back_populates='pedimento_validation')