22from datetime import datetime
33from decimal import Decimal
44from enum import Enum
5-
5+ from pydantic import field_validator
66from pydantic import EmailStr
77from sqlmodel import Field , Relationship , SQLModel , Column
88from sqlalchemy import Numeric
1111# Enums for Inventory Management System
1212class UserRole (str , Enum ):
1313 """Roles de usuario en el sistema de inventario"""
14- ADMINISTRADOR = "administrador "
15- VENDEDOR = "vendedor "
16- AUXILIAR = "auxiliar "
14+ ADMINISTRADOR = "ADMINISTRADOR "
15+ VENDEDOR = "VENDEDOR "
16+ AUXILIAR = "AUXILIAR "
1717
1818
1919class MovementType (str , Enum ):
2020 """Tipos de movimientos de inventario"""
21- ENTRADA_COMPRA = "entrada_compra "
22- SALIDA_VENTA = "salida_venta "
23- AJUSTE_CONTEO = "ajuste_conteo "
24- AJUSTE_MERMA = "ajuste_merma "
25- DEVOLUCION_CLIENTE = "devolucion_cliente "
26- DEVOLUCION_PROVEEDOR = "devolucion_proveedor "
21+ ENTRADA_COMPRA = "ENTRADA_COMPRA "
22+ SALIDA_VENTA = "SALIDA_VENTA "
23+ AJUSTE_CONTEO = "AJUSTE_CONTEO "
24+ AJUSTE_MERMA = "AJUSTE_MERMA "
25+ DEVOLUCION_CLIENTE = "DEVOLUCION_CLIENTE "
26+ DEVOLUCION_PROVEEDOR = "DEVOLUCION_PROVEEDOR "
2727
2828
2929class AlertType (str , Enum ):
3030 """Tipos de alertas de inventario"""
31- LOW_STOCK = "low_stock "
32- OUT_OF_STOCK = "out_of_stock "
31+ LOW_STOCK = "LOW_STOCK "
32+ OUT_OF_STOCK = "OUT_OF_STOCK "
3333
3434
3535# Shared properties
@@ -210,7 +210,7 @@ class ProductBase(SQLModel):
210210 sku : str = Field (min_length = 1 , max_length = 50 , unique = True , index = True )
211211 name : str = Field (min_length = 1 , max_length = 255 )
212212 description : str | None = Field (default = None , max_length = 500 )
213- category_id : uuid .UUID | None = None
213+ category_id : uuid .UUID | None = Field ( default = None , foreign_key = "category.id" )
214214 unit_price : Decimal = Field (
215215 sa_column = Column (Numeric (10 , 2 ), nullable = False ),
216216 gt = 0 ,
@@ -236,7 +236,7 @@ class ProductUpdate(SQLModel):
236236 sku : str | None = Field (default = None , min_length = 1 , max_length = 50 )
237237 name : str | None = Field (default = None , min_length = 1 , max_length = 255 )
238238 description : str | None = None
239- category_id : uuid .UUID | None = None
239+ category_id : uuid .UUID | None = Field ( default = None , foreign_key = "category.id" )
240240 unit_price : Decimal | None = Field (default = None , gt = 0 )
241241 sale_price : Decimal | None = Field (default = None , gt = 0 )
242242 unit_of_measure : str | None = Field (default = None , max_length = 50 )
@@ -279,10 +279,9 @@ class ProductsPublic(SQLModel):
279279
280280class InventoryMovementBase (SQLModel ):
281281 """Base model for InventoryMovement with shared properties"""
282- product_id : uuid .UUID
282+ product_id : uuid .UUID = Field ( foreign_key = "product.id" )
283283 movement_type : MovementType
284284 quantity : int = Field (
285- ne = 0 ,
286285 description = "Positivo para entradas, negativo para salidas"
287286 )
288287 reference_number : str | None = Field (default = None , max_length = 100 )
@@ -293,6 +292,13 @@ class InventoryMovementBase(SQLModel):
293292 gt = 0
294293 )
295294 movement_date : datetime = Field (default_factory = datetime .utcnow )
295+
296+ @field_validator ('quantity' )
297+ @classmethod
298+ def quantity_not_zero (cls , v : int ) -> int :
299+ if v == 0 :
300+ raise ValueError ('La cantidad no puede ser 0' )
301+ return v
296302
297303
298304class InventoryMovementCreate (InventoryMovementBase ):
@@ -338,7 +344,7 @@ class InventoryMovementsPublic(SQLModel):
338344
339345class AlertBase (SQLModel ):
340346 """Base model for Alert with shared properties"""
341- product_id : uuid .UUID
347+ product_id : uuid .UUID = Field ( foreign_key = "product.id" )
342348 alert_type : AlertType
343349 current_stock : int = Field (ge = 0 )
344350 min_stock : int = Field (ge = 0 )
0 commit comments