feat(api): add Units of Measure API client with CRUD operations

- Implemented interfaces for UnitOfMeasure, UnitOfMeasureListResponse, CreateUnitOfMeasureData, and UpdateUnitOfMeasureData.
- Added API methods for listing, retrieving, creating, updating, and deleting units of measure.
- Included pagination support for the list method.
This commit is contained in:
Galindo97
2026-01-12 10:36:43 -06:00
parent c2d1961994
commit 0aea981cf1
12 changed files with 1693 additions and 147 deletions

View File

@@ -8,11 +8,10 @@ from core.database import Base
# 1. GUniMedACE
class UnitOfMeasureACE(Base, TenantScopedMixin, TimestampMixin):
class UnitOfMeasureACE(Base, TimestampMixin):
__tablename__ = "unit_of_measure_ace"
__table_args__ = (
UniqueConstraint("code", "tenant_id", "company_id",
name="uq_uom_ace_code"),
UniqueConstraint("code", name="uq_uom_ace_code"),
{"schema": "a76", "extend_existing": True}
)
@@ -25,11 +24,10 @@ class UnitOfMeasureACE(Base, TenantScopedMixin, TimestampMixin):
# 2. GUMOMA
class UnitOfMeasureOMA(Base, TenantScopedMixin, TimestampMixin):
class UnitOfMeasureOMA(Base, TimestampMixin):
__tablename__ = "unit_of_measure_oma"
__table_args__ = (
UniqueConstraint("code", "tenant_id", "company_id",
name="uq_uom_oma_code"),
UniqueConstraint("code", name="uq_uom_oma_code"),
{"schema": "a76", "extend_existing": True}
)
@@ -42,11 +40,10 @@ class UnitOfMeasureOMA(Base, TenantScopedMixin, TimestampMixin):
# 3. GUMAme
class UnitOfMeasureAmerican(Base, TenantScopedMixin, TimestampMixin):
class UnitOfMeasureAmerican(Base, TimestampMixin):
__tablename__ = "unit_of_measure_american"
__table_args__ = (
UniqueConstraint("code", "tenant_id", "company_id",
name="uq_uom_american_code"),
UniqueConstraint("code", name="uq_uom_american_code"),
{"schema": "a76", "extend_existing": True}
)
@@ -59,19 +56,18 @@ class UnitOfMeasureAmerican(Base, TenantScopedMixin, TimestampMixin):
# 4. GUMAduana
class UnitOfMeasureCustoms(Base, TenantScopedMixin, TimestampMixin):
class UnitOfMeasureCustoms(Base, TimestampMixin):
__tablename__ = "unit_of_measure_customs"
__table_args__ = (
UniqueConstraint("code", "tenant_id", "company_id",
name="uq_uom_customs_code"),
UniqueConstraint("code", name="uq_uom_customs_code"),
{"schema": "a76", "extend_existing": True}
)
id: Mapped[int] = mapped_column(
Integer, primary_key=True, autoincrement=True)
code: Mapped[str] = mapped_column(String(2), nullable=False) # CLAVE
code: Mapped[str] = mapped_column(String(10), nullable=False) # CLAVE
description: Mapped[Optional[str]] = mapped_column(
String(20), nullable=True)
String(50), nullable=True)
scaii_unit_code: Mapped[Optional[str]] = mapped_column(
String(5), nullable=True) # UNIDADSCAII
@@ -84,30 +80,26 @@ class UnitOfMeasure(Base, TenantScopedMixin, TimestampMixin):
UniqueConstraint("code", "tenant_id",
"company_id", name="uq_uom_code"),
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"],
["customs_code"],
["a76.unit_of_measure_customs.code"],
use_alter=True,
name="fk_uom_customs"
),
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"],
["american_code"],
["a76.unit_of_measure_american.code"],
use_alter=True,
name="fk_uom_american"
),
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"],
["ace_code"],
["a76.unit_of_measure_ace.code"],
use_alter=True,
name="fk_uom_ace"
),
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"],
["oma_code"],
["a76.unit_of_measure_oma.code"],
use_alter=True,
name="fk_uom_oma"
),
@@ -116,14 +108,14 @@ class UnitOfMeasure(Base, TenantScopedMixin, TimestampMixin):
id: Mapped[int] = mapped_column(
Integer, primary_key=True, autoincrement=True)
code: Mapped[str] = mapped_column(String(5), nullable=False) # CLAVEUNI
code: Mapped[str] = mapped_column(String(10), nullable=False) # CLAVEUNI
description: Mapped[Optional[str]] = mapped_column(
String(100), nullable=True)
description_en: Mapped[Optional[str]] = mapped_column(
String(100), nullable=True)
customs_code: Mapped[Optional[str]] = mapped_column(
String(2), nullable=True) # CLAVE_AMEX
String(10), nullable=True) # CLAVE_AMEX
american_code: Mapped[Optional[str]] = mapped_column(
String(3), nullable=True) # CLAVE_AAMER
ace_code: Mapped[Optional[str]] = mapped_column(
@@ -146,16 +138,14 @@ class UnitOfMeasureGeneral(Base, TenantScopedMixin, TimestampMixin):
UniqueConstraint("code", "tenant_id", "company_id",
name="uq_uom_general_code"),
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"],
["customs_code"],
["a76.unit_of_measure_customs.code"],
use_alter=True,
name="fk_uom_general_customs"
),
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"],
["ace_code"],
["a76.unit_of_measure_ace.code"],
use_alter=True,
name="fk_uom_general_ace"
),
@@ -164,19 +154,19 @@ class UnitOfMeasureGeneral(Base, TenantScopedMixin, TimestampMixin):
id: Mapped[int] = mapped_column(
Integer, primary_key=True, autoincrement=True)
code: Mapped[str] = mapped_column(String(5), nullable=False) # UNIDAD
code: Mapped[str] = mapped_column(String(10), nullable=False) # UNIDAD
description: Mapped[Optional[str]] = mapped_column(
String(100), nullable=True)
conversion_factor: Mapped[Optional[Decimal]] = mapped_column(
Numeric(13, 6), nullable=True)
mexico_unit: Mapped[Optional[str]] = mapped_column(
String(5), nullable=True)
String(10), nullable=True)
# UNIDAD_AME (Note: GUniMed has UNIDAD_AME varchar(5), but GUMAme has CLAVE varchar(3). Keeping as string for now)
american_unit_code: Mapped[Optional[str]
] = mapped_column(String(5), nullable=True)
customs_code: Mapped[Optional[str]] = mapped_column(
String(2), nullable=True) # CLAVE_ADUANA
String(10), nullable=True) # CLAVE_ADUANA
ace_code: Mapped[Optional[str]] = mapped_column(
String(4), nullable=True) # CLAVEACE

