Modelo de datos
La idea más importante de todo el sistema, así que merece su propia página: el stock nunca se guarda como un número. Se calcula, cada vez que se pide, sumando el historial de movimientos.
Cada entrada o salida de una variante del almacén queda anotada como una fila en esta tabla — nunca se edita ni se borra un movimiento ya creado, solo se añaden nuevos:
El signo de cantidad depende del tipo, y la base de datos lo obliga con una restricción (CHECK), no solo la aplicación:
El stock de una variante es la suma de todos sus movimientos. Por almacén, se filtra además por almacen_id:
En el backend esto vive en apps/principal/services.py (stock_variante / stock_por_almacen), y en la base de datos hay una vista equivalente, v_stock_variante, que hace exactamente el mismo cálculo con SQL — se usa desde v_stock_bajo para saber qué reponer.
La variante CUAD-100H (Cuaderno universitario, 100 hojas) tiene estos movimientos, en orden:
| Fecha | Tipo | Referencia | Cantidad |
|---|---|---|---|
| 02/03 | compra | Recepción orden #14 | +200 |
| 05/03 | venta | Pedido #881 | −12 |
| 06/03 | venta | Pedido #883 | −45 |
| 10/03 | merma | Cajas dañadas en almacén | −3 |
| 18/03 | ajuste | Conteo físico (sobraban 2) | +2 |
| Stock actual (suma de todo lo anterior) | 142 | ||
Nadie escribió "142" en ningún sitio: es 200 − 12 − 45 − 3 + 2. Si mañana entra una nueva compra, el número cambia solo, sin tocar ninguna fila anterior.
movimiento_inventario crece sin límite (nunca se borra nada), así que sumar sobre ella podría volverse lento con el tiempo. Por eso tiene índices dedicados: idx_mov_variante y idx_mov_fecha para las sumas y filtros por periodo, y un índice parcial idx_mov_variante_fecha_venta (solo filas de tipo venta) pensado específicamente para "última venta de esta variante" — la consulta más pesada de rotación/stock parado, porque sin él implica revisar todo el historial de cada SKU.
El modelo completo de la tabla está en Esquema de datos; el contrato de la API que lo expone, en API del backend; y la explicación en lenguaje de negocio, sin código, en Almacén / Inventario.