feat: add unit of measure tables and seed data for material types management

This commit is contained in:
Galindo97
2026-01-09 15:34:13 -06:00
parent 25c51120f9
commit 7abe79405e
5 changed files with 367 additions and 5 deletions

View File

@@ -167,12 +167,154 @@ def upgrade() -> None:
sa.PrimaryKeyConstraint("id", name="clave_pedimento_regimens_pkey"),
schema="public",
)
# Tablas de Unidades de Medida (A76)
# 1. Tabla: unit_of_measure_ace (ACE Units)
op.create_table(
'unit_of_measure_ace',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('code', sa.String(length=4), nullable=False),
sa.Column('description', sa.String(length=49), nullable=True),
sa.Column('tenant_id', sa.Integer(), nullable=False),
sa.Column('company_id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('code', 'tenant_id', 'company_id', name='uq_uom_ace_code'),
schema='a76'
)
# 2. Tabla: unit_of_measure_oma (OMA Units)
op.create_table(
'unit_of_measure_oma',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('code', sa.String(length=10), nullable=False),
sa.Column('description', sa.String(length=200), nullable=True),
sa.Column('tenant_id', sa.Integer(), nullable=False),
sa.Column('company_id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('code', 'tenant_id', 'company_id', name='uq_uom_oma_code'),
schema='a76'
)
# 3. Tabla: unit_of_measure_american (American Units)
op.create_table(
'unit_of_measure_american',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('code', sa.String(length=3), nullable=False),
sa.Column('description', sa.String(length=40), nullable=True),
sa.Column('tenant_id', sa.Integer(), nullable=False),
sa.Column('company_id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('code', 'tenant_id', 'company_id', name='uq_uom_american_code'),
schema='a76'
)
# 4. Tabla: unit_of_measure_customs (Customs Units)
op.create_table(
'unit_of_measure_customs',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('code', sa.String(length=2), nullable=False),
sa.Column('description', sa.String(length=20), nullable=True),
sa.Column('scaii_unit_code', sa.String(length=5), nullable=True),
sa.Column('tenant_id', sa.Integer(), nullable=False),
sa.Column('company_id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('code', 'tenant_id', 'company_id', name='uq_uom_customs_code'),
schema='a76'
)
# 5. Tabla: units_of_measure (Main Unit of Measure)
op.create_table(
'units_of_measure',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('code', sa.String(length=5), nullable=False),
sa.Column('description', sa.String(length=100), nullable=True),
sa.Column('description_en', sa.String(length=100), nullable=True),
sa.Column('customs_code', sa.String(length=2), nullable=True),
sa.Column('american_code', sa.String(length=3), nullable=True),
sa.Column('ace_code', sa.String(length=4), nullable=True),
sa.Column('oma_code', sa.String(length=10), nullable=True),
sa.Column('tenant_id', sa.Integer(), nullable=False),
sa.Column('company_id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.ForeignKeyConstraint(
['customs_code', 'tenant_id', 'company_id'],
['a76.unit_of_measure_customs.code', 'a76.unit_of_measure_customs.tenant_id', 'a76.unit_of_measure_customs.company_id'],
name='fk_uom_customs'
),
sa.ForeignKeyConstraint(
['american_code', 'tenant_id', 'company_id'],
['a76.unit_of_measure_american.code', 'a76.unit_of_measure_american.tenant_id', 'a76.unit_of_measure_american.company_id'],
name='fk_uom_american'
),
sa.ForeignKeyConstraint(
['ace_code', 'tenant_id', 'company_id'],
['a76.unit_of_measure_ace.code', 'a76.unit_of_measure_ace.tenant_id', 'a76.unit_of_measure_ace.company_id'],
name='fk_uom_ace'
),
sa.ForeignKeyConstraint(
['oma_code', 'tenant_id', 'company_id'],
['a76.unit_of_measure_oma.code', 'a76.unit_of_measure_oma.tenant_id', 'a76.unit_of_measure_oma.company_id'],
name='fk_uom_oma'
),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('code', 'tenant_id', 'company_id', name='uq_uom_code'),
schema='a76'
)
# 6. Tabla: units_of_measure_general (General/Conversion Units)
op.create_table(
'units_of_measure_general',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('code', sa.String(length=5), nullable=False),
sa.Column('description', sa.String(length=100), nullable=True),
sa.Column('conversion_factor', sa.Numeric(precision=13, scale=6), nullable=True),
sa.Column('mexico_unit', sa.String(length=5), nullable=True),
sa.Column('american_unit_code', sa.String(length=5), nullable=True),
sa.Column('customs_code', sa.String(length=2), nullable=True),
sa.Column('ace_code', sa.String(length=4), nullable=True),
sa.Column('tenant_id', sa.Integer(), nullable=False),
sa.Column('company_id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.ForeignKeyConstraint(
['customs_code', 'tenant_id', 'company_id'],
['a76.unit_of_measure_customs.code', 'a76.unit_of_measure_customs.tenant_id', 'a76.unit_of_measure_customs.company_id'],
name='fk_uom_general_customs'
),
sa.ForeignKeyConstraint(
['ace_code', 'tenant_id', 'company_id'],
['a76.unit_of_measure_ace.code', 'a76.unit_of_measure_ace.tenant_id', 'a76.unit_of_measure_ace.company_id'],
name='fk_uom_general_ace'
),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('code', 'tenant_id', 'company_id', name='uq_uom_general_code'),
schema='a76'
)
# ### end Alembic commands ###
def downgrade() -> None:
"""Downgrade schema."""
# ### commands auto generated by Alembic - please adjust! ###
# Eliminar tablas de unidades de medida
op.drop_table('units_of_measure_general', schema='a76')
op.drop_table('units_of_measure', schema='a76')
op.drop_table('unit_of_measure_customs', schema='a76')
op.drop_table('unit_of_measure_american', schema='a76')
op.drop_table('unit_of_measure_oma', schema='a76')
op.drop_table('unit_of_measure_ace', schema='a76')
# Eliminar tablas públicas
op.drop_table("code_pedimento_regimens", schema="public")
op.drop_table("valuation_methods", schema="public")
op.drop_table("transport_types", schema="public")

View File

@@ -53,12 +53,13 @@ from api.v1.modules.public.reference_data.transport_types.seed import (
from api.v1.modules.public.reference_data.valuation_methods.seed import (
seed as valuation_methods_seed,
)
from api.v1.modules.a76.general_catalogs.units_of_measure.seed import seed as units_of_measure_seed
# revision identifiers, used by Alembic.
revision: str = "7937209f9718"
down_revision: Union[str, Sequence[str], None] = "531bf8cdae06"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = "531bf8cdae06"
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
@@ -288,6 +289,46 @@ def upgrade() -> None:
"""
)
# Insertar seeds de Unidades de Medida
# Preparar valores únicos para cada tabla auxiliar
ace_codes = set()
oma_codes = set()
american_codes = set()
customs_codes = set()
for code, desc, desc_en, customs, american, ace, oma in units_of_measure_seed:
if ace and ace.strip():
ace_codes.add(ace.strip())
if oma and oma.strip():
oma_codes.add(oma.strip())
if american and american.strip():
american_codes.add(american.strip())
if customs and customs.strip():
customs_codes.add(customs.strip())
# Insertar seeds (con tenant_id=1, company_id=1 por defecto)
# IMPORTANTE: En producción necesitarás ajustar estos valores
def format_value(val):
"""Formatea valores para SQL, manejando None y strings vacíos"""
if not val or val.strip() == '':
return 'NULL'
return f"'{val.replace(chr(39), chr(39)*2)}'"
values_uom = ", ".join([
f"('{code}', {format_value(desc)}, {format_value(desc_en)}, "
f"{format_value(customs)}, {format_value(american)}, "
f"{format_value(ace)}, {format_value(oma)}, 1, 1)"
for code, desc, desc_en, customs, american, ace, oma in units_of_measure_seed
])
op.execute(f"""
INSERT INTO a76.units_of_measure
(code, description, description_en, customs_code, american_code, ace_code, oma_code, tenant_id, company_id)
VALUES {values_uom}
ON CONFLICT (code, tenant_id, company_id) DO NOTHING;
""")
def downgrade() -> None:
"""Downgrade schema."""
@@ -308,3 +349,4 @@ def downgrade() -> None:
op.execute("DELETE FROM public.code_pedimento_regimens;")
op.execute("DELETE FROM public.pedimento_regimens;")
op.execute("DELETE FROM public.pedimento_codes;")
op.execute("DELETE FROM a76.units_of_measure;")

View File

@@ -0,0 +1,163 @@
"""create_units_of_measure_tables
Revision ID: d9b22e8e8cd3
Revises: 7937209f9718
Create Date: 2026-01-09 14:51:56.669491
"""
from typing import Sequence, Union
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision: str = 'd9b22e8e8cd3'
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."""
# 1. Tabla: unit_of_measure_ace (ACE Units)
op.create_table(
'unit_of_measure_ace',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('code', sa.String(length=4), nullable=False),
sa.Column('description', sa.String(length=49), nullable=True),
sa.Column('tenant_id', sa.Integer(), nullable=False),
sa.Column('company_id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('code', 'tenant_id', 'company_id', name='uq_uom_ace_code'),
schema='a76'
)
# 2. Tabla: unit_of_measure_oma (OMA Units)
op.create_table(
'unit_of_measure_oma',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('code', sa.String(length=10), nullable=False),
sa.Column('description', sa.String(length=200), nullable=True),
sa.Column('tenant_id', sa.Integer(), nullable=False),
sa.Column('company_id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('code', 'tenant_id', 'company_id', name='uq_uom_oma_code'),
schema='a76'
)
# 3. Tabla: unit_of_measure_american (American Units)
op.create_table(
'unit_of_measure_american',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('code', sa.String(length=3), nullable=False),
sa.Column('description', sa.String(length=40), nullable=True),
sa.Column('tenant_id', sa.Integer(), nullable=False),
sa.Column('company_id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('code', 'tenant_id', 'company_id', name='uq_uom_american_code'),
schema='a76'
)
# 4. Tabla: unit_of_measure_customs (Customs Units)
op.create_table(
'unit_of_measure_customs',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('code', sa.String(length=2), nullable=False),
sa.Column('description', sa.String(length=20), nullable=True),
sa.Column('scaii_unit_code', sa.String(length=5), nullable=True),
sa.Column('tenant_id', sa.Integer(), nullable=False),
sa.Column('company_id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.Column('updated_at', sa.DateTime(), server_default=sa.text('now()'), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('code', 'tenant_id', 'company_id', name='uq_uom_customs_code'),
schema='a76'
)
# 5. Tabla: units_of_measure (Main Unit of Measure)
op.create_table(
'units_of_measure',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('code', sa.String(length=5), nullable=False),
sa.Column('description', sa.String(length=100), nullable=True),
sa.Column('description_en', sa.String(length=100), nullable=True),
sa.Column('customs_code', sa.String(length=2), nullable=True),
sa.Column('american_code', sa.String(length=3), nullable=True),
sa.Column('ace_code', sa.String(length=4), nullable=True),
sa.Column('oma_code', sa.String(length=10), nullable=True),
sa.Column('tenant_id', sa.Integer(), nullable=False),
sa.Column('company_id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
sa.ForeignKeyConstraint(
['customs_code', 'tenant_id', 'company_id'],
['a76.unit_of_measure_customs.code', 'a76.unit_of_measure_customs.tenant_id', 'a76.unit_of_measure_customs.company_id'],
name='fk_uom_customs'
),
sa.ForeignKeyConstraint(
['american_code', 'tenant_id', 'company_id'],
['a76.unit_of_measure_american.code', 'a76.unit_of_measure_american.tenant_id', 'a76.unit_of_measure_american.company_id'],
name='fk_uom_american'
),
sa.ForeignKeyConstraint(
['ace_code', 'tenant_id', 'company_id'],
['a76.unit_of_measure_ace.code', 'a76.unit_of_measure_ace.tenant_id', 'a76.unit_of_measure_ace.company_id'],
name='fk_uom_ace'
),
sa.ForeignKeyConstraint(
['oma_code', 'tenant_id', 'company_id'],
['a76.unit_of_measure_oma.code', 'a76.unit_of_measure_oma.tenant_id', 'a76.unit_of_measure_oma.company_id'],
name='fk_uom_oma'
),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('code', 'tenant_id', 'company_id', name='uq_uom_code'),
schema='a76'
)
# 6. Tabla: units_of_measure_general (General/Conversion Units)
op.create_table(
'units_of_measure_general',
sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
sa.Column('code', sa.String(length=5), nullable=False),
sa.Column('description', sa.String(length=100), nullable=True),
sa.Column('conversion_factor', sa.Numeric(precision=13, scale=6), nullable=True),
sa.Column('mexico_unit', sa.String(length=5), nullable=True),
sa.Column('american_unit_code', sa.String(length=5), nullable=True),
sa.Column('customs_code', sa.String(length=2), nullable=True),
sa.Column('ace_code', sa.String(length=4), nullable=True),
sa.Column('tenant_id', sa.Integer(), nullable=False),
sa.Column('company_id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=True),
sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
sa.ForeignKeyConstraint(
['customs_code', 'tenant_id', 'company_id'],
['a76.unit_of_measure_customs.code', 'a76.unit_of_measure_customs.tenant_id', 'a76.unit_of_measure_customs.company_id'],
name='fk_uom_general_customs'
),
sa.ForeignKeyConstraint(
['ace_code', 'tenant_id', 'company_id'],
['a76.unit_of_measure_ace.code', 'a76.unit_of_measure_ace.tenant_id', 'a76.unit_of_measure_ace.company_id'],
name='fk_uom_general_ace'
),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('code', 'tenant_id', 'company_id', name='uq_uom_general_code'),
schema='a76'
)
def downgrade() -> None:
"""Downgrade schema."""
op.drop_table('units_of_measure_general', schema='a76')
op.drop_table('units_of_measure', schema='a76')
op.drop_table('unit_of_measure_customs', schema='a76')
op.drop_table('unit_of_measure_american', schema='a76')
op.drop_table('unit_of_measure_oma', schema='a76')
op.drop_table('unit_of_measure_ace', schema='a76')

View File

@@ -15,11 +15,17 @@ router = APIRouter(prefix="/material-types")
async def list_material_types(
page: int = Query(1, ge=1, description="Número de página"),
page_size: int = Query(50, ge=1, le=100, description="Tamaño de página"),
type: str = Query(None, description="Filtrar por tipo (ACTIVO FIJO, MATERIALES, PRODUCTOS)"),
db: Session = Depends(get_core_db),
current_user: dict = Depends(get_current_user),
):
skip = (page - 1) * page_size
query = db.query(MaterialType)
# Aplicar filtro por tipo si se proporciona
if type:
query = query.filter(MaterialType.type == type)
items = query.offset(skip).limit(page_size).all()
total = query.count()
return {

View File

@@ -37,11 +37,20 @@ export const materialTypesApi = {
* Lista todos los tipos de material con paginación
* @param page - Número de página (por defecto 1)
* @param pageSize - Tamaño de página (por defecto 50)
* @param type - Filtrar por tipo (ACTIVO FIJO, MATERIALES, PRODUCTOS)
*/
list: (page = 1, pageSize = 50) =>
api.get<MaterialTypeListResponse>(
`/v1/public/refrence_data/material-types?page=${page}&page_size=${pageSize}`
),
list: (page = 1, pageSize = 50, type?: string) => {
const params = new URLSearchParams({
page: page.toString(),
page_size: pageSize.toString()
});
if (type) {
params.append('type', type);
}
return api.get<MaterialTypeListResponse>(
`/v1/public/refrence_data/material-types?${params.toString()}`
);
},
/**
* Obtiene un tipo de material por key