View File

@@ -0,0 +1,58 @@
seed = [
('BAG', 'Bag'),
('BBL', 'Barrel'),
('BDL', 'Bundle'),
('BIC', 'Bing Chest'),
('BIN', 'Bin'),
('BKT', 'Bucket'),
('BLE', 'Bale'),
('BLK', 'Bulk'),
('BOX', 'Box'),
('BSK', 'Basket'),
('CAN', 'Can'),
('CAR', 'Carcass'),
('CAS', 'Case'),
('CBC', 'Container Bulk Cargo'),
('CBY', 'Carboy'),
('CCS', 'Can Case'),
('CHS', 'Chest'),
('COL', 'Coil'),
('COR', 'Cord'),
('CRT', 'Crate'),
('CSK', 'Cask'),
('CTN', 'Carton'),
('CYL', 'Cylinder'),
('DBK', 'Bry Bulk'),
('DRM', 'Drum'),
('DZ', 'Dozen'),
('FT', 'Feet'),
('GAL', 'Gallon'),
('HED', 'Heads of Beef'),
('HMP', 'Hamper'),
('KEG', 'Keg'),
('L', 'Liter'),
('LBK', 'Liquid Bulk'),
('LOG', 'Logs'),
('LUG', 'Lugs'),
('LVN', 'Lift Van'),
('M', 'Meters'),
('PAA', 'Pairs'),
('PAL', 'Pail'),
('PCL', 'Parcel'),
('PCS', 'Pieces'),
('PKG', 'Package'),
('POV', 'Private Vehicle'),
('QTR', 'Quarters of Beef'),
('REL', 'Reel'),
('ROL', 'Roll'),
('SAK', 'Sack'),
('SFT', 'Square Feet'),
('SHT', 'Sheet'),
('SID', 'Sides of Beef'),
('SKD', 'Skid'),
('TBE', 'Tube'),
('TBN', 'Tote Bin'),
('TIN', 'Tin'),
('TNK', 'Tank'),
('UNT', 'Unit'),
]

