diff --git a/backend/alembic.ini b/backend/alembic.ini index 47b33935..dc170438 100644 --- a/backend/alembic.ini +++ b/backend/alembic.ini @@ -84,7 +84,8 @@ path_separator = os # database URL. This is consumed by the user-maintained env.py script only. # other means of configuring database URLs may be customized within the env.py # file. -sqlalchemy.url = ${DATABASE_URL} + +sqlalchemy.url = postgresql://${CORE_DB_USER}:${CORE_DB_PASSWORD}@${CORE_DB_HOST}:${CORE_DB_PORT}/${CORE_DB_NAME} [post_write_hooks] diff --git a/backend/alembic/env.py b/backend/alembic/env.py index 3b2a3673..819d6e50 100644 --- a/backend/alembic/env.py +++ b/backend/alembic/env.py @@ -78,8 +78,9 @@ fileConfig(config.config_file_name) target_metadata = Base.metadata def import_models_from_dir(dir_path: str): - """Importa recursivamente cualquier archivo models.py desde dir_path""" + """Importa recursivamente cualquier archivo models.py desde dir_path y archivos en directorios models/""" for root, dirs, files in os.walk(dir_path): + # Importar archivos models.py directos if "models.py" in files: module_path = os.path.join(root, "models.py") # Convertir path en nombre de módulo compatible @@ -89,6 +90,20 @@ def import_models_from_dir(dir_path: str): spec = importlib.util.spec_from_file_location(module_name, module_path) mod = importlib.util.module_from_spec(spec) spec.loader.exec_module(mod) + + # Importar todos los archivos .py en directorios llamados "models" + if os.path.basename(root) == "models": + for file in files: + if file.endswith(".py") and not file.startswith("__"): + module_path = os.path.join(root, file) + rel_path = os.path.relpath(module_path, BASE_DIR) + module_name = rel_path.replace(os.sep, ".").replace(".py", "") + try: + spec = importlib.util.spec_from_file_location(module_name, module_path) + mod = importlib.util.module_from_spec(spec) + spec.loader.exec_module(mod) + except Exception as e: + logger.warning(f"No se pudo importar {module_path}: {e}") # Importar todos los models dentro de api/v1/modules y api/v1/modules/uploads modules_dir = os.path.join(BASE_DIR, "api", "v1", "modules") diff --git a/backend/alembic/versions/03b786378f94_pedimentos.py b/backend/alembic/versions/03b786378f94_pedimentos.py new file mode 100644 index 00000000..d760d4b8 --- /dev/null +++ b/backend/alembic/versions/03b786378f94_pedimentos.py @@ -0,0 +1,424 @@ +"""Pedimentos + +Revision ID: 03b786378f94 +Revises: 7937209f9718 +Create Date: 2025-11-06 17:07:16.536298 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = '03b786378f94' +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.""" + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('pedimentos', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('year', sa.String(length=2), nullable=True), + sa.Column('customs_office', sa.String(length=2), nullable=True), + sa.Column('license', sa.String(length=4), nullable=True), + sa.Column('pedimento_number', sa.String(length=7), nullable=True), + sa.Column('client_id', sa.Integer(), nullable=True), + sa.Column('operation_type', sa.Integer(), nullable=True), + sa.Column('pedimento_type', sa.Integer(), nullable=True), + sa.Column('pedimento_key', sa.String(length=2), nullable=True), + sa.Column('regime', sa.String(length=3), nullable=True), + sa.Column('status', sa.String(length=30), nullable=True), + sa.Column('usd_value', sa.Numeric(precision=17, scale=6), nullable=True), + sa.Column('paid_price', sa.Numeric(precision=17, scale=6), nullable=True), + sa.Column('gross_weight', sa.Numeric(precision=19, scale=3), nullable=True), + sa.Column('exchange_rate', sa.Numeric(precision=9, scale=5), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimentos_pkey'), + schema='a76' + ) + op.create_index('idx_pedimentos_client_id', 'pedimentos', ['client_id'], unique=False, schema='a76') + op.create_index('idx_pedimentos_created_at', 'pedimentos', ['created_at'], unique=False, schema='a76') + op.create_index('idx_pedimentos_status', 'pedimentos', ['status'], unique=False, schema='a76') + op.create_index(op.f('ix_a76_pedimentos_tenant_id'), 'pedimentos', ['tenant_id'], unique=False, schema='a76') + op.create_table('pedimento_config_additional', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('pedimento_id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('add_po_identifier', sa.SmallInteger(), nullable=True), + sa.Column('do_not_exempt_norms_complement_x', sa.SmallInteger(), nullable=True), + sa.Column('manual_pedimento_year', sa.String(length=2), nullable=True), + sa.Column('enable_import_invoice_recipient', sa.SmallInteger(), nullable=True), + sa.Column('send_502_validation_file_for_consolidated', sa.SmallInteger(), nullable=True), + sa.Column('add_remove_norms', sa.SmallInteger(), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True), + sa.ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], name='fk_pedimento_config_additional', ondelete='CASCADE'), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimento_config_additional_pkey'), + sa.UniqueConstraint('pedimento_id', name='pedimento_config_additional_pedimento_id_key'), + schema='a76' + ) + op.create_index(op.f('ix_a76_pedimento_config_additional_tenant_id'), 'pedimento_config_additional', ['tenant_id'], unique=False, schema='a76') + op.create_table('pedimento_config_calculations', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('pedimento_id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('dta_type', sa.String(length=1), nullable=True), + sa.Column('dta_operation', sa.SmallInteger(), nullable=True), + sa.Column('dta_vehicle_count', sa.SmallInteger(), nullable=True), + sa.Column('dta_mixed_rate_8permil', sa.SmallInteger(), nullable=True), + sa.Column('pays_vat', sa.SmallInteger(), nullable=True), + sa.Column('pays_prevalidation', sa.SmallInteger(), nullable=True), + sa.Column('include_sagar_certificate_fee', sa.SmallInteger(), nullable=True), + sa.Column('fixed_vehicle_dta_fee', sa.SmallInteger(), nullable=True), + sa.Column('additional_fixed_fee', sa.SmallInteger(), nullable=True), + sa.Column('additional_fixed_fee_payment_method', sa.SmallInteger(), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True), + sa.ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], name='fk_pedimento_config_calculations', ondelete='CASCADE'), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimento_config_calculations_pkey'), + sa.UniqueConstraint('pedimento_id', name='pedimento_config_calculations_pedimento_id_key'), + schema='a76' + ) + op.create_index(op.f('ix_a76_pedimento_config_calculations_tenant_id'), 'pedimento_config_calculations', ['tenant_id'], unique=False, schema='a76') + op.create_table('pedimento_config_parameters', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('pedimento_id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('is_embassy', sa.SmallInteger(), nullable=True), + sa.Column('embassy_dta', sa.Numeric(precision=11, scale=2), nullable=True), + sa.Column('rule_3121_section_ii', sa.SmallInteger(), nullable=True), + sa.Column('use_previous_tariff', sa.SmallInteger(), nullable=True), + sa.Column('use_payment_date_fi', sa.SmallInteger(), nullable=True), + sa.Column('add_state_supplier_record_505', sa.SmallInteger(), nullable=True), + sa.Column('customs_value_calculation', sa.SmallInteger(), nullable=True), + sa.Column('two_decimals_unit_value', sa.SmallInteger(), nullable=True), + sa.Column('customs_value_per_item', sa.SmallInteger(), nullable=True), + sa.Column('is_national_supplier', sa.SmallInteger(), nullable=True), + sa.Column('is_consolidated', sa.SmallInteger(), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True), + sa.ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], name='fk_pedimento_config_parameters', ondelete='CASCADE'), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimento_config_parameters_pkey'), + sa.UniqueConstraint('pedimento_id', name='pedimento_config_parameters_pedimento_id_key'), + schema='a76' + ) + op.create_index(op.f('ix_a76_pedimento_config_parameters_tenant_id'), 'pedimento_config_parameters', ['tenant_id'], unique=False, schema='a76') + op.create_table('pedimento_config_surcharges', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('pedimento_id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('surcharge_igi', sa.SmallInteger(), nullable=True), + sa.Column('surcharge_dta', sa.SmallInteger(), nullable=True), + sa.Column('surcharge_vat', sa.SmallInteger(), nullable=True), + sa.Column('surcharge_isan', sa.SmallInteger(), nullable=True), + sa.Column('surcharge_ieps', sa.SmallInteger(), nullable=True), + sa.Column('surcharge_cc', sa.SmallInteger(), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True), + sa.ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], name='fk_pedimento_config_surcharges', ondelete='CASCADE'), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimento_config_surcharges_pkey'), + sa.UniqueConstraint('pedimento_id', name='pedimento_config_surcharges_pedimento_id_key'), + schema='a76' + ) + op.create_index(op.f('ix_a76_pedimento_config_surcharges_tenant_id'), 'pedimento_config_surcharges', ['tenant_id'], unique=False, schema='a76') + op.create_table('pedimento_config_update_rectification', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('pedimento_id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('update_vat', sa.SmallInteger(), nullable=True), + sa.Column('update_advalorem', sa.SmallInteger(), nullable=True), + sa.Column('update_cc', sa.SmallInteger(), nullable=True), + sa.Column('update_ieps', sa.SmallInteger(), nullable=True), + sa.Column('calculate_surcharge', sa.SmallInteger(), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True), + sa.ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], name='fk_pedimento_config_update_rectification', ondelete='CASCADE'), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimento_config_update_rectification_pkey'), + sa.UniqueConstraint('pedimento_id', name='pedimento_config_update_rectification_pedimento_id_key'), + schema='a76' + ) + op.create_index(op.f('ix_a76_pedimento_config_update_rectification_tenant_id'), 'pedimento_config_update_rectification', ['tenant_id'], unique=False, schema='a76') + op.create_table('pedimento_config_updates', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('pedimento_id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('update_vat', sa.SmallInteger(), nullable=True), + sa.Column('update_advalorem', sa.SmallInteger(), nullable=True), + sa.Column('update_cc', sa.SmallInteger(), nullable=True), + sa.Column('update_ieps', sa.SmallInteger(), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True), + sa.ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], name='fk_pedimento_config_updates', ondelete='CASCADE'), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimento_config_updates_pkey'), + sa.UniqueConstraint('pedimento_id', name='pedimento_config_updates_pedimento_id_key'), + schema='a76' + ) + op.create_index(op.f('ix_a76_pedimento_config_updates_tenant_id'), 'pedimento_config_updates', ['tenant_id'], unique=False, schema='a76') + op.create_table('pedimento_customs_offices', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('pedimento_id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('dispatch_customs', sa.String(length=3), nullable=True), + sa.Column('entry_exit_customs', sa.String(length=3), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True), + sa.ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], name='fk_pedimento_customs_offices', ondelete='CASCADE'), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimento_customs_offices_pkey'), + sa.UniqueConstraint('pedimento_id', name='pedimento_customs_offices_pedimento_id_key'), + schema='a76' + ) + op.create_index(op.f('ix_a76_pedimento_customs_offices_tenant_id'), 'pedimento_customs_offices', ['tenant_id'], unique=False, schema='a76') + op.create_table('pedimento_dates', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('pedimento_id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('entry_date', sa.DateTime(), nullable=True), + sa.Column('pedimento_date', sa.DateTime(), nullable=True), + sa.Column('payment_date', sa.DateTime(), nullable=True), + sa.Column('rectification_payment_date', sa.DateTime(), nullable=True), + sa.Column('extraction_date', sa.DateTime(), nullable=True), + sa.Column('submission_date', sa.DateTime(), nullable=True), + sa.Column('eucan_date', sa.DateTime(), nullable=True), + sa.Column('original_date', sa.DateTime(), nullable=True), + sa.Column('start_date', sa.DateTime(), nullable=True), + sa.Column('end_date', sa.DateTime(), nullable=True), + sa.Column('capture_date', sa.DateTime(), nullable=True), + sa.Column('capture_time', sa.Time(), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True), + sa.ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], name='fk_pedimento_dates', ondelete='CASCADE'), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimento_dates_pkey'), + sa.UniqueConstraint('pedimento_id', name='pedimento_dates_pedimento_id_key'), + schema='a76' + ) + op.create_index('idx_pedimento_dates_pedimento_id', 'pedimento_dates', ['pedimento_id'], unique=False, schema='a76') + op.create_index(op.f('ix_a76_pedimento_dates_tenant_id'), 'pedimento_dates', ['tenant_id'], unique=False, schema='a76') + op.create_table('pedimento_decrementables', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('pedimento_id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('freight', sa.Numeric(precision=13, scale=2), nullable=True), + sa.Column('insurance', sa.Numeric(precision=13, scale=2), nullable=True), + sa.Column('loading', sa.Numeric(precision=13, scale=2), nullable=True), + sa.Column('unloading', sa.Numeric(precision=13, scale=2), nullable=True), + sa.Column('others', sa.Numeric(precision=13, scale=2), nullable=True), + sa.Column('currency', sa.String(length=3), nullable=True), + sa.Column('currency_factor', sa.Numeric(precision=15, scale=8), nullable=True), + sa.Column('not_affect_usd_value', sa.SmallInteger(), nullable=True), + sa.Column('not_affect_customs_value', sa.SmallInteger(), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True), + sa.ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], name='fk_pedimento_decrementables', ondelete='CASCADE'), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimento_decrementables_pkey'), + sa.UniqueConstraint('pedimento_id', name='pedimento_decrementables_pedimento_id_key'), + schema='a76' + ) + op.create_index(op.f('ix_a76_pedimento_decrementables_tenant_id'), 'pedimento_decrementables', ['tenant_id'], unique=False, schema='a76') + op.create_table('pedimento_incrementables', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('pedimento_id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('insured_value', sa.Numeric(precision=13, scale=2), nullable=True), + sa.Column('freight', sa.Numeric(precision=13, scale=2), nullable=True), + sa.Column('insurance', sa.Numeric(precision=13, scale=2), nullable=True), + sa.Column('packaging', sa.Numeric(precision=13, scale=2), nullable=True), + sa.Column('others', sa.Numeric(precision=13, scale=3), nullable=True), + sa.Column('deductibles', sa.Numeric(precision=13, scale=3), nullable=True), + sa.Column('currency', sa.String(length=3), nullable=True), + sa.Column('currency_factor', sa.Numeric(precision=15, scale=8), nullable=True), + sa.Column('not_affect_usd_value', sa.SmallInteger(), nullable=True), + sa.Column('not_affect_customs_value', sa.SmallInteger(), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True), + sa.ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], name='fk_pedimento_incrementables', ondelete='CASCADE'), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimento_incrementables_pkey'), + sa.UniqueConstraint('pedimento_id', name='pedimento_incrementables_pedimento_id_key'), + schema='a76' + ) + op.create_index(op.f('ix_a76_pedimento_incrementables_tenant_id'), 'pedimento_incrementables', ['tenant_id'], unique=False, schema='a76') + op.create_table('pedimento_indexes', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('pedimento_id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('update_factor_type', sa.SmallInteger(), nullable=True), + sa.Column('update_factor', sa.Numeric(precision=7, scale=4), nullable=True), + sa.Column('manual_update_factor', sa.SmallInteger(), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True), + sa.ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], name='fk_pedimento_indexes', ondelete='CASCADE'), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimento_indexes_pkey'), + sa.UniqueConstraint('pedimento_id', name='pedimento_indexes_pedimento_id_key'), + schema='a76' + ) + op.create_index(op.f('ix_a76_pedimento_indexes_tenant_id'), 'pedimento_indexes', ['tenant_id'], unique=False, schema='a76') + op.create_table('pedimento_payments', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('pedimento_id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('acknowledgment', sa.String(length=20), nullable=True), + sa.Column('operation_number', sa.String(length=14), nullable=True), + sa.Column('bank_code', sa.Integer(), nullable=True), + sa.Column('cashier', sa.String(length=2), nullable=True), + sa.Column('date', sa.Date(), nullable=True), + sa.Column('time', sa.Time(), nullable=True), + sa.Column('shift', sa.String(length=1), nullable=True), + sa.Column('total_cash_paid', sa.Integer(), nullable=True), + sa.Column('total_contributions', sa.Integer(), nullable=True), + sa.Column('counter_payment', sa.SmallInteger(), nullable=True), + sa.Column('pece_code', sa.String(length=5), nullable=True), + sa.Column('payment_id', sa.Integer(), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True), + sa.ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], name='fk_pedimento_payments', ondelete='CASCADE'), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimento_payments_pkey'), + sa.UniqueConstraint('pedimento_id', name='pedimento_payments_pedimento_id_key'), + schema='a76' + ) + op.create_index('idx_pedimento_payments_pedimento_id', 'pedimento_payments', ['pedimento_id'], unique=False, schema='a76') + op.create_index(op.f('ix_a76_pedimento_payments_tenant_id'), 'pedimento_payments', ['tenant_id'], unique=False, schema='a76') + op.create_table('pedimento_rectification_destination', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('pedimento_id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('destination_pedimento_year', sa.String(length=2), nullable=True), + sa.Column('destination_customs_office', sa.String(length=3), nullable=True), + sa.Column('destination_license', sa.String(length=4), nullable=True), + sa.Column('destination_pedimento_number', sa.String(length=7), nullable=True), + sa.ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], name='fk_pedimento_rectification_destination', ondelete='CASCADE'), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimento_rectification_destination_pkey'), + sa.UniqueConstraint('pedimento_id', name='pedimento_rectification_destination_pedimento_id_key'), + schema='a76' + ) + op.create_index(op.f('ix_a76_pedimento_rectification_destination_tenant_id'), 'pedimento_rectification_destination', ['tenant_id'], unique=False, schema='a76') + op.create_table('pedimento_rectification_origin', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('pedimento_id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('original_pedimento_year', sa.String(length=2), nullable=True), + sa.Column('original_customs_office', sa.String(length=3), nullable=True), + sa.Column('original_license', sa.String(length=4), nullable=True), + sa.Column('original_pedimento_number', sa.String(length=7), nullable=True), + sa.Column('original_pedimento_key', sa.String(length=2), nullable=True), + sa.Column('original_payment_date', sa.DateTime(), nullable=True), + sa.Column('total_cash', sa.Integer(), nullable=True), + sa.Column('total_others', sa.Integer(), nullable=True), + sa.Column('reason', sa.String(length=255), nullable=True), + sa.Column('charge_to_client', sa.SmallInteger(), nullable=True), + sa.Column('use_original_payment_date_for_interest_calc', sa.SmallInteger(), nullable=True), + sa.Column('manual_calculation', sa.SmallInteger(), nullable=True), + sa.Column('original_pedimento_norms', sa.SmallInteger(), nullable=True), + sa.ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], name='fk_pedimento_rectification_origin', ondelete='CASCADE'), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimento_rectification_origin_pkey'), + sa.UniqueConstraint('pedimento_id', name='pedimento_rectification_origin_pedimento_id_key'), + schema='a76' + ) + op.create_index(op.f('ix_a76_pedimento_rectification_origin_tenant_id'), 'pedimento_rectification_origin', ['tenant_id'], unique=False, schema='a76') + op.create_table('pedimento_transport_means', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('pedimento_id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('destination', sa.SmallInteger(), nullable=True), + sa.Column('entry_exit', sa.String(length=2), nullable=True), + sa.Column('arrival', sa.String(length=2), nullable=True), + sa.Column('departure', sa.String(length=2), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True), + sa.ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], name='fk_pedimento_transport_means', ondelete='CASCADE'), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimento_transport_means_pkey'), + sa.UniqueConstraint('pedimento_id', name='pedimento_transport_means_pedimento_id_key'), + schema='a76' + ) + op.create_index(op.f('ix_a76_pedimento_transport_means_tenant_id'), 'pedimento_transport_means', ['tenant_id'], unique=False, schema='a76') + op.create_table('pedimento_validation', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('pedimento_id', sa.Integer(), nullable=False), + sa.Column('tenant_id', sa.Integer(), nullable=False), + sa.Column('validator', sa.String(length=3), nullable=True), + sa.Column('validation_ack', sa.String(length=8), nullable=True), + sa.Column('pre_ack', sa.String(length=8), nullable=True), + sa.Column('line_signature', sa.String(length=50), nullable=True), + sa.Column('electronic_signature', sa.String(length=999), nullable=True), + sa.Column('certificate_number', sa.String(length=99), nullable=True), + sa.Column('validator_id', sa.Integer(), nullable=True), + sa.Column('responsible_id', sa.Integer(), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True), + sa.ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], name='fk_pedimento_validation', ondelete='CASCADE'), + sa.ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id'], ), + sa.PrimaryKeyConstraint('id', name='pedimento_validation_pkey'), + sa.UniqueConstraint('pedimento_id', name='pedimento_validation_pedimento_id_key'), + schema='a76' + ) + op.create_index(op.f('ix_a76_pedimento_validation_tenant_id'), 'pedimento_validation', ['tenant_id'], unique=False, schema='a76') + op.drop_constraint(op.f('fk_regimenped'), 'code_pedimento_regimens', type_='foreignkey') + op.drop_constraint(op.f('fk_codeped'), 'code_pedimento_regimens', type_='foreignkey') + op.create_foreign_key('fk_codeped', 'code_pedimento_regimens', 'pedimento_codes', ['pedimento_code'], ['code'], source_schema='public', referent_schema='public') + op.create_foreign_key('fk_regimenped', 'code_pedimento_regimens', 'pedimento_regimens', ['regimen_code'], ['code'], source_schema='public', referent_schema='public') + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.drop_constraint('fk_regimenped', 'code_pedimento_regimens', schema='public', type_='foreignkey') + op.drop_constraint('fk_codeped', 'code_pedimento_regimens', schema='public', type_='foreignkey') + op.create_foreign_key(op.f('fk_codeped'), 'code_pedimento_regimens', 'pedimento_codes', ['pedimento_code'], ['code']) + op.create_foreign_key(op.f('fk_regimenped'), 'code_pedimento_regimens', 'pedimento_regimens', ['regimen_code'], ['code']) + op.drop_index(op.f('ix_a76_pedimento_validation_tenant_id'), table_name='pedimento_validation', schema='a76') + op.drop_table('pedimento_validation', schema='a76') + op.drop_index(op.f('ix_a76_pedimento_transport_means_tenant_id'), table_name='pedimento_transport_means', schema='a76') + op.drop_table('pedimento_transport_means', schema='a76') + op.drop_index(op.f('ix_a76_pedimento_rectification_origin_tenant_id'), table_name='pedimento_rectification_origin', schema='a76') + op.drop_table('pedimento_rectification_origin', schema='a76') + op.drop_index(op.f('ix_a76_pedimento_rectification_destination_tenant_id'), table_name='pedimento_rectification_destination', schema='a76') + op.drop_table('pedimento_rectification_destination', schema='a76') + op.drop_index(op.f('ix_a76_pedimento_payments_tenant_id'), table_name='pedimento_payments', schema='a76') + op.drop_index('idx_pedimento_payments_pedimento_id', table_name='pedimento_payments', schema='a76') + op.drop_table('pedimento_payments', schema='a76') + op.drop_index(op.f('ix_a76_pedimento_indexes_tenant_id'), table_name='pedimento_indexes', schema='a76') + op.drop_table('pedimento_indexes', schema='a76') + op.drop_index(op.f('ix_a76_pedimento_incrementables_tenant_id'), table_name='pedimento_incrementables', schema='a76') + op.drop_table('pedimento_incrementables', schema='a76') + op.drop_index(op.f('ix_a76_pedimento_decrementables_tenant_id'), table_name='pedimento_decrementables', schema='a76') + op.drop_table('pedimento_decrementables', schema='a76') + op.drop_index(op.f('ix_a76_pedimento_dates_tenant_id'), table_name='pedimento_dates', schema='a76') + op.drop_index('idx_pedimento_dates_pedimento_id', table_name='pedimento_dates', schema='a76') + op.drop_table('pedimento_dates', schema='a76') + op.drop_index(op.f('ix_a76_pedimento_customs_offices_tenant_id'), table_name='pedimento_customs_offices', schema='a76') + op.drop_table('pedimento_customs_offices', schema='a76') + op.drop_index(op.f('ix_a76_pedimento_config_updates_tenant_id'), table_name='pedimento_config_updates', schema='a76') + op.drop_table('pedimento_config_updates', schema='a76') + op.drop_index(op.f('ix_a76_pedimento_config_update_rectification_tenant_id'), table_name='pedimento_config_update_rectification', schema='a76') + op.drop_table('pedimento_config_update_rectification', schema='a76') + op.drop_index(op.f('ix_a76_pedimento_config_surcharges_tenant_id'), table_name='pedimento_config_surcharges', schema='a76') + op.drop_table('pedimento_config_surcharges', schema='a76') + op.drop_index(op.f('ix_a76_pedimento_config_parameters_tenant_id'), table_name='pedimento_config_parameters', schema='a76') + op.drop_table('pedimento_config_parameters', schema='a76') + op.drop_index(op.f('ix_a76_pedimento_config_calculations_tenant_id'), table_name='pedimento_config_calculations', schema='a76') + op.drop_table('pedimento_config_calculations', schema='a76') + op.drop_index(op.f('ix_a76_pedimento_config_additional_tenant_id'), table_name='pedimento_config_additional', schema='a76') + op.drop_table('pedimento_config_additional', schema='a76') + op.drop_index(op.f('ix_a76_pedimentos_tenant_id'), table_name='pedimentos', schema='a76') + op.drop_index('idx_pedimentos_status', table_name='pedimentos', schema='a76') + op.drop_index('idx_pedimentos_created_at', table_name='pedimentos', schema='a76') + op.drop_index('idx_pedimentos_client_id', table_name='pedimentos', schema='a76') + op.drop_table('pedimentos', schema='a76') + op.drop_index(op.f('ix_a76_licenses_tenant_id'), table_name='licenses', schema='a76') + op.drop_index(op.f('ix_a76_licenses_id'), table_name='licenses', schema='a76') + op.drop_table('licenses', schema='a76') + op.drop_index(op.f('ix_a76_license_usage_tenant_id'), table_name='license_usage', schema='a76') + op.drop_index(op.f('ix_a76_license_usage_id'), table_name='license_usage', schema='a76') + op.drop_table('license_usage', schema='a76') + op.drop_index(op.f('ix_a76_tenants_slug'), table_name='tenants', schema='a76') + op.drop_index(op.f('ix_a76_tenants_name'), table_name='tenants', schema='a76') + op.drop_index(op.f('ix_a76_tenants_id'), table_name='tenants', schema='a76') + op.drop_table('tenants', schema='a76') + # ### end Alembic commands ### diff --git a/backend/api/v1/modules/a76/licenses/routes.py b/backend/api/v1/modules/a76/licenses/routes.py index 2703840b..730cbade 100644 --- a/backend/api/v1/modules/a76/licenses/routes.py +++ b/backend/api/v1/modules/a76/licenses/routes.py @@ -15,7 +15,7 @@ from .dto import ( ) from .service import LicenseService -router = APIRouter(prefix="/licenses", tags=["Licenses"]) +router = APIRouter(prefix="/licenses") @router.post("/", response_model=LicenseResponseDTO, status_code=201) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_additional.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_additional.py new file mode 100644 index 00000000..5e372c0f --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_additional.py @@ -0,0 +1,38 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from datetime import datetime + + +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(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(None, description="Enable import invoice recipient") + send_502_validation_file_for_consolidated: Optional[int] = Field(None, description="Send 502 validation file for consolidated") + add_remove_norms: Optional[int] = Field(None, description="Add/remove norms") + + +class PedimentoConfigAdditionalCreate(PedimentoConfigAdditionalBase): + """Schema for creating a new Pedimento Config Additional""" + pass + + +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 + 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 + + +class PedimentoConfigAdditionalResponse(PedimentoConfigAdditionalBase): + """Schema for Pedimento Config Additional response""" + id: int + created_at: datetime + + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_calculations.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_calculations.py new file mode 100644 index 00000000..a9289d75 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_calculations.py @@ -0,0 +1,46 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from datetime import datetime + + +class PedimentoConfigCalculationsBase(BaseModel): + """Base schema for Pedimento Config Calculations""" + pedimento_id: int = Field(..., description="Pedimento ID") + tenant_id: int = Field(..., 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") + 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") + fixed_vehicle_dta_fee: Optional[int] = Field(None, description="Fixed vehicle DTA fee") + additional_fixed_fee: Optional[int] = Field(None, description="Additional fixed fee") + additional_fixed_fee_payment_method: Optional[int] = Field(None, description="Additional fixed fee payment method") + + +class PedimentoConfigCalculationsCreate(PedimentoConfigCalculationsBase): + """Schema for creating a new Pedimento Config Calculations""" + pass + + +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_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 + additional_fixed_fee: Optional[int] = None + additional_fixed_fee_payment_method: Optional[int] = None + + +class PedimentoConfigCalculationsResponse(PedimentoConfigCalculationsBase): + """Schema for Pedimento Config Calculations response""" + id: int + created_at: datetime + + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_parameters.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_parameters.py new file mode 100644 index 00000000..3590a24b --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_parameters.py @@ -0,0 +1,49 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from decimal import Decimal +from datetime import datetime + + +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") + 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") + customs_value_calculation: Optional[int] = Field(None, description="Customs value calculation") + two_decimals_unit_value: Optional[int] = Field(None, description="Two decimals unit value") + customs_value_per_item: Optional[int] = Field(None, description="Customs value per item") + is_national_supplier: Optional[int] = Field(None, description="Is national supplier") + is_consolidated: Optional[int] = Field(None, description="Is consolidated") + + +class PedimentoConfigParametersCreate(PedimentoConfigParametersBase): + """Schema for creating a new Pedimento Config Parameters""" + pass + + +class PedimentoConfigParametersUpdate(BaseModel): + """Schema for updating a Pedimento Config Parameters""" + is_embassy: Optional[int] = 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 + + +class PedimentoConfigParametersResponse(PedimentoConfigParametersBase): + """Schema for Pedimento Config Parameters response""" + id: int + created_at: datetime + + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_surcharges.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_surcharges.py new file mode 100644 index 00000000..36b4e5f4 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_surcharges.py @@ -0,0 +1,38 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from datetime import datetime + + +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") + + +class PedimentoConfigSurchargesCreate(PedimentoConfigSurchargesBase): + """Schema for creating a new Pedimento Config Surcharges""" + pass + + +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 + + +class PedimentoConfigSurchargesResponse(PedimentoConfigSurchargesBase): + """Schema for Pedimento Config Surcharges response""" + id: int + created_at: datetime + + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_update_rectification.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_update_rectification.py new file mode 100644 index 00000000..08af0bb9 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_update_rectification.py @@ -0,0 +1,36 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from datetime import datetime + + +class PedimentoConfigUpdateRectificationBase(BaseModel): + """Base schema for Pedimento Config Update Rectification""" + pedimento_id: int = Field(..., description="Pedimento ID") + tenant_id: int = Field(..., description="Tenant ID") + 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") + calculate_surcharge: Optional[int] = Field(None, description="Calculate surcharge") + + +class PedimentoConfigUpdateRectificationCreate(PedimentoConfigUpdateRectificationBase): + """Schema for creating a new Pedimento Config Update Rectification""" + pass + + +class PedimentoConfigUpdateRectificationUpdate(BaseModel): + """Schema for updating a Pedimento Config Update Rectification""" + update_vat: Optional[int] = None + update_advalorem: Optional[int] = None + update_cc: Optional[int] = None + update_ieps: Optional[int] = None + calculate_surcharge: Optional[int] = None + + +class PedimentoConfigUpdateRectificationResponse(PedimentoConfigUpdateRectificationBase): + """Schema for Pedimento Config Update Rectification response""" + id: int + created_at: datetime + + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_updates.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_updates.py new file mode 100644 index 00000000..a1fda392 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_config_updates.py @@ -0,0 +1,34 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from datetime import datetime + + +class PedimentoConfigUpdatesBase(BaseModel): + """Base schema for Pedimento Config Updates""" + pedimento_id: int = Field(..., description="Pedimento ID") + tenant_id: int = Field(..., description="Tenant ID") + 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") + + +class PedimentoConfigUpdatesCreate(PedimentoConfigUpdatesBase): + """Schema for creating a new Pedimento Config Updates""" + pass + + +class PedimentoConfigUpdatesUpdate(BaseModel): + """Schema for updating a Pedimento Config Updates""" + update_vat: Optional[int] = None + update_advalorem: Optional[int] = None + update_cc: Optional[int] = None + update_ieps: Optional[int] = None + + +class PedimentoConfigUpdatesResponse(PedimentoConfigUpdatesBase): + """Schema for Pedimento Config Updates response""" + id: int + created_at: datetime + + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_customs_offices.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_customs_offices.py new file mode 100644 index 00000000..108cf979 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_customs_offices.py @@ -0,0 +1,30 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from datetime import datetime + + +class PedimentoCustomsOfficesBase(BaseModel): + """Base schema for Pedimento Customs Offices""" + pedimento_id: int = Field(..., description="Pedimento ID") + tenant_id: int = Field(..., description="Tenant ID") + dispatch_customs: Optional[str] = Field(None, max_length=3, description="Dispatch customs") + entry_exit_customs: Optional[str] = Field(None, max_length=3, description="Entry/exit customs") + + +class PedimentoCustomsOfficesCreate(PedimentoCustomsOfficesBase): + """Schema for creating a new Pedimento Customs Offices""" + pass + + +class PedimentoCustomsOfficesUpdate(BaseModel): + """Schema for updating a Pedimento Customs Offices""" + dispatch_customs: Optional[str] = Field(None, max_length=3) + entry_exit_customs: Optional[str] = Field(None, max_length=3) + + +class PedimentoCustomsOfficesResponse(PedimentoCustomsOfficesBase): + """Schema for Pedimento Customs Offices response""" + id: int + created_at: datetime + + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_dates.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_dates.py new file mode 100644 index 00000000..7cf2f9dc --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_dates.py @@ -0,0 +1,50 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from datetime import datetime, time + + +class PedimentoDatesBase(BaseModel): + """Base schema for Pedimento Dates""" + pedimento_id: int = Field(..., description="Pedimento ID") + tenant_id: int = Field(..., description="Tenant ID") + entry_date: Optional[datetime] = Field(None, description="Entry date") + pedimento_date: Optional[datetime] = Field(None, description="Pedimento date") + payment_date: Optional[datetime] = Field(None, description="Payment date") + rectification_payment_date: Optional[datetime] = Field(None, description="Rectification payment date") + extraction_date: Optional[datetime] = Field(None, description="Extraction date") + submission_date: Optional[datetime] = Field(None, description="Submission date") + eucan_date: Optional[datetime] = Field(None, description="EUCAN date") + original_date: Optional[datetime] = Field(None, description="Original date") + start_date: Optional[datetime] = Field(None, description="Start date") + end_date: Optional[datetime] = Field(None, description="End date") + capture_date: Optional[datetime] = Field(None, description="Capture date") + capture_time: Optional[time] = Field(None, description="Capture time") + + +class PedimentoDatesCreate(PedimentoDatesBase): + """Schema for creating a new Pedimento Dates""" + pass + + +class PedimentoDatesUpdate(BaseModel): + """Schema for updating a Pedimento Dates""" + 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 + submission_date: Optional[datetime] = None + eucan_date: Optional[datetime] = None + original_date: Optional[datetime] = None + start_date: Optional[datetime] = None + end_date: Optional[datetime] = None + capture_date: Optional[datetime] = None + capture_time: Optional[time] = None + + +class PedimentoDatesResponse(PedimentoDatesBase): + """Schema for Pedimento Dates response""" + id: int + created_at: datetime + + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_decrementables.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_decrementables.py new file mode 100644 index 00000000..ec76a40e --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_decrementables.py @@ -0,0 +1,45 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from decimal import Decimal +from datetime import datetime + + +class PedimentoDecrementablesBase(BaseModel): + """Base schema for Pedimento Decrementables""" + pedimento_id: int = Field(..., description="Pedimento ID") + tenant_id: int = Field(..., description="Tenant ID") + freight: Optional[Decimal] = Field(None, description="Freight") + insurance: Optional[Decimal] = Field(None, description="Insurance") + loading: Optional[Decimal] = Field(None, description="Loading") + unloading: Optional[Decimal] = Field(None, description="Unloading") + 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(None, description="Not affect USD value") + not_affect_customs_value: Optional[int] = Field(None, description="Not affect customs value") + + +class PedimentoDecrementablesCreate(PedimentoDecrementablesBase): + """Schema for creating a new Pedimento Decrementables""" + pass + + +class PedimentoDecrementablesUpdate(BaseModel): + """Schema for updating a Pedimento Decrementables""" + freight: Optional[Decimal] = None + insurance: Optional[Decimal] = None + loading: Optional[Decimal] = None + unloading: Optional[Decimal] = None + 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 + + +class PedimentoDecrementablesResponse(PedimentoDecrementablesBase): + """Schema for Pedimento Decrementables response""" + id: int + created_at: datetime + + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_incrementables.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_incrementables.py new file mode 100644 index 00000000..fd22d50b --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_incrementables.py @@ -0,0 +1,47 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from decimal import Decimal +from datetime import datetime + + +class PedimentoIncrementablesBase(BaseModel): + """Base schema for Pedimento Incrementables""" + pedimento_id: int = Field(..., description="Pedimento ID") + tenant_id: int = Field(..., 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") + packaging: Optional[Decimal] = Field(None, description="Packaging") + others: Optional[Decimal] = Field(None, description="Others") + 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(None, description="Not affect USD value") + not_affect_customs_value: Optional[int] = Field(None, description="Not affect customs value") + + +class PedimentoIncrementablesCreate(PedimentoIncrementablesBase): + """Schema for creating a new Pedimento Incrementables""" + pass + + +class PedimentoIncrementablesUpdate(BaseModel): + """Schema for updating a Pedimento Incrementables""" + insured_value: Optional[Decimal] = None + freight: Optional[Decimal] = None + insurance: Optional[Decimal] = None + packaging: Optional[Decimal] = None + others: Optional[Decimal] = None + 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 + + +class PedimentoIncrementablesResponse(PedimentoIncrementablesBase): + """Schema for Pedimento Incrementables response""" + id: int + created_at: datetime + + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_indexes.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_indexes.py new file mode 100644 index 00000000..6dd993c9 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_indexes.py @@ -0,0 +1,33 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from decimal import Decimal +from datetime import datetime + + +class PedimentoIndexesBase(BaseModel): + """Base schema for Pedimento Indexes""" + pedimento_id: int = Field(..., description="Pedimento ID") + tenant_id: int = Field(..., 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(None, description="Manual update factor") + + +class PedimentoIndexesCreate(PedimentoIndexesBase): + """Schema for creating a new Pedimento Indexes""" + pass + + +class PedimentoIndexesUpdate(BaseModel): + """Schema for updating a Pedimento Indexes""" + update_factor_type: Optional[int] = None + update_factor: Optional[Decimal] = None + manual_update_factor: Optional[int] = None + + +class PedimentoIndexesResponse(PedimentoIndexesBase): + """Schema for Pedimento Indexes response""" + id: int + created_at: datetime + + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_payments.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_payments.py new file mode 100644 index 00000000..4421637c --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_payments.py @@ -0,0 +1,50 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from datetime import datetime, date as Date, time as Time + + +class PedimentoPaymentsBase(BaseModel): + """Base schema for Pedimento Payments""" + pedimento_id: int = Field(..., description="Pedimento ID") + tenant_id: int = Field(..., description="Tenant ID") + acknowledgment: Optional[str] = Field(None, max_length=20, description="Acknowledgment") + operation_number: Optional[str] = Field(None, max_length=14, description="Operation number") + bank_code: Optional[int] = Field(None, description="Bank code") + cashier: Optional[str] = Field(None, max_length=2, description="Cashier") + date: Optional[Date] = Field(None, description="Date") + time: Optional[Time] = Field(None, description="Time") + shift: Optional[str] = Field(None, max_length=1, description="Shift") + total_cash_paid: Optional[int] = Field(None, description="Total cash paid") + total_contributions: Optional[int] = Field(None, description="Total contributions") + counter_payment: Optional[int] = Field(None, description="Counter payment") + pece_code: Optional[str] = Field(None, max_length=5, description="PECE code") + payment_id: Optional[int] = Field(None, description="Payment ID") + + +class PedimentoPaymentsCreate(PedimentoPaymentsBase): + """Schema for creating a new Pedimento Payments""" + pass + + +class PedimentoPaymentsUpdate(BaseModel): + """Schema for updating a Pedimento Payments""" + acknowledgment: Optional[str] = Field(None, max_length=20) + operation_number: Optional[str] = Field(None, max_length=14) + bank_code: Optional[int] = None + cashier: Optional[str] = Field(None, max_length=2) + date: Optional[Date] = None + time: Optional[Time] = None + shift: Optional[str] = Field(None, max_length=1) + total_cash_paid: Optional[int] = None + total_contributions: Optional[int] = None + counter_payment: Optional[int] = None + pece_code: Optional[str] = Field(None, max_length=5) + payment_id: Optional[int] = None + + +class PedimentoPaymentsResponse(PedimentoPaymentsBase): + """Schema for Pedimento Payments response""" + id: int + created_at: datetime + + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_rectification_destination.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_rectification_destination.py new file mode 100644 index 00000000..1f35d1af --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_rectification_destination.py @@ -0,0 +1,32 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional + + +class PedimentoRectificationDestinationBase(BaseModel): + """Base schema for Pedimento Rectification Destination""" + pedimento_id: int = Field(..., description="Pedimento ID") + tenant_id: int = Field(..., description="Tenant ID") + destination_pedimento_year: Optional[str] = Field(None, max_length=2, description="Destination pedimento year") + destination_customs_office: Optional[str] = Field(None, max_length=3, description="Destination customs office") + destination_license: Optional[str] = Field(None, max_length=4, description="Destination license") + destination_pedimento_number: Optional[str] = Field(None, max_length=7, description="Destination pedimento number") + + +class PedimentoRectificationDestinationCreate(PedimentoRectificationDestinationBase): + """Schema for creating a new Pedimento Rectification Destination""" + pass + + +class PedimentoRectificationDestinationUpdate(BaseModel): + """Schema for updating a Pedimento Rectification Destination""" + destination_pedimento_year: Optional[str] = Field(None, max_length=2) + destination_customs_office: Optional[str] = Field(None, max_length=3) + destination_license: Optional[str] = Field(None, max_length=4) + destination_pedimento_number: Optional[str] = Field(None, max_length=7) + + +class PedimentoRectificationDestinationResponse(PedimentoRectificationDestinationBase): + """Schema for Pedimento Rectification Destination response""" + id: int + + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_rectification_origin.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_rectification_origin.py new file mode 100644 index 00000000..ee8dfeda --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_rectification_origin.py @@ -0,0 +1,51 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from datetime import datetime + + +class PedimentoRectificationOriginBase(BaseModel): + """Base schema for Pedimento Rectification Origin""" + pedimento_id: int = Field(..., description="Pedimento ID") + tenant_id: int = Field(..., description="Tenant ID") + original_pedimento_year: Optional[str] = Field(None, max_length=2, description="Original pedimento year") + original_customs_office: Optional[str] = Field(None, max_length=3, description="Original customs office") + original_license: Optional[str] = Field(None, max_length=4, description="Original license") + original_pedimento_number: Optional[str] = Field(None, max_length=7, description="Original pedimento number") + original_pedimento_key: Optional[str] = Field(None, max_length=2, description="Original pedimento key") + original_payment_date: Optional[datetime] = Field(None, description="Original payment date") + total_cash: Optional[int] = Field(None, description="Total cash") + total_others: Optional[int] = Field(None, description="Total others") + reason: Optional[str] = Field(None, max_length=255, description="Reason") + charge_to_client: Optional[int] = Field(None, description="Charge to client") + use_original_payment_date_for_interest_calc: Optional[int] = Field(None, description="Use original payment date for interest calculation") + manual_calculation: Optional[int] = Field(None, description="Manual calculation") + original_pedimento_norms: Optional[int] = Field(None, description="Original pedimento norms") + + +class PedimentoRectificationOriginCreate(PedimentoRectificationOriginBase): + """Schema for creating a new Pedimento Rectification Origin""" + pass + + +class PedimentoRectificationOriginUpdate(BaseModel): + """Schema for updating a Pedimento Rectification Origin""" + original_pedimento_year: Optional[str] = Field(None, max_length=2) + original_customs_office: Optional[str] = Field(None, max_length=3) + original_license: Optional[str] = Field(None, max_length=4) + original_pedimento_number: Optional[str] = Field(None, max_length=7) + original_pedimento_key: Optional[str] = Field(None, max_length=2) + original_payment_date: Optional[datetime] = None + total_cash: Optional[int] = None + total_others: Optional[int] = None + reason: Optional[str] = Field(None, max_length=255) + charge_to_client: Optional[int] = None + use_original_payment_date_for_interest_calc: Optional[int] = None + manual_calculation: Optional[int] = None + original_pedimento_norms: Optional[int] = None + + +class PedimentoRectificationOriginResponse(PedimentoRectificationOriginBase): + """Schema for Pedimento Rectification Origin response""" + id: int + + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_transport_means.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_transport_means.py new file mode 100644 index 00000000..3bec5e34 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_transport_means.py @@ -0,0 +1,34 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from datetime import datetime + + +class PedimentoTransportMeansBase(BaseModel): + """Base schema for Pedimento Transport Means""" + pedimento_id: int = Field(..., description="Pedimento ID") + tenant_id: int = Field(..., description="Tenant ID") + destination: Optional[int] = Field(None, description="Destination") + entry_exit: Optional[str] = Field(None, max_length=2, description="Entry/exit") + arrival: Optional[str] = Field(None, max_length=2, description="Arrival") + departure: Optional[str] = Field(None, max_length=2, description="Departure") + + +class PedimentoTransportMeansCreate(PedimentoTransportMeansBase): + """Schema for creating a new Pedimento Transport Means""" + pass + + +class PedimentoTransportMeansUpdate(BaseModel): + """Schema for updating a Pedimento Transport Means""" + destination: Optional[int] = None + entry_exit: Optional[str] = Field(None, max_length=2) + arrival: Optional[str] = Field(None, max_length=2) + departure: Optional[str] = Field(None, max_length=2) + + +class PedimentoTransportMeansResponse(PedimentoTransportMeansBase): + """Schema for Pedimento Transport Means response""" + id: int + created_at: datetime + + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_validation.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_validation.py new file mode 100644 index 00000000..817394e5 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimento_validation.py @@ -0,0 +1,42 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from datetime import datetime + + +class PedimentoValidationBase(BaseModel): + """Base schema for Pedimento Validation""" + pedimento_id: int = Field(..., description="Pedimento ID") + tenant_id: int = Field(..., 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") + pre_ack: Optional[str] = Field(None, max_length=8, description="Pre-acknowledgment") + line_signature: Optional[str] = Field(None, max_length=50, description="Line signature") + electronic_signature: Optional[str] = Field(None, max_length=999, description="Electronic signature") + certificate_number: Optional[str] = Field(None, max_length=99, description="Certificate number") + validator_id: Optional[int] = Field(None, description="Validator ID") + responsible_id: Optional[int] = Field(None, description="Responsible ID") + + +class PedimentoValidationCreate(PedimentoValidationBase): + """Schema for creating a new Pedimento Validation""" + pass + + +class PedimentoValidationUpdate(BaseModel): + """Schema for updating a Pedimento Validation""" + validator: Optional[str] = Field(None, max_length=3) + validation_ack: Optional[str] = Field(None, max_length=8) + pre_ack: Optional[str] = Field(None, max_length=8) + line_signature: Optional[str] = Field(None, max_length=50) + electronic_signature: Optional[str] = Field(None, max_length=999) + certificate_number: Optional[str] = Field(None, max_length=99) + validator_id: Optional[int] = None + responsible_id: Optional[int] = None + + +class PedimentoValidationResponse(PedimentoValidationBase): + """Schema for Pedimento Validation response""" + id: int + created_at: datetime + + model_config = ConfigDict(from_attributes=True) diff --git a/backend/api/v1/modules/a76/pedmientos/dtos/pedimentos.py b/backend/api/v1/modules/a76/pedmientos/dtos/pedimentos.py new file mode 100644 index 00000000..6ac4c4cf --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/dtos/pedimentos.py @@ -0,0 +1,54 @@ +from pydantic import BaseModel, Field, ConfigDict +from typing import Optional +from decimal import Decimal +from datetime import datetime + + +class PedimentosBase(BaseModel): + """Base schema for Pedimentos""" + year: Optional[str] = Field(None, max_length=2, description="Year") + customs_office: Optional[str] = Field(None, max_length=2, description="Customs office") + license: Optional[str] = Field(None, max_length=4, description="License") + pedimento_number: Optional[str] = Field(None, max_length=7, description="Pedimento number") + client_id: Optional[int] = Field(None, description="Client ID") + operation_type: Optional[int] = Field(None, description="Operation type") + pedimento_type: Optional[int] = Field(None, description="Pedimento type") + pedimento_key: Optional[str] = Field(None, max_length=2, description="Pedimento key") + regime: Optional[str] = Field(None, max_length=3, description="Regime") + status: Optional[str] = Field(None, max_length=30, description="Status") + 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") + + +class PedimentosCreate(PedimentosBase): + """Schema for creating a new Pedimento""" + pass + + +class PedimentosUpdate(BaseModel): + """Schema for updating a Pedimento""" + year: Optional[str] = Field(None, max_length=2) + customs_office: Optional[str] = Field(None, max_length=2) + license: Optional[str] = Field(None, max_length=4) + pedimento_number: Optional[str] = Field(None, max_length=7) + client_id: Optional[int] = None + operation_type: Optional[int] = None + pedimento_type: Optional[int] = None + pedimento_key: Optional[str] = Field(None, max_length=2) + regime: Optional[str] = Field(None, max_length=3) + status: Optional[str] = Field(None, max_length=30) + usd_value: Optional[Decimal] = None + paid_price: Optional[Decimal] = None + gross_weight: Optional[Decimal] = None + exchange_rate: Optional[Decimal] = None + + +class PedimentosResponse(PedimentosBase): + """Schema for Pedimento response""" + id: int + tenant_id: int + created_at: datetime + + model_config = ConfigDict(from_attributes=True) 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 new file mode 100644 index 00000000..78ee3907 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_additional.py @@ -0,0 +1,27 @@ +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 PedimentoConfigAdditional(Base): + __tablename__ = 'pedimento_config_additional' + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], ondelete='CASCADE', name='fk_pedimento_config_additional'), + PrimaryKeyConstraint('id', name='pedimento_config_additional_pkey'), + UniqueConstraint('pedimento_id', name='pedimento_config_additional_pedimento_id_key'), + {'schema': 'a76'} + ) + + id = mapped_column(Integer) + pedimento_id = mapped_column(Integer, nullable=False) + tenant_id = mapped_column(Integer, nullable=False, index=True) + add_po_identifier = mapped_column(SmallInteger) + do_not_exempt_norms_complement_x = mapped_column(SmallInteger) + manual_pedimento_year = mapped_column(String(2)) + 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')) + + 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 new file mode 100644 index 00000000..da711625 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_calculations.py @@ -0,0 +1,31 @@ +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 PedimentoConfigCalculations(Base): + __tablename__ = 'pedimento_config_calculations' + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], ondelete='CASCADE', name='fk_pedimento_config_calculations'), + PrimaryKeyConstraint('id', name='pedimento_config_calculations_pkey'), + UniqueConstraint('pedimento_id', name='pedimento_config_calculations_pedimento_id_key'), + {'schema': 'a76'} + ) + + id = mapped_column(Integer) + pedimento_id = mapped_column(Integer, nullable=False) + tenant_id = mapped_column(Integer, nullable=False, index=True) + dta_type = mapped_column(String(1)) + dta_operation = mapped_column(SmallInteger) + dta_vehicle_count = mapped_column(SmallInteger) + dta_mixed_rate_8permil = mapped_column(SmallInteger) + pays_vat = mapped_column(SmallInteger) + pays_prevalidation = mapped_column(SmallInteger) + include_sagar_certificate_fee = mapped_column(SmallInteger) + 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')) + + 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 new file mode 100644 index 00000000..bce09458 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_parameters.py @@ -0,0 +1,33 @@ +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, Numeric, PrimaryKeyConstraint, SmallInteger, UniqueConstraint, text +from sqlalchemy.orm import Mapped, mapped_column, relationship +from sqlalchemy.orm.base import Mapped +from core.database import Base + + +class PedimentoConfigParameters(Base): + __tablename__ = 'pedimento_config_parameters' + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], ondelete='CASCADE', name='fk_pedimento_config_parameters'), + PrimaryKeyConstraint('id', name='pedimento_config_parameters_pkey'), + UniqueConstraint('pedimento_id', name='pedimento_config_parameters_pedimento_id_key'), + {'schema': 'a76'} + ) + + id = mapped_column(Integer) + pedimento_id = mapped_column(Integer, nullable=False) + tenant_id = mapped_column(Integer, nullable=False, index=True) + is_embassy = mapped_column(SmallInteger) + embassy_dta = mapped_column(Numeric(11, 2)) + rule_3121_section_ii = mapped_column(SmallInteger) + use_previous_tariff = mapped_column(SmallInteger) + use_payment_date_fi = mapped_column(SmallInteger) + add_state_supplier_record_505 = mapped_column(SmallInteger) + customs_value_calculation = mapped_column(SmallInteger) + two_decimals_unit_value = mapped_column(SmallInteger) + 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')) + + 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 new file mode 100644 index 00000000..1ba6e0d6 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_surcharges.py @@ -0,0 +1,27 @@ +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, SmallInteger, UniqueConstraint, text +from sqlalchemy.orm import Mapped, mapped_column, relationship +from sqlalchemy.orm.base import Mapped +from core.database import Base + +class PedimentoConfigSurcharges(Base): + __tablename__ = 'pedimento_config_surcharges' + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], ondelete='CASCADE', name='fk_pedimento_config_surcharges'), + PrimaryKeyConstraint('id', name='pedimento_config_surcharges_pkey'), + UniqueConstraint('pedimento_id', name='pedimento_config_surcharges_pedimento_id_key'), + {'schema': 'a76'} + ) + + id = mapped_column(Integer) + pedimento_id = mapped_column(Integer, nullable=False) + tenant_id = mapped_column(Integer, nullable=False, index=True) + surcharge_igi = mapped_column(SmallInteger) + surcharge_dta = mapped_column(SmallInteger) + surcharge_vat = mapped_column(SmallInteger) + 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')) + + 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 new file mode 100644 index 00000000..f7e1ea42 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_update_rectification.py @@ -0,0 +1,26 @@ +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, SmallInteger, UniqueConstraint, text +from sqlalchemy.orm import Mapped, mapped_column, relationship +from sqlalchemy.orm.base import Mapped +from core.database import Base + +class PedimentoConfigUpdateRectification(Base): + __tablename__ = 'pedimento_config_update_rectification' + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], ondelete='CASCADE', name='fk_pedimento_config_update_rectification'), + PrimaryKeyConstraint('id', name='pedimento_config_update_rectification_pkey'), + UniqueConstraint('pedimento_id', name='pedimento_config_update_rectification_pedimento_id_key'), + {'schema': 'a76'} + ) + + id = mapped_column(Integer) + pedimento_id = mapped_column(Integer, nullable=False) + tenant_id = mapped_column(Integer, nullable=False, index=True) + update_vat = mapped_column(SmallInteger) + update_advalorem = mapped_column(SmallInteger) + 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')) + + 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 new file mode 100644 index 00000000..1fcedb8c --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_config_updates.py @@ -0,0 +1,25 @@ +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, SmallInteger, UniqueConstraint, text +from sqlalchemy.orm import Mapped, mapped_column, relationship +from sqlalchemy.orm.base import Mapped +from core.database import Base + +class PedimentoConfigUpdates(Base): + __tablename__ = 'pedimento_config_updates' + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], ondelete='CASCADE', name='fk_pedimento_config_updates'), + PrimaryKeyConstraint('id', name='pedimento_config_updates_pkey'), + UniqueConstraint('pedimento_id', name='pedimento_config_updates_pedimento_id_key'), + {'schema': 'a76'} + ) + + id = mapped_column(Integer) + pedimento_id = mapped_column(Integer, nullable=False) + tenant_id = mapped_column(Integer, nullable=False, index=True) + update_vat = mapped_column(SmallInteger) + 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')) + + 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 new file mode 100644 index 00000000..f6af5419 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_customs_offices.py @@ -0,0 +1,23 @@ +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, String, UniqueConstraint, text +from sqlalchemy.orm import Mapped, mapped_column, relationship +from sqlalchemy.orm.base import Mapped +from core.database import Base + +class PedimentoCustomsOffices(Base): + __tablename__ = 'pedimento_customs_offices' + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], ondelete='CASCADE', name='fk_pedimento_customs_offices'), + PrimaryKeyConstraint('id', name='pedimento_customs_offices_pkey'), + UniqueConstraint('pedimento_id', name='pedimento_customs_offices_pedimento_id_key'), + {'schema': 'a76'} + ) + + id = mapped_column(Integer) + pedimento_id = mapped_column(Integer, nullable=False) + 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')) + + 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 new file mode 100644 index 00000000..406974c2 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_dates.py @@ -0,0 +1,34 @@ +from sqlalchemy import DateTime, ForeignKeyConstraint, Index, Integer, PrimaryKeyConstraint, Time, UniqueConstraint, text +from sqlalchemy.orm import Mapped, mapped_column, relationship +from sqlalchemy.orm.base import Mapped +from core.database import Base + +class PedimentoDates(Base): + __tablename__ = 'pedimento_dates' + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], ondelete='CASCADE', name='fk_pedimento_dates'), + PrimaryKeyConstraint('id', name='pedimento_dates_pkey'), + UniqueConstraint('pedimento_id', name='pedimento_dates_pedimento_id_key'), + Index('idx_pedimento_dates_pedimento_id', 'pedimento_id'), + {'schema': 'a76'} + ) + + id = mapped_column(Integer) + pedimento_id = mapped_column(Integer, nullable=False) + tenant_id = mapped_column(Integer, nullable=False, index=True) + entry_date = mapped_column(DateTime) + pedimento_date = mapped_column(DateTime) + payment_date = mapped_column(DateTime) + rectification_payment_date = mapped_column(DateTime) + extraction_date = mapped_column(DateTime) + submission_date = mapped_column(DateTime) + eucan_date = mapped_column(DateTime) + original_date = mapped_column(DateTime) + start_date = mapped_column(DateTime) + 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')) + + 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 new file mode 100644 index 00000000..04376b85 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_decrementables.py @@ -0,0 +1,30 @@ +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, Numeric, 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 PedimentoDecrementables(Base): + __tablename__ = 'pedimento_decrementables' + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], ondelete='CASCADE', name='fk_pedimento_decrementables'), + PrimaryKeyConstraint('id', name='pedimento_decrementables_pkey'), + UniqueConstraint('pedimento_id', name='pedimento_decrementables_pedimento_id_key'), + {'schema': 'a76'} + ) + + id = mapped_column(Integer) + pedimento_id = mapped_column(Integer, nullable=False) + tenant_id = mapped_column(Integer, nullable=False, index=True) + freight = mapped_column(Numeric(13, 2)) + insurance = mapped_column(Numeric(13, 2)) + loading = mapped_column(Numeric(13, 2)) + unloading = mapped_column(Numeric(13, 2)) + others = mapped_column(Numeric(13, 2)) + currency = mapped_column(String(3)) + 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')) + + 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 new file mode 100644 index 00000000..44c3f987 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_incrementables.py @@ -0,0 +1,31 @@ +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, Numeric, 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 PedimentoIncrementables(Base): + __tablename__ = 'pedimento_incrementables' + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], ondelete='CASCADE', name='fk_pedimento_incrementables'), + PrimaryKeyConstraint('id', name='pedimento_incrementables_pkey'), + UniqueConstraint('pedimento_id', name='pedimento_incrementables_pedimento_id_key'), + {'schema': 'a76'} + ) + + id = mapped_column(Integer) + pedimento_id = mapped_column(Integer, nullable=False) + tenant_id = mapped_column(Integer, nullable=False, index=True) + insured_value = mapped_column(Numeric(13, 2)) + freight = mapped_column(Numeric(13, 2)) + insurance = mapped_column(Numeric(13, 2)) + packaging = mapped_column(Numeric(13, 2)) + others = mapped_column(Numeric(13, 3)) + deductibles = mapped_column(Numeric(13, 3)) + currency = mapped_column(String(3)) + 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')) + + 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 new file mode 100644 index 00000000..3704e981 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_indexes.py @@ -0,0 +1,24 @@ +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, Numeric, PrimaryKeyConstraint, SmallInteger, UniqueConstraint, text +from sqlalchemy.orm import Mapped, mapped_column, relationship +from sqlalchemy.orm.base import Mapped +from core.database import Base + +class PedimentoIndexes(Base): + __tablename__ = 'pedimento_indexes' + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], ondelete='CASCADE', name='fk_pedimento_indexes'), + PrimaryKeyConstraint('id', name='pedimento_indexes_pkey'), + UniqueConstraint('pedimento_id', name='pedimento_indexes_pedimento_id_key'), + {'schema': 'a76'} + ) + + id = mapped_column(Integer) + pedimento_id = mapped_column(Integer, nullable=False) + tenant_id = mapped_column(Integer, nullable=False, index=True) + 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')) + + 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 new file mode 100644 index 00000000..5360af8b --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_payments.py @@ -0,0 +1,34 @@ +from sqlalchemy import Date, DateTime, ForeignKeyConstraint, Index, Integer, PrimaryKeyConstraint, SmallInteger, String, Time, UniqueConstraint, text +from sqlalchemy.orm import Mapped, mapped_column, relationship +from sqlalchemy.orm.base import Mapped +from core.database import Base + +class PedimentoPayments(Base): + __tablename__ = 'pedimento_payments' + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], ondelete='CASCADE', name='fk_pedimento_payments'), + PrimaryKeyConstraint('id', name='pedimento_payments_pkey'), + UniqueConstraint('pedimento_id', name='pedimento_payments_pedimento_id_key'), + Index('idx_pedimento_payments_pedimento_id', 'pedimento_id'), + {'schema': 'a76'} + ) + + id = mapped_column(Integer) + pedimento_id = mapped_column(Integer, nullable=False) + tenant_id = mapped_column(Integer, nullable=False, index=True) + acknowledgment = mapped_column(String(20)) + operation_number = mapped_column(String(14)) + bank_code = mapped_column(Integer) + cashier = mapped_column(String(2)) + date = mapped_column(Date) + time = mapped_column(Time) + shift = mapped_column(String(1)) + total_cash_paid = mapped_column(Integer) + total_contributions = mapped_column(Integer) + 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')) + + 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 new file mode 100644 index 00000000..6b4a18fa --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_rectification_destination.py @@ -0,0 +1,24 @@ +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 + +class PedimentoRectificationDestination(Base): + __tablename__ = 'pedimento_rectification_destination' + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], ondelete='CASCADE', name='fk_pedimento_rectification_destination'), + PrimaryKeyConstraint('id', name='pedimento_rectification_destination_pkey'), + UniqueConstraint('pedimento_id', name='pedimento_rectification_destination_pedimento_id_key'), + {'schema': 'a76'} + ) + + id = mapped_column(Integer) + pedimento_id = mapped_column(Integer, nullable=False) + tenant_id = mapped_column(Integer, nullable=False, index=True) + destination_pedimento_year = mapped_column(String(2)) + destination_customs_office = mapped_column(String(3)) + destination_license = mapped_column(String(4)) + destination_pedimento_number = mapped_column(String(7)) + + pedimento: Mapped['Pedimentos'] = relationship('Pedimentos', back_populates='pedimento_rectification_destination') \ No newline at end of file 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 new file mode 100644 index 00000000..9e92068f --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_rectification_origin.py @@ -0,0 +1,33 @@ +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 + +class PedimentoRectificationOrigin(Base): + __tablename__ = 'pedimento_rectification_origin' + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], ondelete='CASCADE', name='fk_pedimento_rectification_origin'), + PrimaryKeyConstraint('id', name='pedimento_rectification_origin_pkey'), + UniqueConstraint('pedimento_id', name='pedimento_rectification_origin_pedimento_id_key'), + {'schema': 'a76'} + ) + + id = mapped_column(Integer) + pedimento_id = mapped_column(Integer, nullable=False) + tenant_id = mapped_column(Integer, nullable=False, index=True) + original_pedimento_year = mapped_column(String(2)) + original_customs_office = mapped_column(String(3)) + original_license = mapped_column(String(4)) + original_pedimento_number = mapped_column(String(7)) + original_pedimento_key = mapped_column(String(2)) + original_payment_date = mapped_column(DateTime) + total_cash = mapped_column(Integer) + total_others = mapped_column(Integer) + reason = mapped_column(String(255)) + charge_to_client = mapped_column(SmallInteger) + use_original_payment_date_for_interest_calc = mapped_column(SmallInteger) + manual_calculation = mapped_column(SmallInteger) + original_pedimento_norms = mapped_column(SmallInteger) + + pedimento: Mapped['Pedimentos'] = relationship('Pedimentos', back_populates='pedimento_rectification_origin') \ No newline at end of file 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 new file mode 100644 index 00000000..fa3d5508 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_transport_means.py @@ -0,0 +1,25 @@ +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 PedimentoTransportMeans(Base): + __tablename__ = 'pedimento_transport_means' + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + ForeignKeyConstraint(['pedimento_id'], ['a76.pedimentos.id'], ondelete='CASCADE', name='fk_pedimento_transport_means'), + PrimaryKeyConstraint('id', name='pedimento_transport_means_pkey'), + UniqueConstraint('pedimento_id', name='pedimento_transport_means_pedimento_id_key'), + {'schema': 'a76'} + ) + + id = mapped_column(Integer) + pedimento_id = mapped_column(Integer, nullable=False) + tenant_id = mapped_column(Integer, nullable=False, index=True) + destination = mapped_column(SmallInteger) + entry_exit = mapped_column(String(2)) + arrival = mapped_column(String(2)) + departure = mapped_column(String(2)) + created_at = mapped_column(DateTime, server_default=text('CURRENT_TIMESTAMP')) + + pedimento: Mapped['Pedimentos'] = relationship('Pedimentos', back_populates='pedimento_transport_means') \ No newline at end of file diff --git a/backend/api/v1/modules/a76/pedmientos/models/pedimento_validation.py b/backend/api/v1/modules/a76/pedmientos/models/pedimento_validation.py new file mode 100644 index 00000000..9965c08a --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimento_validation.py @@ -0,0 +1,29 @@ +from sqlalchemy import DateTime, ForeignKeyConstraint, Integer, PrimaryKeyConstraint, 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' #PedimentoValidacion + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + 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) + tenant_id = mapped_column(Integer, nullable=False, index=True) + validator = mapped_column(String(3)) #validador + validation_ack = mapped_column(String(8)) #acuse_validacion + pre_ack = mapped_column(String(8)) #acuse_previo + line_signature = mapped_column(String(50)) #firma_linea_captura + electronic_signature = mapped_column(String(999)) #firma_electronica + 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')) + + 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 new file mode 100644 index 00000000..977003d9 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/models/pedimentos.py @@ -0,0 +1,52 @@ +from sqlalchemy import DateTime, ForeignKeyConstraint, Index, Integer, Numeric, PrimaryKeyConstraint, String, text +from sqlalchemy.orm import Mapped, mapped_column, relationship +from sqlalchemy.orm.base import Mapped +from core.database import Base + + +class Pedimentos(Base): + __tablename__ = 'pedimentos' + __table_args__ = ( + ForeignKeyConstraint(['tenant_id'], ['a76.tenants.id']), + PrimaryKeyConstraint('id', name='pedimentos_pkey'), + Index('idx_pedimentos_client_id', 'client_id'), + Index('idx_pedimentos_created_at', 'created_at'), + Index('idx_pedimentos_status', 'status'), + {'schema': 'a76'} + ) + + id = mapped_column(Integer) + tenant_id = mapped_column(Integer, nullable=False, index=True) + year = mapped_column(String(2)) + customs_office = mapped_column(String(2)) + license = mapped_column(String(4)) + pedimento_number = mapped_column(String(7)) + client_id = mapped_column(Integer) + operation_type = mapped_column(Integer) + pedimento_type = mapped_column(Integer) + pedimento_key = mapped_column(String(2)) + regime = mapped_column(String(3)) + status = mapped_column(String(30)) + usd_value = mapped_column(Numeric(17, 6)) + 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')) + + pedimento_config_additional: Mapped['PedimentoConfigAdditional'] = relationship('PedimentoConfigAdditional', uselist=False, back_populates='pedimento') + pedimento_config_calculations: Mapped['PedimentoConfigCalculations'] = relationship('PedimentoConfigCalculations', uselist=False, back_populates='pedimento') + pedimento_config_parameters: Mapped['PedimentoConfigParameters'] = relationship('PedimentoConfigParameters', uselist=False, back_populates='pedimento') + pedimento_config_surcharges: Mapped['PedimentoConfigSurcharges'] = relationship('PedimentoConfigSurcharges', uselist=False, back_populates='pedimento') + pedimento_config_update_rectification: Mapped['PedimentoConfigUpdateRectification'] = relationship('PedimentoConfigUpdateRectification', uselist=False, back_populates='pedimento') + pedimento_config_updates: Mapped['PedimentoConfigUpdates'] = relationship('PedimentoConfigUpdates', uselist=False, back_populates='pedimento') + pedimento_customs_offices: Mapped['PedimentoCustomsOffices'] = relationship('PedimentoCustomsOffices', uselist=False, back_populates='pedimento') + pedimento_dates: Mapped['PedimentoDates'] = relationship('PedimentoDates', uselist=False, back_populates='pedimento') + pedimento_decrementables: Mapped['PedimentoDecrementables'] = relationship('PedimentoDecrementables', uselist=False, back_populates='pedimento') + pedimento_incrementables: Mapped['PedimentoIncrementables'] = relationship('PedimentoIncrementables', uselist=False, back_populates='pedimento') + pedimento_indexes: Mapped['PedimentoIndexes'] = relationship('PedimentoIndexes', uselist=False, back_populates='pedimento') + pedimento_payments: Mapped['PedimentoPayments'] = relationship('PedimentoPayments', uselist=False, back_populates='pedimento') + pedimento_rectification_destination: Mapped['PedimentoRectificationDestination'] = relationship('PedimentoRectificationDestination', uselist=False, back_populates='pedimento') + pedimento_rectification_origin: Mapped['PedimentoRectificationOrigin'] = relationship('PedimentoRectificationOrigin', uselist=False, back_populates='pedimento') + pedimento_transport_means: Mapped['PedimentoTransportMeans'] = relationship('PedimentoTransportMeans', uselist=False, back_populates='pedimento') + pedimento_validation: Mapped['PedimentoValidation'] = relationship('PedimentoValidation', uselist=False, back_populates='pedimento') + diff --git a/backend/api/v1/modules/a76/pedmientos/router.py b/backend/api/v1/modules/a76/pedmientos/router.py new file mode 100644 index 00000000..07084d4f --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/router.py @@ -0,0 +1,39 @@ +from fastapi import APIRouter + +from .routes.pedimento_config_additional import router as pedimento_config_additional_router +from .routes.pedimento_config_calculations import router as pedimento_config_calculations_router +from .routes.pedimento_config_parameters import router as pedimento_config_parameters_router +from .routes.pedimento_config_surcharges import router as pedimento_config_surcharges_router +from .routes.pedimento_config_update_rectification import router as pedimento_config_update_rectification_router +from .routes.pedimento_config_updates import router as pedimento_config_updates_router +from .routes.pedimento_customs_offices import router as pedimento_customs_offices_router +from .routes.pedimento_dates import router as pedimento_dates_router +from .routes.pedimento_decrementables import router as pedimento_decrementables_router +from .routes.pedimento_incrementables import router as pedimento_incrementables_router +from .routes.pedimento_indexes import router as pedimento_indexes_router +from .routes.pedimento_payments import router as pedimento_payments_router +from .routes.pedimento_rectification_destination import router as pedimento_rectification_destination_router +from .routes.pedimento_rectification_origin import router as pedimento_rectification_origin_router +from .routes.pedimento_transport_means import router as pedimento_transport_means_router +from .routes.pedimento_validation import router as pedimento_validation_router +from .routes.pedimentos import router as pedimentos_router + +router = APIRouter() + +router.include_router(pedimento_config_additional_router, prefix="/pedimentos", tags=["a76 / pedimentos / pedimento_config_additional"]) +router.include_router(pedimento_config_calculations_router, prefix="/pedimentos", tags=["a76 / pedimentos / pedimento_config_calculations"]) +router.include_router(pedimento_config_parameters_router, prefix="/pedimentos", tags=["a76 / pedimentos / pedimento_config_parameters"]) +router.include_router(pedimento_config_surcharges_router, prefix="/pedimentos", tags=["a76 / pedimentos / pedimento_config_surcharges"]) +router.include_router(pedimento_config_update_rectification_router, prefix="/pedimentos", tags=["a76 / pedimentos / pedimento_config_update_rectification"]) +router.include_router(pedimento_config_updates_router, prefix="/pedimentos", tags=["a76 / pedimentos / pedimento_config_updates"]) +router.include_router(pedimento_customs_offices_router, prefix="/pedimentos", tags=["a76 / pedimentos / pedimento_customs_offices"]) +router.include_router(pedimento_dates_router, prefix="/pedimentos", tags=["a76 / pedimentos / pedimento_dates"]) +router.include_router(pedimento_decrementables_router, prefix="/pedimentos", tags=["a76 / pedimentos / pedimento_decrementables"]) +router.include_router(pedimento_incrementables_router, prefix="/pedimentos", tags=["a76 / pedimentos / pedimento_incrementables"]) +router.include_router(pedimento_indexes_router, prefix="/pedimentos", tags=["a76 / pedimentos / pedimento_indexes"]) +router.include_router(pedimento_payments_router, prefix="/pedimentos", tags=["a76 / pedimentos / pedimento_payments"]) +router.include_router(pedimento_rectification_destination_router, prefix="/pedimentos", tags=["a76 / pedimentos / pedimento_rectification_destination"]) +router.include_router(pedimento_rectification_origin_router, prefix="/pedimentos", tags=["a76 / pedimentos / pedimento_rectification_origin"]) +router.include_router(pedimento_transport_means_router, prefix="/pedimentos", tags=["a76 / pedimentos / pedimento_transport_means"]) +router.include_router(pedimento_validation_router, prefix="/pedimentos", tags=["a76 / pedimentos / pedimento_validation"]) +router.include_router(pedimentos_router, prefix="/pedimentos", tags=["a76 / pedimentos"]) \ No newline at end of file diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_additional.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_additional.py new file mode 100644 index 00000000..206227c2 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_additional.py @@ -0,0 +1,94 @@ +""" +Routes for PedimentoConfigAdditional CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimento_config_additional import PedimentoConfigAdditionalService +from ..dtos.pedimento_config_additional import ( + PedimentoConfigAdditionalCreate, + PedimentoConfigAdditionalUpdate, + PedimentoConfigAdditionalResponse +) + + +router = APIRouter(prefix="/{pedimento_id}/config-additional") + + +@router.get("/", response_model=PedimentoConfigAdditionalResponse) +async def get_config_additional( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get config additional by pedimento ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + config = PedimentoConfigAdditionalService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + raise HTTPException(status_code=404, detail="Config additional not found") + + return config + + +@router.post("/", response_model=PedimentoConfigAdditionalResponse, status_code=201) +async def create_config_additional( + pedimento_id: int, + data: PedimentoConfigAdditionalCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create config additional""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + # Ensure pedimento_id and tenant_id match + if data.pedimento_id != pedimento_id: + raise HTTPException(status_code=400, detail="Pedimento ID mismatch") + if data.tenant_id != tenant_id: + raise HTTPException(status_code=403, detail="Tenant ID mismatch") + + config = PedimentoConfigAdditionalService.create(db, data) + return config + + +@router.put("/", response_model=PedimentoConfigAdditionalResponse) +async def update_config_additional( + pedimento_id: int, + data: PedimentoConfigAdditionalUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update config additional""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + config = PedimentoConfigAdditionalService.update(db, pedimento_id, tenant_id, data) + if not config: + raise HTTPException(status_code=404, detail="Config additional not found") + + return config + + +@router.delete("/", status_code=204) +async def delete_config_additional( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete config additional""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentoConfigAdditionalService.delete(db, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Config additional not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_calculations.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_calculations.py new file mode 100644 index 00000000..7b65b272 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_calculations.py @@ -0,0 +1,92 @@ +""" +Routes for PedimentoConfigCalculations CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimento_config_calculations import PedimentoConfigCalculationsService +from ..dtos.pedimento_config_calculations import ( + PedimentoConfigCalculationsCreate, + PedimentoConfigCalculationsUpdate, + PedimentoConfigCalculationsResponse +) + + +router = APIRouter(prefix="/{pedimento_id}/config-calculations") + + +@router.get("/", response_model=PedimentoConfigCalculationsResponse) +async def get_config_calculations( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get config calculations by pedimento ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + config = PedimentoConfigCalculationsService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + raise HTTPException(status_code=404, detail="Config calculations not found") + + return config + + +@router.post("/", response_model=PedimentoConfigCalculationsResponse, status_code=201) +async def create_config_calculations( + pedimento_id: int, + data: PedimentoConfigCalculationsCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create config calculations""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + # Ensure pedimento_id matches + if data.pedimento_id != pedimento_id: + raise HTTPException(status_code=400, detail="Pedimento ID mismatch") + + config = PedimentoConfigCalculationsService.create(db, data, tenant_id) + return config + + +@router.put("/", response_model=PedimentoConfigCalculationsResponse) +async def update_config_calculations( + pedimento_id: int, + data: PedimentoConfigCalculationsUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update config calculations""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + config = PedimentoConfigCalculationsService.update(db, pedimento_id, tenant_id, data) + if not config: + raise HTTPException(status_code=404, detail="Config calculations not found") + + return config + + +@router.delete("/", status_code=204) +async def delete_config_calculations( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete config calculations""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentoConfigCalculationsService.delete(db, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Config calculations not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_parameters.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_parameters.py new file mode 100644 index 00000000..92b9b023 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_parameters.py @@ -0,0 +1,92 @@ +""" +Routes for PedimentoConfigParameters CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimento_config_parameters import PedimentoConfigParametersService +from ..dtos.pedimento_config_parameters import ( + PedimentoConfigParametersCreate, + PedimentoConfigParametersUpdate, + PedimentoConfigParametersResponse +) + + +router = APIRouter(prefix="/{pedimento_id}/config-parameters") + + +@router.get("/", response_model=PedimentoConfigParametersResponse) +async def get_config_parameters( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get config parameters by pedimento ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + config = PedimentoConfigParametersService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + raise HTTPException(status_code=404, detail="Config parameters not found") + + return config + + +@router.post("/", response_model=PedimentoConfigParametersResponse, status_code=201) +async def create_config_parameters( + pedimento_id: int, + data: PedimentoConfigParametersCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create config parameters""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + # Ensure pedimento_id matches + if data.pedimento_id != pedimento_id: + raise HTTPException(status_code=400, detail="Pedimento ID mismatch") + + config = PedimentoConfigParametersService.create(db, data, tenant_id) + return config + + +@router.put("/", response_model=PedimentoConfigParametersResponse) +async def update_config_parameters( + pedimento_id: int, + data: PedimentoConfigParametersUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update config parameters""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + config = PedimentoConfigParametersService.update(db, pedimento_id, tenant_id, data) + if not config: + raise HTTPException(status_code=404, detail="Config parameters not found") + + return config + + +@router.delete("/", status_code=204) +async def delete_config_parameters( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete config parameters""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentoConfigParametersService.delete(db, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Config parameters not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_surcharges.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_surcharges.py new file mode 100644 index 00000000..cd5d8417 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_surcharges.py @@ -0,0 +1,92 @@ +""" +Routes for PedimentoConfigSurcharges CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimento_config_surcharges import PedimentoConfigSurchargesService +from ..dtos.pedimento_config_surcharges import ( + PedimentoConfigSurchargesCreate, + PedimentoConfigSurchargesUpdate, + PedimentoConfigSurchargesResponse +) + + +router = APIRouter(prefix="/{pedimento_id}/config-surcharges") + + +@router.get("/", response_model=PedimentoConfigSurchargesResponse) +async def get_config_surcharges( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get config surcharges by pedimento ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + config = PedimentoConfigSurchargesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + raise HTTPException(status_code=404, detail="Config surcharges not found") + + return config + + +@router.post("/", response_model=PedimentoConfigSurchargesResponse, status_code=201) +async def create_config_surcharges( + pedimento_id: int, + data: PedimentoConfigSurchargesCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create config surcharges""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + # Ensure pedimento_id matches + if data.pedimento_id != pedimento_id: + raise HTTPException(status_code=400, detail="Pedimento ID mismatch") + + config = PedimentoConfigSurchargesService.create(db, data, tenant_id) + return config + + +@router.put("/", response_model=PedimentoConfigSurchargesResponse) +async def update_config_surcharges( + pedimento_id: int, + data: PedimentoConfigSurchargesUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update config surcharges""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + config = PedimentoConfigSurchargesService.update(db, pedimento_id, tenant_id, data) + if not config: + raise HTTPException(status_code=404, detail="Config surcharges not found") + + return config + + +@router.delete("/", status_code=204) +async def delete_config_surcharges( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete config surcharges""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentoConfigSurchargesService.delete(db, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Config surcharges not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_update_rectification.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_update_rectification.py new file mode 100644 index 00000000..b537a8a7 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_update_rectification.py @@ -0,0 +1,92 @@ +""" +Routes for PedimentoConfigUpdateRectification CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimento_config_update_rectification import PedimentoConfigUpdateRectificationService +from ..dtos.pedimento_config_update_rectification import ( + PedimentoConfigUpdateRectificationCreate, + PedimentoConfigUpdateRectificationUpdate, + PedimentoConfigUpdateRectificationResponse +) + + +router = APIRouter(prefix="/{pedimento_id}/config-update-rectification") + + +@router.get("/", response_model=PedimentoConfigUpdateRectificationResponse) +async def get_config_update_rectification( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get config update rectification by pedimento ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + config = PedimentoConfigUpdateRectificationService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + raise HTTPException(status_code=404, detail="Config update rectification not found") + + return config + + +@router.post("/", response_model=PedimentoConfigUpdateRectificationResponse, status_code=201) +async def create_config_update_rectification( + pedimento_id: int, + data: PedimentoConfigUpdateRectificationCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create config update rectification""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + # Ensure pedimento_id matches + if data.pedimento_id != pedimento_id: + raise HTTPException(status_code=400, detail="Pedimento ID mismatch") + + config = PedimentoConfigUpdateRectificationService.create(db, data, tenant_id) + return config + + +@router.put("/", response_model=PedimentoConfigUpdateRectificationResponse) +async def update_config_update_rectification( + pedimento_id: int, + data: PedimentoConfigUpdateRectificationUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update config update rectification""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + config = PedimentoConfigUpdateRectificationService.update(db, pedimento_id, tenant_id, data) + if not config: + raise HTTPException(status_code=404, detail="Config update rectification not found") + + return config + + +@router.delete("/", status_code=204) +async def delete_config_update_rectification( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete config update rectification""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentoConfigUpdateRectificationService.delete(db, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Config update rectification not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_updates.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_updates.py new file mode 100644 index 00000000..5ae2c9e7 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_config_updates.py @@ -0,0 +1,92 @@ +""" +Routes for PedimentoConfigUpdates CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimento_config_updates import PedimentoConfigUpdatesService +from ..dtos.pedimento_config_updates import ( + PedimentoConfigUpdatesCreate, + PedimentoConfigUpdatesUpdate, + PedimentoConfigUpdatesResponse +) + + +router = APIRouter(prefix="/{pedimento_id}/config-updates") + + +@router.get("/", response_model=PedimentoConfigUpdatesResponse) +async def get_config_updates( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get config updates by pedimento ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + config = PedimentoConfigUpdatesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + raise HTTPException(status_code=404, detail="Config updates not found") + + return config + + +@router.post("/", response_model=PedimentoConfigUpdatesResponse, status_code=201) +async def create_config_updates( + pedimento_id: int, + data: PedimentoConfigUpdatesCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create config updates""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + # Ensure pedimento_id matches + if data.pedimento_id != pedimento_id: + raise HTTPException(status_code=400, detail="Pedimento ID mismatch") + + config = PedimentoConfigUpdatesService.create(db, data, tenant_id) + return config + + +@router.put("/", response_model=PedimentoConfigUpdatesResponse) +async def update_config_updates( + pedimento_id: int, + data: PedimentoConfigUpdatesUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update config updates""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + config = PedimentoConfigUpdatesService.update(db, pedimento_id, tenant_id, data) + if not config: + raise HTTPException(status_code=404, detail="Config updates not found") + + return config + + +@router.delete("/", status_code=204) +async def delete_config_updates( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete config updates""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentoConfigUpdatesService.delete(db, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Config updates not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimento_customs_offices.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_customs_offices.py new file mode 100644 index 00000000..1bb61d4c --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_customs_offices.py @@ -0,0 +1,111 @@ +""" +Routes for PedimentoCustomsOffices CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from typing import List +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimento_customs_offices import PedimentoCustomsOfficesService +from ..dtos.pedimento_customs_offices import ( + PedimentoCustomsOfficesCreate, + PedimentoCustomsOfficesUpdate, + PedimentoCustomsOfficesResponse +) + + +router = APIRouter(prefix="/{pedimento_id}/customs-offices") + + +@router.get("/", response_model=List[PedimentoCustomsOfficesResponse]) +async def list_customs_offices( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get all customs offices for a pedimento""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + offices = PedimentoCustomsOfficesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + return offices + + +@router.get("/{office_id}", response_model=PedimentoCustomsOfficesResponse) +async def get_customs_office( + pedimento_id: int, + office_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get a specific customs office by ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + office = PedimentoCustomsOfficesService.get_by_id(db, office_id, pedimento_id, tenant_id) + if not office: + raise HTTPException(status_code=404, detail="Customs office not found") + + return office + + +@router.post("/", response_model=PedimentoCustomsOfficesResponse, status_code=201) +async def create_customs_office( + pedimento_id: int, + data: PedimentoCustomsOfficesCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create a new customs office""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + # Ensure pedimento_id matches + if data.pedimento_id != pedimento_id: + raise HTTPException(status_code=400, detail="Pedimento ID mismatch") + + office = PedimentoCustomsOfficesService.create(db, data, tenant_id) + return office + + +@router.put("/{office_id}", response_model=PedimentoCustomsOfficesResponse) +async def update_customs_office( + pedimento_id: int, + office_id: int, + data: PedimentoCustomsOfficesUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update a customs office""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + office = PedimentoCustomsOfficesService.update(db, office_id, pedimento_id, tenant_id, data) + if not office: + raise HTTPException(status_code=404, detail="Customs office not found") + + return office + + +@router.delete("/{office_id}", status_code=204) +async def delete_customs_office( + pedimento_id: int, + office_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete a customs office""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentoCustomsOfficesService.delete(db, office_id, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Customs office not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimento_dates.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_dates.py new file mode 100644 index 00000000..ae83a91e --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_dates.py @@ -0,0 +1,92 @@ +""" +Routes for PedimentoDates CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimento_dates import PedimentoDatesService +from ..dtos.pedimento_dates import ( + PedimentoDatesCreate, + PedimentoDatesUpdate, + PedimentoDatesResponse +) + + +router = APIRouter(prefix="/{pedimento_id}/dates") + + +@router.get("/", response_model=PedimentoDatesResponse) +async def get_dates( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get dates by pedimento ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + dates = PedimentoDatesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not dates: + raise HTTPException(status_code=404, detail="Pedimento dates not found") + + return dates + + +@router.post("/", response_model=PedimentoDatesResponse, status_code=201) +async def create_dates( + pedimento_id: int, + data: PedimentoDatesCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create pedimento dates""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + # Ensure pedimento_id matches + if data.pedimento_id != pedimento_id: + raise HTTPException(status_code=400, detail="Pedimento ID mismatch") + + dates = PedimentoDatesService.create(db, data, tenant_id) + return dates + + +@router.put("/", response_model=PedimentoDatesResponse) +async def update_dates( + pedimento_id: int, + data: PedimentoDatesUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update pedimento dates""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + dates = PedimentoDatesService.update(db, pedimento_id, tenant_id, data) + if not dates: + raise HTTPException(status_code=404, detail="Pedimento dates not found") + + return dates + + +@router.delete("/", status_code=204) +async def delete_dates( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete pedimento dates""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentoDatesService.delete(db, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Pedimento dates not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimento_decrementables.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_decrementables.py new file mode 100644 index 00000000..22a0e868 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_decrementables.py @@ -0,0 +1,111 @@ +""" +Routes for PedimentoDecrementables CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from typing import List +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimento_decrementables import PedimentoDecrementablesService +from ..dtos.pedimento_decrementables import ( + PedimentoDecrementablesCreate, + PedimentoDecrementablesUpdate, + PedimentoDecrementablesResponse +) + + +router = APIRouter(prefix="/{pedimento_id}/decrementables") + + +@router.get("/", response_model=List[PedimentoDecrementablesResponse]) +async def list_decrementables( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get all decrementables for a pedimento""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + decrementables = PedimentoDecrementablesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + return decrementables + + +@router.get("/{decrementable_id}", response_model=PedimentoDecrementablesResponse) +async def get_decrementable( + pedimento_id: int, + decrementable_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get a specific decrementable by ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + decrementable = PedimentoDecrementablesService.get_by_id(db, decrementable_id, pedimento_id, tenant_id) + if not decrementable: + raise HTTPException(status_code=404, detail="Decrementable not found") + + return decrementable + + +@router.post("/", response_model=PedimentoDecrementablesResponse, status_code=201) +async def create_decrementable( + pedimento_id: int, + data: PedimentoDecrementablesCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create a new decrementable""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + # Ensure pedimento_id matches + if data.pedimento_id != pedimento_id: + raise HTTPException(status_code=400, detail="Pedimento ID mismatch") + + decrementable = PedimentoDecrementablesService.create(db, data, tenant_id) + return decrementable + + +@router.put("/{decrementable_id}", response_model=PedimentoDecrementablesResponse) +async def update_decrementable( + pedimento_id: int, + decrementable_id: int, + data: PedimentoDecrementablesUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update a decrementable""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + decrementable = PedimentoDecrementablesService.update(db, decrementable_id, pedimento_id, tenant_id, data) + if not decrementable: + raise HTTPException(status_code=404, detail="Decrementable not found") + + return decrementable + + +@router.delete("/{decrementable_id}", status_code=204) +async def delete_decrementable( + pedimento_id: int, + decrementable_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete a decrementable""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentoDecrementablesService.delete(db, decrementable_id, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Decrementable not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimento_incrementables.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_incrementables.py new file mode 100644 index 00000000..e5cbccab --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_incrementables.py @@ -0,0 +1,111 @@ +""" +Routes for PedimentoIncrementables CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from typing import List +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimento_incrementables import PedimentoIncrementablesService +from ..dtos.pedimento_incrementables import ( + PedimentoIncrementablesCreate, + PedimentoIncrementablesUpdate, + PedimentoIncrementablesResponse +) + + +router = APIRouter(prefix="/{pedimento_id}/incrementables") + + +@router.get("/", response_model=List[PedimentoIncrementablesResponse]) +async def list_incrementables( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get all incrementables for a pedimento""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + incrementables = PedimentoIncrementablesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + return incrementables + + +@router.get("/{incrementable_id}", response_model=PedimentoIncrementablesResponse) +async def get_incrementable( + pedimento_id: int, + incrementable_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get a specific incrementable by ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + incrementable = PedimentoIncrementablesService.get_by_id(db, incrementable_id, pedimento_id, tenant_id) + if not incrementable: + raise HTTPException(status_code=404, detail="Incrementable not found") + + return incrementable + + +@router.post("/", response_model=PedimentoIncrementablesResponse, status_code=201) +async def create_incrementable( + pedimento_id: int, + data: PedimentoIncrementablesCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create a new incrementable""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + # Ensure pedimento_id matches + if data.pedimento_id != pedimento_id: + raise HTTPException(status_code=400, detail="Pedimento ID mismatch") + + incrementable = PedimentoIncrementablesService.create(db, data, tenant_id) + return incrementable + + +@router.put("/{incrementable_id}", response_model=PedimentoIncrementablesResponse) +async def update_incrementable( + pedimento_id: int, + incrementable_id: int, + data: PedimentoIncrementablesUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update an incrementable""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + incrementable = PedimentoIncrementablesService.update(db, incrementable_id, pedimento_id, tenant_id, data) + if not incrementable: + raise HTTPException(status_code=404, detail="Incrementable not found") + + return incrementable + + +@router.delete("/{incrementable_id}", status_code=204) +async def delete_incrementable( + pedimento_id: int, + incrementable_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete an incrementable""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentoIncrementablesService.delete(db, incrementable_id, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Incrementable not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimento_indexes.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_indexes.py new file mode 100644 index 00000000..31e83d8f --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_indexes.py @@ -0,0 +1,92 @@ +""" +Routes for PedimentoIndexes CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimento_indexes import PedimentoIndexesService +from ..dtos.pedimento_indexes import ( + PedimentoIndexesCreate, + PedimentoIndexesUpdate, + PedimentoIndexesResponse +) + + +router = APIRouter(prefix="/{pedimento_id}/indexes") + + +@router.get("/", response_model=PedimentoIndexesResponse) +async def get_indexes( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get indexes by pedimento ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + indexes = PedimentoIndexesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not indexes: + raise HTTPException(status_code=404, detail="Pedimento indexes not found") + + return indexes + + +@router.post("/", response_model=PedimentoIndexesResponse, status_code=201) +async def create_indexes( + pedimento_id: int, + data: PedimentoIndexesCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create pedimento indexes""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + # Ensure pedimento_id matches + if data.pedimento_id != pedimento_id: + raise HTTPException(status_code=400, detail="Pedimento ID mismatch") + + indexes = PedimentoIndexesService.create(db, data, tenant_id) + return indexes + + +@router.put("/", response_model=PedimentoIndexesResponse) +async def update_indexes( + pedimento_id: int, + data: PedimentoIndexesUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update pedimento indexes""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + indexes = PedimentoIndexesService.update(db, pedimento_id, tenant_id, data) + if not indexes: + raise HTTPException(status_code=404, detail="Pedimento indexes not found") + + return indexes + + +@router.delete("/", status_code=204) +async def delete_indexes( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete pedimento indexes""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentoIndexesService.delete(db, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Pedimento indexes not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimento_payments.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_payments.py new file mode 100644 index 00000000..b1ed4eee --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_payments.py @@ -0,0 +1,111 @@ +""" +Routes for PedimentoPayments CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from typing import List +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimento_payments import PedimentoPaymentsService +from ..dtos.pedimento_payments import ( + PedimentoPaymentsCreate, + PedimentoPaymentsUpdate, + PedimentoPaymentsResponse +) + + +router = APIRouter(prefix="/{pedimento_id}/payments") + + +@router.get("/", response_model=List[PedimentoPaymentsResponse]) +async def list_payments( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get all payments for a pedimento""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + payments = PedimentoPaymentsService.get_by_pedimento_id(db, pedimento_id, tenant_id) + return payments + + +@router.get("/{payment_id}", response_model=PedimentoPaymentsResponse) +async def get_payment( + pedimento_id: int, + payment_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get a specific payment by ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + payment = PedimentoPaymentsService.get_by_id(db, payment_id, pedimento_id, tenant_id) + if not payment: + raise HTTPException(status_code=404, detail="Payment not found") + + return payment + + +@router.post("/", response_model=PedimentoPaymentsResponse, status_code=201) +async def create_payment( + pedimento_id: int, + data: PedimentoPaymentsCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create a new payment""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + # Ensure pedimento_id matches + if data.pedimento_id != pedimento_id: + raise HTTPException(status_code=400, detail="Pedimento ID mismatch") + + payment = PedimentoPaymentsService.create(db, data, tenant_id) + return payment + + +@router.put("/{payment_id}", response_model=PedimentoPaymentsResponse) +async def update_payment( + pedimento_id: int, + payment_id: int, + data: PedimentoPaymentsUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update a payment""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + payment = PedimentoPaymentsService.update(db, payment_id, pedimento_id, tenant_id, data) + if not payment: + raise HTTPException(status_code=404, detail="Payment not found") + + return payment + + +@router.delete("/{payment_id}", status_code=204) +async def delete_payment( + pedimento_id: int, + payment_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete a payment""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentoPaymentsService.delete(db, payment_id, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Payment not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimento_rectification_destination.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_rectification_destination.py new file mode 100644 index 00000000..d05fbd30 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_rectification_destination.py @@ -0,0 +1,92 @@ +""" +Routes for PedimentoRectificationDestination CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimento_rectification_destination import PedimentoRectificationDestinationService +from ..dtos.pedimento_rectification_destination import ( + PedimentoRectificationDestinationCreate, + PedimentoRectificationDestinationUpdate, + PedimentoRectificationDestinationResponse +) + + +router = APIRouter(prefix="/{pedimento_id}/rectification-destination") + + +@router.get("/", response_model=PedimentoRectificationDestinationResponse) +async def get_rectification_destination( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get rectification destination by pedimento ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + rectification = PedimentoRectificationDestinationService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not rectification: + raise HTTPException(status_code=404, detail="Rectification destination not found") + + return rectification + + +@router.post("/", response_model=PedimentoRectificationDestinationResponse, status_code=201) +async def create_rectification_destination( + pedimento_id: int, + data: PedimentoRectificationDestinationCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create rectification destination""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + # Ensure pedimento_id matches + if data.pedimento_id != pedimento_id: + raise HTTPException(status_code=400, detail="Pedimento ID mismatch") + + rectification = PedimentoRectificationDestinationService.create(db, data, tenant_id) + return rectification + + +@router.put("/", response_model=PedimentoRectificationDestinationResponse) +async def update_rectification_destination( + pedimento_id: int, + data: PedimentoRectificationDestinationUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update rectification destination""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + rectification = PedimentoRectificationDestinationService.update(db, pedimento_id, tenant_id, data) + if not rectification: + raise HTTPException(status_code=404, detail="Rectification destination not found") + + return rectification + + +@router.delete("/", status_code=204) +async def delete_rectification_destination( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete rectification destination""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentoRectificationDestinationService.delete(db, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Rectification destination not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimento_rectification_origin.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_rectification_origin.py new file mode 100644 index 00000000..1521f371 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_rectification_origin.py @@ -0,0 +1,92 @@ +""" +Routes for PedimentoRectificationOrigin CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimento_rectification_origin import PedimentoRectificationOriginService +from ..dtos.pedimento_rectification_origin import ( + PedimentoRectificationOriginCreate, + PedimentoRectificationOriginUpdate, + PedimentoRectificationOriginResponse +) + + +router = APIRouter(prefix="/{pedimento_id}/rectification-origin") + + +@router.get("/", response_model=PedimentoRectificationOriginResponse) +async def get_rectification_origin( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get rectification origin by pedimento ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + rectification = PedimentoRectificationOriginService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not rectification: + raise HTTPException(status_code=404, detail="Rectification origin not found") + + return rectification + + +@router.post("/", response_model=PedimentoRectificationOriginResponse, status_code=201) +async def create_rectification_origin( + pedimento_id: int, + data: PedimentoRectificationOriginCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create rectification origin""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + # Ensure pedimento_id matches + if data.pedimento_id != pedimento_id: + raise HTTPException(status_code=400, detail="Pedimento ID mismatch") + + rectification = PedimentoRectificationOriginService.create(db, data, tenant_id) + return rectification + + +@router.put("/", response_model=PedimentoRectificationOriginResponse) +async def update_rectification_origin( + pedimento_id: int, + data: PedimentoRectificationOriginUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update rectification origin""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + rectification = PedimentoRectificationOriginService.update(db, pedimento_id, tenant_id, data) + if not rectification: + raise HTTPException(status_code=404, detail="Rectification origin not found") + + return rectification + + +@router.delete("/", status_code=204) +async def delete_rectification_origin( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete rectification origin""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentoRectificationOriginService.delete(db, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Rectification origin not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimento_transport_means.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_transport_means.py new file mode 100644 index 00000000..8365ad2f --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_transport_means.py @@ -0,0 +1,111 @@ +""" +Routes for PedimentoTransportMeans CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from typing import List +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimento_transport_means import PedimentoTransportMeansService +from ..dtos.pedimento_transport_means import ( + PedimentoTransportMeansCreate, + PedimentoTransportMeansUpdate, + PedimentoTransportMeansResponse +) + + +router = APIRouter(prefix="/{pedimento_id}/transport-means") + + +@router.get("/", response_model=List[PedimentoTransportMeansResponse]) +async def list_transport_means( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get all transport means for a pedimento""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + transport_means = PedimentoTransportMeansService.get_by_pedimento_id(db, pedimento_id, tenant_id) + return transport_means + + +@router.get("/{transport_mean_id}", response_model=PedimentoTransportMeansResponse) +async def get_transport_mean( + pedimento_id: int, + transport_mean_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get a specific transport mean by ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + transport_mean = PedimentoTransportMeansService.get_by_id(db, transport_mean_id, pedimento_id, tenant_id) + if not transport_mean: + raise HTTPException(status_code=404, detail="Transport mean not found") + + return transport_mean + + +@router.post("/", response_model=PedimentoTransportMeansResponse, status_code=201) +async def create_transport_mean( + pedimento_id: int, + data: PedimentoTransportMeansCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create a new transport mean""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + # Ensure pedimento_id matches + if data.pedimento_id != pedimento_id: + raise HTTPException(status_code=400, detail="Pedimento ID mismatch") + + transport_mean = PedimentoTransportMeansService.create(db, data, tenant_id) + return transport_mean + + +@router.put("/{transport_mean_id}", response_model=PedimentoTransportMeansResponse) +async def update_transport_mean( + pedimento_id: int, + transport_mean_id: int, + data: PedimentoTransportMeansUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update a transport mean""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + transport_mean = PedimentoTransportMeansService.update(db, transport_mean_id, pedimento_id, tenant_id, data) + if not transport_mean: + raise HTTPException(status_code=404, detail="Transport mean not found") + + return transport_mean + + +@router.delete("/{transport_mean_id}", status_code=204) +async def delete_transport_mean( + pedimento_id: int, + transport_mean_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete a transport mean""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentoTransportMeansService.delete(db, transport_mean_id, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Transport mean not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimento_validation.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_validation.py new file mode 100644 index 00000000..66164a31 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimento_validation.py @@ -0,0 +1,92 @@ +""" +Routes for PedimentoValidation CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimento_validation import PedimentoValidationService +from ..dtos.pedimento_validation import ( + PedimentoValidationCreate, + PedimentoValidationUpdate, + PedimentoValidationResponse +) + + +router = APIRouter(prefix="/{pedimento_id}/validation") + + +@router.get("/", response_model=PedimentoValidationResponse) +async def get_validation( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get validation by pedimento ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + validation = PedimentoValidationService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not validation: + raise HTTPException(status_code=404, detail="Pedimento validation not found") + + return validation + + +@router.post("/", response_model=PedimentoValidationResponse, status_code=201) +async def create_validation( + pedimento_id: int, + data: PedimentoValidationCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create pedimento validation""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + # Ensure pedimento_id matches + if data.pedimento_id != pedimento_id: + raise HTTPException(status_code=400, detail="Pedimento ID mismatch") + + validation = PedimentoValidationService.create(db, data, tenant_id) + return validation + + +@router.put("/", response_model=PedimentoValidationResponse) +async def update_validation( + pedimento_id: int, + data: PedimentoValidationUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update pedimento validation""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + validation = PedimentoValidationService.update(db, pedimento_id, tenant_id, data) + if not validation: + raise HTTPException(status_code=404, detail="Pedimento validation not found") + + return validation + + +@router.delete("/", status_code=204) +async def delete_validation( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete pedimento validation""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentoValidationService.delete(db, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Pedimento validation not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/routes/pedimentos.py b/backend/api/v1/modules/a76/pedmientos/routes/pedimentos.py new file mode 100644 index 00000000..2dd457ef --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/routes/pedimentos.py @@ -0,0 +1,118 @@ +""" +Routes for Pedimentos CRUD operations +""" +from fastapi import APIRouter, Depends, HTTPException, Query +from sqlalchemy.orm import Session +from typing import Dict, Any, Optional +from core.database import get_core_db +from core.security import get_current_user, get_tenant_from_token + +from ..services.pedimentos import PedimentosService +from ..dtos.pedimentos import PedimentosCreate, PedimentosUpdate, PedimentosResponse + + +router = APIRouter() + + +@router.get("/", response_model=Dict[str, Any]) +async def list_pedimentos( + page: int = Query(1, ge=1, description="Page number"), + page_size: int = Query(50, ge=1, le=100, description="Page size"), + status: Optional[str] = Query(None, description="Filter by status"), + client_id: Optional[int] = Query(None, description="Filter by client ID"), + year: Optional[str] = Query(None, description="Filter by year"), + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get all pedimentos with pagination and filters""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + filters = {} + if status: + filters["status"] = status + if client_id: + filters["client_id"] = client_id + if year: + filters["year"] = year + + skip = (page - 1) * page_size + items, total = PedimentosService.get_all(db, tenant_id, skip, page_size, filters) + + return { + "items": [PedimentosResponse.model_validate(item) for item in items], + "total": total, + "page": page, + "page_size": page_size + } + + +@router.get("/{pedimento_id}", response_model=PedimentosResponse) +async def get_pedimento( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Get a pedimento by ID""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + pedimento = PedimentosService.get_by_id(db, pedimento_id, tenant_id) + if not pedimento: + raise HTTPException(status_code=404, detail="Pedimento not found") + + return pedimento + + +@router.post("/", response_model=PedimentosResponse, status_code=201) +async def create_pedimento( + data: PedimentosCreate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Create a new pedimento""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + pedimento = PedimentosService.create(db, data, tenant_id) + return pedimento + + +@router.put("/{pedimento_id}", response_model=PedimentosResponse) +async def update_pedimento( + pedimento_id: int, + data: PedimentosUpdate, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Update a pedimento""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + pedimento = PedimentosService.update(db, pedimento_id, tenant_id, data) + if not pedimento: + raise HTTPException(status_code=404, detail="Pedimento not found") + + return pedimento + + +@router.delete("/{pedimento_id}", status_code=204) +async def delete_pedimento( + pedimento_id: int, + db: Session = Depends(get_core_db), + current_user: dict = Depends(get_current_user) +): + """Delete a pedimento""" + tenant_id = get_tenant_from_token(current_user) + if not tenant_id: + raise HTTPException(status_code=400, detail="Tenant ID not found in token") + + success = PedimentosService.delete(db, pedimento_id, tenant_id) + if not success: + raise HTTPException(status_code=404, detail="Pedimento not found") + + return None diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_additional.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_additional.py new file mode 100644 index 00000000..40762a99 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_additional.py @@ -0,0 +1,60 @@ +""" +Service layer for PedimentoConfigAdditional CRUD operations +""" +from typing import Optional +from sqlalchemy.orm import Session + +from ..models.pedimento_config_additional import PedimentoConfigAdditional +from ..dtos.pedimento_config_additional import PedimentoConfigAdditionalCreate, PedimentoConfigAdditionalUpdate + + +class PedimentoConfigAdditionalService: + """Service class for PedimentoConfigAdditional business logic""" + + @staticmethod + def get_by_pedimento_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[PedimentoConfigAdditional]: + """Get config by pedimento ID""" + return db.query(PedimentoConfigAdditional).filter( + PedimentoConfigAdditional.pedimento_id == pedimento_id, + PedimentoConfigAdditional.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, config_data: PedimentoConfigAdditionalCreate) -> PedimentoConfigAdditional: + """Create a new config""" + config = PedimentoConfigAdditional(**config_data.model_dump()) + db.add(config) + db.commit() + db.refresh(config) + return config + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + config_data: PedimentoConfigAdditionalUpdate + ) -> Optional[PedimentoConfigAdditional]: + """Update config""" + config = PedimentoConfigAdditionalService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + return None + + update_data = config_data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(config, field, value) + + db.commit() + db.refresh(config) + return config + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """Delete config""" + config = PedimentoConfigAdditionalService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + return False + + db.delete(config) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_calculations.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_calculations.py new file mode 100644 index 00000000..7919bdab --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_calculations.py @@ -0,0 +1,60 @@ +""" +Service layer for PedimentoConfigCalculations CRUD operations +""" +from typing import Optional +from sqlalchemy.orm import Session + +from ..models.pedimento_config_calculations import PedimentoConfigCalculations +from ..dtos.pedimento_config_calculations import PedimentoConfigCalculationsCreate, PedimentoConfigCalculationsUpdate + + +class PedimentoConfigCalculationsService: + """Service class for PedimentoConfigCalculations business logic""" + + @staticmethod + def get_by_pedimento_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[PedimentoConfigCalculations]: + """Get config by pedimento ID""" + return db.query(PedimentoConfigCalculations).filter( + PedimentoConfigCalculations.pedimento_id == pedimento_id, + PedimentoConfigCalculations.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, config_data: PedimentoConfigCalculationsCreate) -> PedimentoConfigCalculations: + """Create a new config""" + config = PedimentoConfigCalculations(**config_data.model_dump()) + db.add(config) + db.commit() + db.refresh(config) + return config + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + config_data: PedimentoConfigCalculationsUpdate + ) -> Optional[PedimentoConfigCalculations]: + """Update config""" + config = PedimentoConfigCalculationsService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + return None + + update_data = config_data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(config, field, value) + + db.commit() + db.refresh(config) + return config + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """Delete config""" + config = PedimentoConfigCalculationsService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + return False + + db.delete(config) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_parameters.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_parameters.py new file mode 100644 index 00000000..e3ed7f3c --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_parameters.py @@ -0,0 +1,60 @@ +""" +Service layer for PedimentoConfigParameters CRUD operations +""" +from typing import Optional +from sqlalchemy.orm import Session + +from ..models.pedimento_config_parameters import PedimentoConfigParameters +from ..dtos.pedimento_config_parameters import PedimentoConfigParametersCreate, PedimentoConfigParametersUpdate + + +class PedimentoConfigParametersService: + """Service class for PedimentoConfigParameters business logic""" + + @staticmethod + def get_by_pedimento_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[PedimentoConfigParameters]: + """Get config by pedimento ID""" + return db.query(PedimentoConfigParameters).filter( + PedimentoConfigParameters.pedimento_id == pedimento_id, + PedimentoConfigParameters.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, config_data: PedimentoConfigParametersCreate) -> PedimentoConfigParameters: + """Create a new config""" + config = PedimentoConfigParameters(**config_data.model_dump()) + db.add(config) + db.commit() + db.refresh(config) + return config + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + config_data: PedimentoConfigParametersUpdate + ) -> Optional[PedimentoConfigParameters]: + """Update config""" + config = PedimentoConfigParametersService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + return None + + update_data = config_data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(config, field, value) + + db.commit() + db.refresh(config) + return config + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """Delete config""" + config = PedimentoConfigParametersService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + return False + + db.delete(config) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_surcharges.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_surcharges.py new file mode 100644 index 00000000..af7b9283 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_surcharges.py @@ -0,0 +1,60 @@ +""" +Service layer for PedimentoConfigSurcharges CRUD operations +""" +from typing import Optional +from sqlalchemy.orm import Session + +from ..models.pedimento_config_surcharges import PedimentoConfigSurcharges +from ..dtos.pedimento_config_surcharges import PedimentoConfigSurchargesCreate, PedimentoConfigSurchargesUpdate + + +class PedimentoConfigSurchargesService: + """Service class for PedimentoConfigSurcharges business logic""" + + @staticmethod + def get_by_pedimento_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[PedimentoConfigSurcharges]: + """Get config by pedimento ID""" + return db.query(PedimentoConfigSurcharges).filter( + PedimentoConfigSurcharges.pedimento_id == pedimento_id, + PedimentoConfigSurcharges.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, config_data: PedimentoConfigSurchargesCreate) -> PedimentoConfigSurcharges: + """Create a new config""" + config = PedimentoConfigSurcharges(**config_data.model_dump()) + db.add(config) + db.commit() + db.refresh(config) + return config + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + config_data: PedimentoConfigSurchargesUpdate + ) -> Optional[PedimentoConfigSurcharges]: + """Update config""" + config = PedimentoConfigSurchargesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + return None + + update_data = config_data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(config, field, value) + + db.commit() + db.refresh(config) + return config + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """Delete config""" + config = PedimentoConfigSurchargesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + return False + + db.delete(config) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_update_rectification.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_update_rectification.py new file mode 100644 index 00000000..a9566f49 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_update_rectification.py @@ -0,0 +1,60 @@ +""" +Service layer for PedimentoConfigUpdateRectification CRUD operations +""" +from typing import Optional +from sqlalchemy.orm import Session + +from ..models.pedimento_config_update_rectification import PedimentoConfigUpdateRectification +from ..dtos.pedimento_config_update_rectification import PedimentoConfigUpdateRectificationCreate, PedimentoConfigUpdateRectificationUpdate + + +class PedimentoConfigUpdateRectificationService: + """Service class for PedimentoConfigUpdateRectification business logic""" + + @staticmethod + def get_by_pedimento_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[PedimentoConfigUpdateRectification]: + """Get config by pedimento ID""" + return db.query(PedimentoConfigUpdateRectification).filter( + PedimentoConfigUpdateRectification.pedimento_id == pedimento_id, + PedimentoConfigUpdateRectification.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, config_data: PedimentoConfigUpdateRectificationCreate) -> PedimentoConfigUpdateRectification: + """Create a new config""" + config = PedimentoConfigUpdateRectification(**config_data.model_dump()) + db.add(config) + db.commit() + db.refresh(config) + return config + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + config_data: PedimentoConfigUpdateRectificationUpdate + ) -> Optional[PedimentoConfigUpdateRectification]: + """Update config""" + config = PedimentoConfigUpdateRectificationService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + return None + + update_data = config_data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(config, field, value) + + db.commit() + db.refresh(config) + return config + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """Delete config""" + config = PedimentoConfigUpdateRectificationService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + return False + + db.delete(config) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_updates.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_updates.py new file mode 100644 index 00000000..bf8a4b97 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_config_updates.py @@ -0,0 +1,60 @@ +""" +Service layer for PedimentoConfigUpdates CRUD operations +""" +from typing import Optional +from sqlalchemy.orm import Session + +from ..models.pedimento_config_updates import PedimentoConfigUpdates +from ..dtos.pedimento_config_updates import PedimentoConfigUpdatesCreate, PedimentoConfigUpdatesUpdate + + +class PedimentoConfigUpdatesService: + """Service class for PedimentoConfigUpdates business logic""" + + @staticmethod + def get_by_pedimento_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[PedimentoConfigUpdates]: + """Get config by pedimento ID""" + return db.query(PedimentoConfigUpdates).filter( + PedimentoConfigUpdates.pedimento_id == pedimento_id, + PedimentoConfigUpdates.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, config_data: PedimentoConfigUpdatesCreate) -> PedimentoConfigUpdates: + """Create a new config""" + config = PedimentoConfigUpdates(**config_data.model_dump()) + db.add(config) + db.commit() + db.refresh(config) + return config + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + config_data: PedimentoConfigUpdatesUpdate + ) -> Optional[PedimentoConfigUpdates]: + """Update config""" + config = PedimentoConfigUpdatesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + return None + + update_data = config_data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(config, field, value) + + db.commit() + db.refresh(config) + return config + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """Delete config""" + config = PedimentoConfigUpdatesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not config: + return False + + db.delete(config) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_customs_offices.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_customs_offices.py new file mode 100644 index 00000000..521cb5ce --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_customs_offices.py @@ -0,0 +1,60 @@ +""" +Service layer for PedimentoCustomsOffices CRUD operations +""" +from typing import Optional +from sqlalchemy.orm import Session + +from ..models.pedimento_customs_offices import PedimentoCustomsOffices +from ..dtos.pedimento_customs_offices import PedimentoCustomsOfficesCreate, PedimentoCustomsOfficesUpdate + + +class PedimentoCustomsOfficesService: + """Service class for PedimentoCustomsOffices business logic""" + + @staticmethod + def get_by_pedimento_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[PedimentoCustomsOffices]: + """Get customs offices by pedimento ID""" + return db.query(PedimentoCustomsOffices).filter( + PedimentoCustomsOffices.pedimento_id == pedimento_id, + PedimentoCustomsOffices.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, data: PedimentoCustomsOfficesCreate) -> PedimentoCustomsOffices: + """Create new customs offices""" + offices = PedimentoCustomsOffices(**data.model_dump()) + db.add(offices) + db.commit() + db.refresh(offices) + return offices + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + data: PedimentoCustomsOfficesUpdate + ) -> Optional[PedimentoCustomsOffices]: + """Update customs offices""" + offices = PedimentoCustomsOfficesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not offices: + return None + + update_data = data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(offices, field, value) + + db.commit() + db.refresh(offices) + return offices + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """Delete customs offices""" + offices = PedimentoCustomsOfficesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not offices: + return False + + db.delete(offices) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_dates.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_dates.py new file mode 100644 index 00000000..84708efd --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_dates.py @@ -0,0 +1,60 @@ +""" +Service layer for PedimentoDates CRUD operations +""" +from typing import Optional +from sqlalchemy.orm import Session + +from ..models.pedimento_dates import PedimentoDates +from ..dtos.pedimento_dates import PedimentoDatesCreate, PedimentoDatesUpdate + + +class PedimentoDatesService: + """Service class for PedimentoDates business logic""" + + @staticmethod + def get_by_pedimento_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[PedimentoDates]: + """Get dates by pedimento ID""" + return db.query(PedimentoDates).filter( + PedimentoDates.pedimento_id == pedimento_id, + PedimentoDates.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, data: PedimentoDatesCreate) -> PedimentoDates: + """Create new pedimento dates""" + dates = PedimentoDates(**data.model_dump()) + db.add(dates) + db.commit() + db.refresh(dates) + return dates + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + data: PedimentoDatesUpdate + ) -> Optional[PedimentoDates]: + """Update pedimento dates""" + dates = PedimentoDatesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not dates: + return None + + update_data = data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(dates, field, value) + + db.commit() + db.refresh(dates) + return dates + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """Delete pedimento dates""" + dates = PedimentoDatesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not dates: + return False + + db.delete(dates) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_decrementables.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_decrementables.py new file mode 100644 index 00000000..f9eb2893 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_decrementables.py @@ -0,0 +1,60 @@ +""" +Service layer for PedimentoDecrementables CRUD operations +""" +from typing import Optional +from sqlalchemy.orm import Session + +from ..models.pedimento_decrementables import PedimentoDecrementables +from ..dtos.pedimento_decrementables import PedimentoDecrementablesCreate, PedimentoDecrementablesUpdate + + +class PedimentoDecrementablesService: + """Service class for PedimentoDecrementables business logic""" + + @staticmethod + def get_by_pedimento_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[PedimentoDecrementables]: + """Get decrementables by pedimento ID""" + return db.query(PedimentoDecrementables).filter( + PedimentoDecrementables.pedimento_id == pedimento_id, + PedimentoDecrementables.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, data: PedimentoDecrementablesCreate) -> PedimentoDecrementables: + """Create new decrementables""" + decrementables = PedimentoDecrementables(**data.model_dump()) + db.add(decrementables) + db.commit() + db.refresh(decrementables) + return decrementables + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + data: PedimentoDecrementablesUpdate + ) -> Optional[PedimentoDecrementables]: + """Update decrementables""" + decrementables = PedimentoDecrementablesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not decrementables: + return None + + update_data = data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(decrementables, field, value) + + db.commit() + db.refresh(decrementables) + return decrementables + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """Delete decrementables""" + decrementables = PedimentoDecrementablesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not decrementables: + return False + + db.delete(decrementables) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_incrementables.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_incrementables.py new file mode 100644 index 00000000..40bd6c81 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_incrementables.py @@ -0,0 +1,60 @@ +""" +Service layer for PedimentoIncrementables CRUD operations +""" +from typing import Optional +from sqlalchemy.orm import Session + +from ..models.pedimento_incrementables import PedimentoIncrementables +from ..dtos.pedimento_incrementables import PedimentoIncrementablesCreate, PedimentoIncrementablesUpdate + + +class PedimentoIncrementablesService: + """Service class for PedimentoIncrementables business logic""" + + @staticmethod + def get_by_pedimento_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[PedimentoIncrementables]: + """Get incrementables by pedimento ID""" + return db.query(PedimentoIncrementables).filter( + PedimentoIncrementables.pedimento_id == pedimento_id, + PedimentoIncrementables.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, data: PedimentoIncrementablesCreate) -> PedimentoIncrementables: + """Create new incrementables""" + incrementables = PedimentoIncrementables(**data.model_dump()) + db.add(incrementables) + db.commit() + db.refresh(incrementables) + return incrementables + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + data: PedimentoIncrementablesUpdate + ) -> Optional[PedimentoIncrementables]: + """Update incrementables""" + incrementables = PedimentoIncrementablesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not incrementables: + return None + + update_data = data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(incrementables, field, value) + + db.commit() + db.refresh(incrementables) + return incrementables + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """Delete incrementables""" + incrementables = PedimentoIncrementablesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not incrementables: + return False + + db.delete(incrementables) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_indexes.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_indexes.py new file mode 100644 index 00000000..dbd8fdd5 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_indexes.py @@ -0,0 +1,60 @@ +""" +Service layer for PedimentoIndexes CRUD operations +""" +from typing import Optional +from sqlalchemy.orm import Session + +from ..models.pedimento_indexes import PedimentoIndexes +from ..dtos.pedimento_indexes import PedimentoIndexesCreate, PedimentoIndexesUpdate + + +class PedimentoIndexesService: + """Service class for PedimentoIndexes business logic""" + + @staticmethod + def get_by_pedimento_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[PedimentoIndexes]: + """Get indexes by pedimento ID""" + return db.query(PedimentoIndexes).filter( + PedimentoIndexes.pedimento_id == pedimento_id, + PedimentoIndexes.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, data: PedimentoIndexesCreate) -> PedimentoIndexes: + """Create new indexes""" + indexes = PedimentoIndexes(**data.model_dump()) + db.add(indexes) + db.commit() + db.refresh(indexes) + return indexes + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + data: PedimentoIndexesUpdate + ) -> Optional[PedimentoIndexes]: + """Update indexes""" + indexes = PedimentoIndexesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not indexes: + return None + + update_data = data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(indexes, field, value) + + db.commit() + db.refresh(indexes) + return indexes + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """Delete indexes""" + indexes = PedimentoIndexesService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not indexes: + return False + + db.delete(indexes) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_payments.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_payments.py new file mode 100644 index 00000000..81dc5af1 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_payments.py @@ -0,0 +1,60 @@ +""" +Service layer for PedimentoPayments CRUD operations +""" +from typing import Optional +from sqlalchemy.orm import Session + +from ..models.pedimento_payments import PedimentoPayments +from ..dtos.pedimento_payments import PedimentoPaymentsCreate, PedimentoPaymentsUpdate + + +class PedimentoPaymentsService: + """Service class for PedimentoPayments business logic""" + + @staticmethod + def get_by_pedimento_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[PedimentoPayments]: + """Get payments by pedimento ID""" + return db.query(PedimentoPayments).filter( + PedimentoPayments.pedimento_id == pedimento_id, + PedimentoPayments.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, data: PedimentoPaymentsCreate) -> PedimentoPayments: + """Create new payments""" + payments = PedimentoPayments(**data.model_dump()) + db.add(payments) + db.commit() + db.refresh(payments) + return payments + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + data: PedimentoPaymentsUpdate + ) -> Optional[PedimentoPayments]: + """Update payments""" + payments = PedimentoPaymentsService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not payments: + return None + + update_data = data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(payments, field, value) + + db.commit() + db.refresh(payments) + return payments + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """Delete payments""" + payments = PedimentoPaymentsService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not payments: + return False + + db.delete(payments) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_rectification_destination.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_rectification_destination.py new file mode 100644 index 00000000..19dc8715 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_rectification_destination.py @@ -0,0 +1,60 @@ +""" +Service layer for PedimentoRectificationDestination CRUD operations +""" +from typing import Optional +from sqlalchemy.orm import Session + +from ..models.pedimento_rectification_destination import PedimentoRectificationDestination +from ..dtos.pedimento_rectification_destination import PedimentoRectificationDestinationCreate, PedimentoRectificationDestinationUpdate + + +class PedimentoRectificationDestinationService: + """Service class for PedimentoRectificationDestination business logic""" + + @staticmethod + def get_by_pedimento_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[PedimentoRectificationDestination]: + """Get rectification destination by pedimento ID""" + return db.query(PedimentoRectificationDestination).filter( + PedimentoRectificationDestination.pedimento_id == pedimento_id, + PedimentoRectificationDestination.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, data: PedimentoRectificationDestinationCreate) -> PedimentoRectificationDestination: + """Create new rectification destination""" + rectification = PedimentoRectificationDestination(**data.model_dump()) + db.add(rectification) + db.commit() + db.refresh(rectification) + return rectification + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + data: PedimentoRectificationDestinationUpdate + ) -> Optional[PedimentoRectificationDestination]: + """Update rectification destination""" + rectification = PedimentoRectificationDestinationService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not rectification: + return None + + update_data = data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(rectification, field, value) + + db.commit() + db.refresh(rectification) + return rectification + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """Delete rectification destination""" + rectification = PedimentoRectificationDestinationService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not rectification: + return False + + db.delete(rectification) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_rectification_origin.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_rectification_origin.py new file mode 100644 index 00000000..1206b137 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_rectification_origin.py @@ -0,0 +1,60 @@ +""" +Service layer for PedimentoRectificationOrigin CRUD operations +""" +from typing import Optional +from sqlalchemy.orm import Session + +from ..models.pedimento_rectification_origin import PedimentoRectificationOrigin +from ..dtos.pedimento_rectification_origin import PedimentoRectificationOriginCreate, PedimentoRectificationOriginUpdate + + +class PedimentoRectificationOriginService: + """Service class for PedimentoRectificationOrigin business logic""" + + @staticmethod + def get_by_pedimento_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[PedimentoRectificationOrigin]: + """Get rectification origin by pedimento ID""" + return db.query(PedimentoRectificationOrigin).filter( + PedimentoRectificationOrigin.pedimento_id == pedimento_id, + PedimentoRectificationOrigin.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, data: PedimentoRectificationOriginCreate) -> PedimentoRectificationOrigin: + """Create new rectification origin""" + rectification = PedimentoRectificationOrigin(**data.model_dump()) + db.add(rectification) + db.commit() + db.refresh(rectification) + return rectification + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + data: PedimentoRectificationOriginUpdate + ) -> Optional[PedimentoRectificationOrigin]: + """Update rectification origin""" + rectification = PedimentoRectificationOriginService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not rectification: + return None + + update_data = data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(rectification, field, value) + + db.commit() + db.refresh(rectification) + return rectification + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """Delete rectification origin""" + rectification = PedimentoRectificationOriginService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not rectification: + return False + + db.delete(rectification) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_transport_means.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_transport_means.py new file mode 100644 index 00000000..8384523f --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_transport_means.py @@ -0,0 +1,60 @@ +""" +Service layer for PedimentoTransportMeans CRUD operations +""" +from typing import Optional +from sqlalchemy.orm import Session + +from ..models.pedimento_transport_means import PedimentoTransportMeans +from ..dtos.pedimento_transport_means import PedimentoTransportMeansCreate, PedimentoTransportMeansUpdate + + +class PedimentoTransportMeansService: + """Service class for PedimentoTransportMeans business logic""" + + @staticmethod + def get_by_pedimento_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[PedimentoTransportMeans]: + """Get transport means by pedimento ID""" + return db.query(PedimentoTransportMeans).filter( + PedimentoTransportMeans.pedimento_id == pedimento_id, + PedimentoTransportMeans.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, data: PedimentoTransportMeansCreate) -> PedimentoTransportMeans: + """Create new transport means""" + transport = PedimentoTransportMeans(**data.model_dump()) + db.add(transport) + db.commit() + db.refresh(transport) + return transport + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + data: PedimentoTransportMeansUpdate + ) -> Optional[PedimentoTransportMeans]: + """Update transport means""" + transport = PedimentoTransportMeansService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not transport: + return None + + update_data = data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(transport, field, value) + + db.commit() + db.refresh(transport) + return transport + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """Delete transport means""" + transport = PedimentoTransportMeansService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not transport: + return False + + db.delete(transport) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimento_validation.py b/backend/api/v1/modules/a76/pedmientos/services/pedimento_validation.py new file mode 100644 index 00000000..8db22ede --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimento_validation.py @@ -0,0 +1,60 @@ +""" +Service layer for PedimentoValidation CRUD operations +""" +from typing import Optional +from sqlalchemy.orm import Session + +from ..models.pedimento_validation import PedimentoValidation +from ..dtos.pedimento_validation import PedimentoValidationCreate, PedimentoValidationUpdate + + +class PedimentoValidationService: + """Service class for PedimentoValidation business logic""" + + @staticmethod + def get_by_pedimento_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[PedimentoValidation]: + """Get validation by pedimento ID""" + return db.query(PedimentoValidation).filter( + PedimentoValidation.pedimento_id == pedimento_id, + PedimentoValidation.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, data: PedimentoValidationCreate) -> PedimentoValidation: + """Create new validation""" + validation = PedimentoValidation(**data.model_dump()) + db.add(validation) + db.commit() + db.refresh(validation) + return validation + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + data: PedimentoValidationUpdate + ) -> Optional[PedimentoValidation]: + """Update validation""" + validation = PedimentoValidationService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not validation: + return None + + update_data = data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(validation, field, value) + + db.commit() + db.refresh(validation) + return validation + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """Delete validation""" + validation = PedimentoValidationService.get_by_pedimento_id(db, pedimento_id, tenant_id) + if not validation: + return False + + db.delete(validation) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/pedmientos/services/pedimentos.py b/backend/api/v1/modules/a76/pedmientos/services/pedimentos.py new file mode 100644 index 00000000..e22717c2 --- /dev/null +++ b/backend/api/v1/modules/a76/pedmientos/services/pedimentos.py @@ -0,0 +1,140 @@ +""" +Service layer for Pedimentos CRUD operations +""" +from typing import List, Optional, Dict, Any +from sqlalchemy.orm import Session +from sqlalchemy import desc +from fastapi import HTTPException + +from ..models.pedimentos import Pedimentos +from ..dtos.pedimentos import PedimentosCreate, PedimentosUpdate + + +class PedimentosService: + """Service class for Pedimentos business logic""" + + @staticmethod + def get_all( + db: Session, + tenant_id: int, + skip: int = 0, + limit: int = 100, + filters: Optional[Dict[str, Any]] = None + ) -> tuple[List[Pedimentos], int]: + """ + Get all pedimentos for a tenant with pagination and filters + + Args: + db: Database session + tenant_id: Tenant ID + skip: Number of records to skip + limit: Maximum number of records to return + filters: Optional filters dict + + Returns: + Tuple of (list of pedimentos, total count) + """ + query = db.query(Pedimentos).filter(Pedimentos.tenant_id == tenant_id) + + if filters: + if filters.get("status"): + query = query.filter(Pedimentos.status == filters["status"]) + if filters.get("client_id"): + query = query.filter(Pedimentos.client_id == filters["client_id"]) + if filters.get("year"): + query = query.filter(Pedimentos.year == filters["year"]) + + total = query.count() + items = query.order_by(desc(Pedimentos.created_at)).offset(skip).limit(limit).all() + + return items, total + + @staticmethod + def get_by_id(db: Session, pedimento_id: int, tenant_id: int) -> Optional[Pedimentos]: + """ + Get a pedimento by ID + + Args: + db: Database session + pedimento_id: Pedimento ID + tenant_id: Tenant ID + + Returns: + Pedimento or None if not found + """ + return db.query(Pedimentos).filter( + Pedimentos.id == pedimento_id, + Pedimentos.tenant_id == tenant_id + ).first() + + @staticmethod + def create(db: Session, pedimento_data: PedimentosCreate, tenant_id: int) -> Pedimentos: + """ + Create a new pedimento + + Args: + db: Database session + pedimento_data: Pedimento creation data + + Returns: + Created pedimento + """ + pedimento = Pedimentos(**pedimento_data.model_dump()) + pedimento.tenant_id = 1 + + db.add(pedimento) + db.commit() + db.refresh(pedimento) + return pedimento + + @staticmethod + def update( + db: Session, + pedimento_id: int, + tenant_id: int, + pedimento_data: PedimentosUpdate + ) -> Optional[Pedimentos]: + """ + Update a pedimento + + Args: + db: Database session + pedimento_id: Pedimento ID + tenant_id: Tenant ID + pedimento_data: Updated data + + Returns: + Updated pedimento or None if not found + """ + pedimento = PedimentosService.get_by_id(db, pedimento_id, tenant_id) + if not pedimento: + return None + + update_data = pedimento_data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(pedimento, field, value) + + db.commit() + db.refresh(pedimento) + return pedimento + + @staticmethod + def delete(db: Session, pedimento_id: int, tenant_id: int) -> bool: + """ + Delete a pedimento + + Args: + db: Database session + pedimento_id: Pedimento ID + tenant_id: Tenant ID + + Returns: + True if deleted, False if not found + """ + pedimento = PedimentosService.get_by_id(db, pedimento_id, tenant_id) + if not pedimento: + return False + + db.delete(pedimento) + db.commit() + return True diff --git a/backend/api/v1/modules/a76/router.py b/backend/api/v1/modules/a76/router.py new file mode 100644 index 00000000..06ebeac3 --- /dev/null +++ b/backend/api/v1/modules/a76/router.py @@ -0,0 +1,20 @@ +""" +Router principal de API v1 +Agrega todos los módulos de la aplicación +""" +from fastapi import APIRouter + +# Importar routers de módulos +from .auth import router as auth_router +from .tenants import router as tenants_router +from .licenses import router as licenses_router +from .pedmientos.router import router as pedimentos_router + +# Router principal +router = APIRouter() + +# Registrar módulos +router.include_router(auth_router) +router.include_router(tenants_router, prefix="/a76", tags=["a76 / tenants"]) +router.include_router(licenses_router, prefix="/a76", tags=["a76 / licenses"]) +router.include_router(pedimentos_router, prefix="/a76") diff --git a/backend/api/v1/modules/a76/tenants/routes.py b/backend/api/v1/modules/a76/tenants/routes.py index da18099f..2768c025 100644 --- a/backend/api/v1/modules/a76/tenants/routes.py +++ b/backend/api/v1/modules/a76/tenants/routes.py @@ -10,7 +10,7 @@ from core.security import get_current_user, has_role from .dto import TenantCreateDTO, TenantUpdateDTO, TenantResponseDTO, TenantListResponseDTO from .service import TenantService -router = APIRouter(prefix="/tenants", tags=["Tenants"]) +router = APIRouter(prefix="/tenants") @router.post("/", response_model=TenantResponseDTO, status_code=201) diff --git a/backend/api/v1/modules/public/reference_data/code_pedimento_regimens/routes.py b/backend/api/v1/modules/public/reference_data/code_pedimento_regimens/routes.py index 55672bfd..b0db57d2 100644 --- a/backend/api/v1/modules/public/reference_data/code_pedimento_regimens/routes.py +++ b/backend/api/v1/modules/public/reference_data/code_pedimento_regimens/routes.py @@ -8,7 +8,7 @@ from .dto import CodePedimentoRegimenDTO from typing import Any, Dict -router = APIRouter(prefix="/code-pedimento-regimens", tags=["Code Pedimento Regimens"]) +router = APIRouter(prefix="/code-pedimento-regimens") @router.get("/", response_model=Dict[str, Any]) diff --git a/backend/api/v1/modules/public/reference_data/containers/routes.py b/backend/api/v1/modules/public/reference_data/containers/routes.py index 83a52e1a..73265a2a 100644 --- a/backend/api/v1/modules/public/reference_data/containers/routes.py +++ b/backend/api/v1/modules/public/reference_data/containers/routes.py @@ -8,7 +8,7 @@ from .dto import ContainerDTO from typing import Any, Dict -router = APIRouter(prefix="/containers", tags=["Containers"]) +router = APIRouter(prefix="/containers") diff --git a/backend/api/v1/modules/public/reference_data/countries/routes.py b/backend/api/v1/modules/public/reference_data/countries/routes.py index 950140f3..c2271122 100644 --- a/backend/api/v1/modules/public/reference_data/countries/routes.py +++ b/backend/api/v1/modules/public/reference_data/countries/routes.py @@ -8,7 +8,7 @@ from .dto import CountryDTO from typing import Any, Dict -router = APIRouter(prefix="/countries", tags=["Countries"]) +router = APIRouter(prefix="/countries") diff --git a/backend/api/v1/modules/public/reference_data/currency_types/routes.py b/backend/api/v1/modules/public/reference_data/currency_types/routes.py index 5987808f..a878a7a8 100644 --- a/backend/api/v1/modules/public/reference_data/currency_types/routes.py +++ b/backend/api/v1/modules/public/reference_data/currency_types/routes.py @@ -8,7 +8,7 @@ from .dto import CurrencyTypeDTO from typing import Any, Dict -router = APIRouter(prefix="/currency-types", tags=["Currency Types"]) +router = APIRouter(prefix="/currency-types") diff --git a/backend/api/v1/modules/public/reference_data/customs_sections/routes.py b/backend/api/v1/modules/public/reference_data/customs_sections/routes.py index 70225245..fdf636a6 100644 --- a/backend/api/v1/modules/public/reference_data/customs_sections/routes.py +++ b/backend/api/v1/modules/public/reference_data/customs_sections/routes.py @@ -8,7 +8,7 @@ from .dto import CustomsSectionDTO from typing import Any, Dict -router = APIRouter(prefix="/customs-sections", tags=["Customs Sections"]) +router = APIRouter(prefix="/customs-sections") @router.get("/", response_model=Dict[str, Any]) diff --git a/backend/api/v1/modules/public/reference_data/customs_warehouses/routes.py b/backend/api/v1/modules/public/reference_data/customs_warehouses/routes.py index 9c0ca9f0..8f25ac54 100644 --- a/backend/api/v1/modules/public/reference_data/customs_warehouses/routes.py +++ b/backend/api/v1/modules/public/reference_data/customs_warehouses/routes.py @@ -8,7 +8,7 @@ from .dto import CustomsWarehouseDTO from typing import Any, Dict -router = APIRouter(prefix="/customs-warehouses", tags=["Customs Warehouses"]) +router = APIRouter(prefix="/customs-warehouses") @router.get("/", response_model=Dict[str, Any]) diff --git a/backend/api/v1/modules/public/reference_data/incoterms/routes.py b/backend/api/v1/modules/public/reference_data/incoterms/routes.py index 3bc6ea7b..894a1833 100644 --- a/backend/api/v1/modules/public/reference_data/incoterms/routes.py +++ b/backend/api/v1/modules/public/reference_data/incoterms/routes.py @@ -8,7 +8,7 @@ from .dto import IncotermDTO from typing import Any, Dict -router = APIRouter(prefix="/incoterms", tags=["Incoterms"]) +router = APIRouter(prefix="/incoterms") diff --git a/backend/api/v1/modules/public/reference_data/invoice_types/routes.py b/backend/api/v1/modules/public/reference_data/invoice_types/routes.py index eddcf8e3..9cd997a1 100644 --- a/backend/api/v1/modules/public/reference_data/invoice_types/routes.py +++ b/backend/api/v1/modules/public/reference_data/invoice_types/routes.py @@ -8,7 +8,7 @@ from .dto import InvoiceTypeDTO from typing import Any, Dict -router = APIRouter(prefix="/invoice-types", tags=["Invoice Types"]) +router = APIRouter(prefix="/invoice-types") @router.get("/", response_model=Dict[str, Any]) diff --git a/backend/api/v1/modules/public/reference_data/material_types/routes.py b/backend/api/v1/modules/public/reference_data/material_types/routes.py index da83e152..dab0b4ec 100644 --- a/backend/api/v1/modules/public/reference_data/material_types/routes.py +++ b/backend/api/v1/modules/public/reference_data/material_types/routes.py @@ -8,7 +8,7 @@ from .dto import MaterialTypeDTO from typing import Any, Dict -router = APIRouter(prefix="/material-types", tags=["Material Types"]) +router = APIRouter(prefix="/material-types") diff --git a/backend/api/v1/modules/public/reference_data/payment_methods/routes.py b/backend/api/v1/modules/public/reference_data/payment_methods/routes.py index 104de6b8..ba27a187 100644 --- a/backend/api/v1/modules/public/reference_data/payment_methods/routes.py +++ b/backend/api/v1/modules/public/reference_data/payment_methods/routes.py @@ -8,7 +8,7 @@ from .dto import PaymentMethodDTO from typing import Any, Dict -router = APIRouter(prefix="/payment-methods", tags=["Payment Methods"]) +router = APIRouter(prefix="/payment-methods") @router.get("/", response_model=Dict[str, Any]) diff --git a/backend/api/v1/modules/public/reference_data/pedimento_codes/routes.py b/backend/api/v1/modules/public/reference_data/pedimento_codes/routes.py index d00ac957..34097e0b 100644 --- a/backend/api/v1/modules/public/reference_data/pedimento_codes/routes.py +++ b/backend/api/v1/modules/public/reference_data/pedimento_codes/routes.py @@ -8,7 +8,7 @@ from .dto import PedimentoCodeDTO from typing import Any, Dict -router = APIRouter(prefix="/pedimento-codes", tags=["Pedimento Codes"]) +router = APIRouter(prefix="/pedimento-codes") @router.get("/", response_model=Dict[str, Any]) diff --git a/backend/api/v1/modules/public/reference_data/pedimento_regimens/routes.py b/backend/api/v1/modules/public/reference_data/pedimento_regimens/routes.py index a3cb398a..593d7a53 100644 --- a/backend/api/v1/modules/public/reference_data/pedimento_regimens/routes.py +++ b/backend/api/v1/modules/public/reference_data/pedimento_regimens/routes.py @@ -8,7 +8,7 @@ from .dto import RegimenPedimentoDTO from typing import Any, Dict -router = APIRouter(prefix="/pedimento-regimens", tags=["Pedimento Regimens"]) +router = APIRouter(prefix="/pedimento-regimens") @router.get("/", response_model=Dict[str, Any]) diff --git a/backend/api/v1/modules/public/reference_data/router.py b/backend/api/v1/modules/public/reference_data/router.py new file mode 100644 index 00000000..e8a350a4 --- /dev/null +++ b/backend/api/v1/modules/public/reference_data/router.py @@ -0,0 +1,45 @@ +""" +Router principal de API v1 +Agrega todos los módulos de la aplicación +""" +from fastapi import APIRouter + +from .pedimento_codes.routes import router as pedimento_codes_router +from .payment_methods.routes import router as payment_methods_router +from .containers.routes import router as containers_router +from .countries.routes import router as countries_router +from .material_types.routes import router as material_types_router +from .currency_types.routes import router as currency_types_router +from .states.routes import router as states_router +from .transport_types.routes import router as transport_types_router +from .customs_warehouses.routes import router as customs_warehouses_router +from .valuation_methods.routes import router as valuation_methods_router +from .sectors.routes import router as sectors_router +from .transport_modes.routes import router as transport_modes_router +from .customs_sections.routes import router as customs_sections_router +from .invoice_types.routes import router as invoice_types_router +from .code_pedimento_regimens.routes import router as code_pedimento_regimens_router +from .pedimento_regimens.routes import router as pedimento_regimens_router +from .incoterms.routes import router as incoterms_router + +# Router principal +router = APIRouter() + +# Registrar módulos +router.include_router(pedimento_codes_router, prefix="/refrence_data", tags=["public / refrence_data / pedimento_codes"]) +router.include_router(payment_methods_router, prefix="/refrence_data", tags=["public / refrence_data / payment_methods"]) +router.include_router(containers_router, prefix="/refrence_data", tags=["public / refrence_data / containers"]) +router.include_router(countries_router, prefix="/refrence_data", tags=["public / refrence_data / countries"]) +router.include_router(material_types_router, prefix="/refrence_data", tags=["public / refrence_data / material_types"]) +router.include_router(currency_types_router, prefix="/refrence_data", tags=["public / refrence_data / currency_types"]) +router.include_router(states_router, prefix="/refrence_data", tags=["public / refrence_data / states"]) +router.include_router(transport_types_router, prefix="/refrence_data", tags=["public / refrence_data / transport_types"]) +router.include_router(customs_warehouses_router, prefix="/refrence_data", tags=["public / refrence_data / customs_warehouses"]) +router.include_router(valuation_methods_router, prefix="/refrence_data", tags=["public / refrence_data / valuation_methods"]) +router.include_router(sectors_router, prefix="/refrence_data", tags=["public / public / refrence_data / sectors"]) +router.include_router(transport_modes_router, prefix="/refrence_data", tags=["public / refrence_data / transport_modes"]) +router.include_router(customs_sections_router, prefix="/refrence_data", tags=["public / refrence_data / customs_sections"]) +router.include_router(invoice_types_router, prefix="/refrence_data", tags=["public / refrence_data / invoice_types"]) +router.include_router(code_pedimento_regimens_router, prefix="/refrence_data", tags=["public / refrence_data / code_pedimento_regimens"]) +router.include_router(pedimento_regimens_router, prefix="/refrence_data", tags=["public / refrence_data / pedimento_regimens"]) +router.include_router(incoterms_router, prefix="/refrence_data", tags=["public / refrence_data / incoterms"]) \ No newline at end of file diff --git a/backend/api/v1/modules/public/reference_data/sectors/routes.py b/backend/api/v1/modules/public/reference_data/sectors/routes.py index dd4b5694..9ba896c6 100644 --- a/backend/api/v1/modules/public/reference_data/sectors/routes.py +++ b/backend/api/v1/modules/public/reference_data/sectors/routes.py @@ -8,7 +8,7 @@ from .dto import SectorDTO from typing import Any, Dict -router = APIRouter(prefix="/sectors", tags=["Sectors"]) +router = APIRouter(prefix="/sectors") @router.get("/", response_model=Dict[str, Any]) diff --git a/backend/api/v1/modules/public/reference_data/states/routes.py b/backend/api/v1/modules/public/reference_data/states/routes.py index e63a8fd0..e9cf3cf4 100644 --- a/backend/api/v1/modules/public/reference_data/states/routes.py +++ b/backend/api/v1/modules/public/reference_data/states/routes.py @@ -8,7 +8,7 @@ from .dto import StateDTO from typing import Any, Dict -router = APIRouter(prefix="/states", tags=["States"]) +router = APIRouter(prefix="/states") diff --git a/backend/api/v1/modules/public/reference_data/transport_modes/routes.py b/backend/api/v1/modules/public/reference_data/transport_modes/routes.py index 883b8763..24d0406e 100644 --- a/backend/api/v1/modules/public/reference_data/transport_modes/routes.py +++ b/backend/api/v1/modules/public/reference_data/transport_modes/routes.py @@ -8,7 +8,7 @@ from .dto import TransportModeDTO from typing import Any, Dict -router = APIRouter(prefix="/transport-modes", tags=["Transport Modes"]) +router = APIRouter(prefix="/transport-modes") diff --git a/backend/api/v1/modules/public/reference_data/transport_types/routes.py b/backend/api/v1/modules/public/reference_data/transport_types/routes.py index fbcfd42f..737416a7 100644 --- a/backend/api/v1/modules/public/reference_data/transport_types/routes.py +++ b/backend/api/v1/modules/public/reference_data/transport_types/routes.py @@ -8,7 +8,7 @@ from .dto import TransportTypeDTO from typing import Any, Dict -router = APIRouter(prefix="/transport-types", tags=["Transport Types"]) +router = APIRouter(prefix="/transport-types") @router.get("/", response_model=Dict[str, Any]) diff --git a/backend/api/v1/modules/public/reference_data/valuation_methods/routes.py b/backend/api/v1/modules/public/reference_data/valuation_methods/routes.py index b4971d32..2296a7fc 100644 --- a/backend/api/v1/modules/public/reference_data/valuation_methods/routes.py +++ b/backend/api/v1/modules/public/reference_data/valuation_methods/routes.py @@ -8,7 +8,7 @@ from .dto import ValuationMethodDTO from typing import Any, Dict -router = APIRouter(prefix="/valuation-methods", tags=["Valuation Methods"]) +router = APIRouter(prefix="/valuation-methods") diff --git a/backend/api/v1/modules/public/router.py b/backend/api/v1/modules/public/router.py new file mode 100644 index 00000000..bcaec4b1 --- /dev/null +++ b/backend/api/v1/modules/public/router.py @@ -0,0 +1,13 @@ +""" +Router principal de API v1 +Agrega todos los módulos de la aplicación +""" +from fastapi import APIRouter + +from .reference_data.router import router as reference_data_router + +# Router principal +router = APIRouter() + +# Registrar módulos +router.include_router(reference_data_router, prefix="/public") diff --git a/backend/api/v1/router.py b/backend/api/v1/router.py index ffb93465..5c80eefe 100644 --- a/backend/api/v1/router.py +++ b/backend/api/v1/router.py @@ -5,56 +5,17 @@ Agrega todos los módulos de la aplicación from fastapi import APIRouter # Importar routers de módulos -from .modules.a76.auth import router as auth_router -from .modules.a76.tenants import router as tenants_router - -from .modules.public.reference_data.pedimento_codes.routes import router as pedimento_codes_router -from .modules.public.reference_data.payment_methods.routes import router as payment_methods_router -from .modules.public.reference_data.containers.routes import router as containers_router -from .modules.public.reference_data.countries.routes import router as countries_router -from .modules.public.reference_data.material_types.routes import router as material_types_router -from .modules.public.reference_data.currency_types.routes import router as currency_types_router -from .modules.public.reference_data.states.routes import router as states_router -from .modules.public.reference_data.transport_types.routes import router as transport_types_router -from .modules.public.reference_data.customs_warehouses.routes import router as customs_warehouses_router -from .modules.public.reference_data.valuation_methods.routes import router as valuation_methods_router -from .modules.public.reference_data.sectors.routes import router as sectors_router -from .modules.public.reference_data.transport_modes.routes import router as transport_modes_router -from .modules.public.reference_data.customs_sections.routes import router as customs_sections_router -from .modules.public.reference_data.invoice_types.routes import router as invoice_types_router -from .modules.public.reference_data.code_pedimento_regimens.routes import router as code_pedimento_regimens_router -from .modules.public.reference_data.pedimento_regimens.routes import router as pedimento_regimens_router -from .modules.public.reference_data.incoterms.routes import router as incoterms_router -from .modules.a76.licenses import router as licenses_router +from .modules.a76.router import router as a76_router +from .modules.public.router import router as public_router # Router principal router = APIRouter() # Registrar módulos -router.include_router(auth_router) -router.include_router(tenants_router) -router.include_router(licenses_router) -router.include_router(pedimento_codes_router) -router.include_router(payment_methods_router) -router.include_router(containers_router) -router.include_router(countries_router) -router.include_router(material_types_router) -router.include_router(currency_types_router) -router.include_router(states_router) -router.include_router(transport_types_router) -router.include_router(customs_warehouses_router) -router.include_router(valuation_methods_router) -router.include_router(sectors_router) -router.include_router(transport_modes_router) -router.include_router(customs_sections_router) -router.include_router(invoice_types_router) -router.include_router(code_pedimento_regimens_router) -router.include_router(pedimento_regimens_router) -router.include_router(incoterms_router) +router.include_router(a76_router) +router.include_router(public_router) # Health check - - @router.get("/status") def status(): """Health check de la API""" diff --git a/backend/main.py b/backend/main.py index 3932471a..a11f226f 100644 --- a/backend/main.py +++ b/backend/main.py @@ -4,11 +4,9 @@ Backend API con FastAPI + Keycloak + SQLAlchemy """ from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware -from contextlib import asynccontextmanager import logging from core.config import settings -from core.database import init_db from core.middleware import ( TenantMiddleware, LicenseValidationMiddleware, @@ -51,7 +49,6 @@ app.add_middleware(TenantMiddleware) # Registrar routers app.include_router(api_v1_router, prefix="/api/v1") - @app.get("/api/") async def root(): """Root endpoint""" diff --git a/models.py b/models.py index dc0a617c..e69de29b 100644 --- a/models.py +++ b/models.py @@ -1,135 +0,0 @@ -from typing import List, Optional - -from sqlalchemy import Boolean, Column, Date, DateTime, ForeignKeyConstraint, Index, Integer, PrimaryKeyConstraint, SmallInteger, String, Table, UniqueConstraint, text -from sqlalchemy.orm import Mapped, declarative_base, mapped_column, relationship -from sqlalchemy.orm.base import Mapped - -Base = declarative_base() -metadata = Base.metadata - - -class Gdatosvu(Base): - __tablename__ = 'gdatosvu' - __table_args__ = ( - PrimaryKeyConstraint('id_empageaadu', name='gdatosvu_pkey'), - ) - - id_empageaadu = mapped_column(String(10)) - ruta_arch_cer = mapped_column(String(1500)) - ruta_arch_key = mapped_column(String(1500)) - clave_acceso_fiel = mapped_column(String(50)) - usuario_webservice = mapped_column(String(100)) - clave_acceso_webservice = mapped_column(String(100)) - email_vu = mapped_column(String(800)) - tipo_figura_vu = mapped_column(String(30)) - ruta_vu_central = mapped_column(String(1500)) - ruta_archivos_xml = mapped_column(String(1500)) - rfc_consulta = mapped_column(String(30)) - toma_configuracion_vu = mapped_column(String(30)) - unidad_medida_vu = mapped_column(String(3)) - rfc_validacion_vu = mapped_column(String(30)) - ruta_archivo_cfdi = mapped_column(String(5000)) - ruta_archivo_key_cfdi = mapped_column(String(5000)) - fecha_venc_cer_cfdi = mapped_column(Date) - fecha_venc_key_cfdi = mapped_column(Date) - contrasena_cfdi = mapped_column(String(200)) - ruta_guardar_xml = mapped_column(String(5000)) - ruta_app_cfdi = mapped_column(String(5000)) - ruta_app_pac = mapped_column(String(5000)) - ruta_archivocancelacion = mapped_column(String(5000)) - contrasena_cancelacion = mapped_column(String(200)) - usuario_anam = mapped_column(String(100)) - contrasena_anam = mapped_column(String(200)) - fecha_creacion = mapped_column(DateTime, server_default=text('now()')) - fecha_actualizacion = mapped_column(DateTime) - - -class Gempresa(Base): - __tablename__ = 'gempresa' - __table_args__ = ( - PrimaryKeyConstraint('id_emp', name='gempresa_pkey'), - UniqueConstraint('consecutivo', name='gempresa_consecutivo_key') - ) - - id_emp = mapped_column(String(3), server_default=text("'EMP'::character varying")) - consecutivo = mapped_column(Boolean, server_default=text('true')) - nombre = mapped_column(String(255)) - rfc = mapped_column(String(30)) - actpreponderante = mapped_column(String(255)) - programa = mapped_column(String(10)) - numeroprograma = mapped_column(String(40)) - prosec = mapped_column(SmallInteger) - autorizacionprosec = mapped_column(String(20)) - manufacterid = mapped_column(String(25)) - broker_emp = mapped_column(String(10)) - responsable = mapped_column(String(80)) - respnombre = mapped_column(String(20)) - resppaterno = mapped_column(String(20)) - respmaterno = mapped_column(String(20)) - rfcresponsable = mapped_column(String(30)) - puesto = mapped_column(String(30)) - logo = mapped_column(String(255)) - tienelineaexpress = mapped_column(Boolean) - tipoformatoped = mapped_column(String(19)) - codigoanterior = mapped_column(SmallInteger) - esempresaservicio = mapped_column(Boolean) - nombrecliente = mapped_column(String(300)) - modosubmaquila = mapped_column(String(7)) - curp = mapped_column(String(19)) - nombrebdinter = mapped_column(String(100)) - ctpat_svi = mapped_column(String(100)) - numdeexportadorconfiable = mapped_column(String(50)) - claveprevalidador = mapped_column(String(20)) - septimaenmienda = mapped_column(Boolean) - fecha_creacion = mapped_column(DateTime, server_default=text('now()')) - fecha_actualizacion = mapped_column(DateTime) - - gempresa_sucursales: Mapped[List['GempresaSucursales']] = relationship('GempresaSucursales', uselist=True, back_populates='gempresa') - -t_gempresa_certificacion = Table( - 'gempresa_certificacion', metadata, - Column('id_empresa', String(3), nullable=False), - Column('esempresacertificada', Boolean), - Column('registroempcert', String(40)), - Column('fechainicialempcert', Date), - Column('fechafinalempcert', Date), - Column('fechacertificacionanexo31', Date), - Column('numerocertificacionanexo31', String(50)), - Column('modalidadanexo31', String(50)), - Column('tipoempresaanexo31', String(50)), - Column('empresaneec', Boolean), - Column('empresaoea', Boolean), - Column('empresarfe', Boolean), - Column('fecharenovacioncertificaciona31', Date), - Column('fechafinalcertificaciona31', Date), - Column('fecha_creacion', DateTime, server_default=text('now()')), - Column('fecha_actualizacion', DateTime), - ForeignKeyConstraint(['id_empresa'], ['gempresa.id_emp'], name='gempresa_certificacion_id_empresa_fkey') -) - - -class GempresaSucursales(Base): - __tablename__ = 'gempresa_sucursales' - __table_args__ = ( - ForeignKeyConstraint(['id_empresa'], ['gempresa.id_emp'], name='gempresa_sucursales_id_empresa_fkey'), - PrimaryKeyConstraint('id_sucursal', name='gempresa_sucursales_pkey') - ) - - id_empresa = mapped_column(String(3), nullable=False) - id_sucursal = mapped_column(Integer) - indicador = mapped_column(String(25)) - calle = mapped_column(String(255)) - num_ext = mapped_column(String(70)) - num_int = mapped_column(String(70)) - codigo_postal = mapped_column(String(15)) - colonia = mapped_column(String(50)) - ciudad = mapped_column(String(50)) - municipio = mapped_column(String(50)) - estado = mapped_column(String(40)) - pais = mapped_column(String(5)) - telefono = mapped_column(String(30)) - email = mapped_column(String(100)) - fecha_creacion = mapped_column(DateTime, server_default=text('now()')) - fecha_actualizacion = mapped_column(DateTime) - - gempresa: Mapped['Gempresa'] = relationship('Gempresa', back_populates='gempresa_sucursales') diff --git a/models_ped.py b/models_ped.py new file mode 100644 index 00000000..233407cf --- /dev/null +++ b/models_ped.py @@ -0,0 +1,27 @@ +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')