View File

@@ -0,0 +1,24 @@
seed = [
('KGS', 'Kilo'),
('KW', 'Kilowatt'),
('MILLR', 'Millar'),
('JGO', 'Juego'),
('KWH', 'Kilowatt/Hora'),
('TON', 'Tonelada'),
('BARR', 'Barril'),
('GRN', 'Gramo Neto'),
('DEC', 'Decenas'),
('CIEN', 'Cientos'),
('DOCE', 'Decenas (Docenas)'),
('GR', 'Gramo'),
('CAJA', 'Caja'),
('PZA', 'Botella'),
('CARAT', 'Carat'),
('MT', 'Metro Lineal'),
('M2', 'Metro Cuadrado'),
('M3', 'Metro Cubico'),
('PZA', 'Pieza'),
('PZA', 'Cabeza'),
('LT', 'Litro'),
('PAR', 'Par'),
]

View File

@@ -0,0 +1,48 @@
seed = [
('BBL', 'Barrels (42 Gallons ea) (Volume)'),
('BOL', 'Boluses (Dosage)'),
('CAP', 'Capsules (Dosage)'),
('CAR', 'Carats (Weight)'),
('CFT', 'Cubic Feet (Volume)'),
('CGI', 'Centigrams (Weight)'),
('CM', 'Centimeters (Long)'),
('CM3', 'Cubic Centimeters (Volume)'),
('CYD', 'Cubic Yards (Volume)'),
('DOZ', 'Dozen (Count)'),
('DPC', 'Dozen Pieces (Count)'),
('DPR', 'Dozen Pairs (Count)'),
('FOZ', 'Ounces, fluid (Volume)'),
('FT', 'Feet (Length)'),
('G', 'Grams (Weight)'),
('GAL', 'Gallons (US)(Volume)'),
('GR', 'Gross (Count)'),
('KG2', 'Kilograms (Weight)'),
('KM', 'Kilometers (Length)'),
('KM2', '1000 sq Meter Area'),
('KM3', '1,000 Cubic Meters (Volume)'),
('L', 'Liters (Volume)'),
('LB', 'Pounds (Weight)'),
('LNM', 'Linear Meters (Length)'),
('M', 'Meters (Length)'),
('M2', 'SQ Meter (Area)'),
('M3', 'Cubic Meters (Volume)'),
('MG', 'Miligrams (Weight)'),
('ML', 'Milliliters (Volume)'),
('NO', 'Number (Count)'),
('OZ', 'Weight'),
('PCS', 'Pieces (Count)'),
('PRS', 'Pairs (Count)'),
('PTL', 'Pints, liquid (US)(Volume)'),
('QTL', 'Quarts, liquid (US)(Volume)'),
('SFT', 'SQ Feet (Area)'),
('SQI', 'Sq Inches (Area)'),
('STN', 'Short Ion (2000 LB)(Weight)'),
('SUP', 'Suppositories (Dosage)'),
('SYD', 'Sq. Yards (Area)'),
('T', 'Metric Ton (Weight)'),
('TAB', 'Tablets (Dosage)'),
('TON', 'Long Ton (2,240 LB) (Weight)'),
('TOZ', 'Ounces, Troy or Apoth (Weight)'),
('YD', 'Yards (Length)'),
]

View File

@@ -0,0 +1,44 @@
seed = [
# (code, desc_es, desc_en, customs, american, ace, oma)
('BARR', 'BARRIL', 'BARIEL', '', 'BBL', 'BLL', ''),
('BD FT', 'PIE TABLA', 'BD FEET', '', 'FT', 'BFT', ''),
('BOLS', 'BOLSA', 'BAG', '', 'PCS', 'BG', ''),
('BTL', 'BOTELLA', 'BOTTLE', '', 'PCS', 'BO', ''),
('BULT', 'BULTO', 'BULK', '', 'PCS', 'VQ', ''),
('CAJA', 'CAJA', 'BOX', '', '', 'BX', ''),
('CARAT', 'CARAT', 'CARAT', '', '', 'HE', ''),
('CBZA', 'CABEZA', 'HEAD', '', 'PCS', 'Z4', ''),
('CIEN', 'CIENTO', 'CIEN', '', '', 'CEN', ''),
('CM', 'CENTIMETRO', 'CM', 'CM', 'CM', 'CMT', ''),
('CM2', 'CENTIMETRO CUADRADO', 'CM2', 'CM2', 'CM2', 'CMK', ''),
('DEC', 'DECENA', '', '', '', 'DC', ''),
('DM', 'DECIMETRO', 'DM', '', '', 'DMT', ''),
('DM2', 'DECIMETRO CUADRADO', 'SQ DM', '', '', 'DMK', ''),
('DOCE', 'DOCENA', 'DOZ', '', 'DOZ', 'DZN', 'DZ'),
('FOZ', 'ONZA LIQUIDA', 'FOZ', 'FOZ', 'FOZ', 'OZA', ''),
('FT', 'PIES', 'FT', 'FT', 'FT', 'LF', ''),
('FT2', 'PIE CUADRADO', 'FT2', '', 'SFT', 'FTK', ''),
('GAL', 'GALON', 'GAL', 'GAL', 'GAL', 'GLL', ''),
('GR', 'GRAMO', 'GRAM', '', '', 'GRM', ''),
('IN', 'PULGADA', 'IN', '', '', 'LI', ''),
('IN2', 'PULGADA CUADRADA', 'IN2', '', '', 'INK', ''),
('JGO', 'JUEGO', 'SET', '', '', 'SET', ''),
('KGS', 'KILOGRAMOS', 'KGS', '', 'KG2', 'KGM', ''),
('LB', 'LIBRAS', 'LB', '', '', 'LBR', ''),
('LT', 'LITRO', 'LT', 'LT', 'L', 'LTR', ''),
('M2', 'METRO CUADRADO', 'M2', 'M2', 'M2', 'MTK', ''),
('M3', 'METRO CUBICO', 'M3', 'M3', 'M3', 'MTQ', ''),
('MI', 'MILLA', 'MILE', '', 'KM', 'SMI', ''),
('MILLR', 'MILLAR', 'MILLR', '', '', 'MIL', ''),
('MT', 'METROS', 'MT', 'MT', 'M', 'MTR', ''),
('OZ', 'ONZA', 'OZ', 'FOZ', 'FOZ', 'OZ', ''),
('PAR', 'PAR', 'PAIR', '', '', 'PB', ''),
('PQ', 'PAQUETE', 'PACKAGE', '', 'PCS', 'PK_1', ''),
('PZA', 'PIEZA', 'PCS', 'PCS', 'PCS', 'C62_1', ''),
('QGL', 'CUARTO DE GALON', 'QGL', '', '', 'QT', ''),
('ROLL', 'ROLLO', 'ROLL', '', '', 'RO', ''),
('TON', 'TONELADA', 'TON', 'TON', 'TON', 'TNE_1', ''),
('TOZ', 'ONZA TROY', 'TOZ', '', 'TOZ', 'APZ', ''),
('YD', 'YARDA', 'YD', 'YD', 'YD', 'YRD', ''),
('YD2', 'YARDA CUADRADA', 'YD2', '', 'SYD', 'YDK', ''),
]

File diff suppressed because it is too large Load Diff