Stock de producto
Esta página cubre el producto — lo que se vende y no vuelve.
- El producto entra por la producción diaria, no por compra. Aquazaku lo envasa.
- Los activos retornables tienen su propio ciclo: Botellones y bases.
- El agua a granel se mide en litros y vive en los tanques, no acá: Producción y agua.
Cuatro cosas que parecen una
Sección titulada «Cuatro cosas que parecen una»El sistema controla cuatro tipos de existencia. Confundirlas es el error más caro que se puede cometer en este dominio.
| Producto | Insumo | Botellón | Base | |
|---|---|---|---|---|
| Ejemplo | Paca de agua | Tapa, sello | Envase de 20 L | Soporte |
| Se vende | Sí | No | No | No |
| Vuelve | No | No | Se espera que sí | Sí, es un préstamo |
| Se identifica | Por producto | Por tipo | Solo cantidad | ID individual |
| Al salir | Baja por venta | Baja por producción | Cambia de ubicación | Cambia de ubicación |
RN-STK-01 — El producto vive en un solo lugar: la bodega de la planta
Sección titulada «RN-STK-01 — El producto vive en un solo lugar: la bodega de la planta»Estado: ✅ Confirmada — 22-ago-2026. Corrige la versión anterior de esta regla, que suponía dos ubicaciones.
Todo el producto terminado está en la bodega de la planta. No hay stock en otro lado, y por lo tanto el stock no lleva ubicación: es cantidad por producto y lote, y nada más.
Por qué no se modela una ubicación con un solo valor posible: una columna
que hoy solo puede valer BODEGA la arrastra cada consulta, la repite cada test
y no permite verificar que el filtrado funcione, porque no hay contra qué
comparar. Es complejidad que se paga durante meses a cambio de una migración que
tal vez nunca haga falta.
RN-STK-02 — Todo movimiento de stock queda registrado con motivo y responsable
Sección titulada «RN-STK-02 — Todo movimiento de stock queda registrado con motivo y responsable»Estado: 🟡 Supuesto
El stock nunca se edita directamente. Se mueve mediante documentos:
| Documento | Efecto | Módulo |
|---|---|---|
| Cierre de producción | ➕ Producto · ➖ Tapas y sellos | M4 |
| Compra recibida | ➕ Insumos, no producto terminado | M9 |
| Venta | ➖ Producto | M6 |
| Devolución sana | ➕ Producto, al mismo lote | M6 |
| Descarte | ➖ Producto, con causa | M2 |
| Ajuste de inventario | ± con motivo obligatorio | M2 |
Los tres documentos de ruta —carga, venta en ruta y devolución de ruta— ya no existen: dependían de una segunda ubicación que RN-STK-01 descartó.
Por qué: un stock editable a mano es un stock que nadie cree. El ajuste
existe —el inventario físico siempre difiere— pero es un documento con nombre,
fecha y motivo, no un UPDATE.
RN-STK-03 — No se puede vender lo que no hay
Sección titulada «RN-STK-03 — No se puede vender lo que no hay»Estado: ✅ Confirmada — 22-ago-2026. Se simplifica junto con RN-STK-01.
Una venta solo puede despachar producto que exista y no esté vencido. No hay venta con stock negativo.
Por qué: permitir negativo convierte el inventario en una sugerencia. Y un inventario que es una sugerencia no sirve para pedir insumos, ni para detectar un faltante, ni para cerrar el día.
Dónde se hace cumplir: en la base, no solo en el servicio
(ADR-0006). Un saldo que no puede
ser negativo es exactamente el tipo de invariante que un CHECK garantiza
aunque un endpoint nuevo se olvide de validarlo.
RN-STK-04 — Los insumos de empaque son stock, y se consumen por producción
Sección titulada «RN-STK-04 — Los insumos de empaque son stock, y se consumen por producción»Estado: ✅ Confirmada
Tapas y sellos termoencogibles forman parte del stock y se controlan por cantidad, igual que el producto.
| Insumo | Se consume cuando |
|---|---|
| Tapa para botellón | Se llena y sella un botellón |
| Sello termoencogible | Se llena y sella un botellón |
La diferencia con el producto: el insumo no sale por venta, sale por producción (RN-PRD-09).
Por qué: una planta sin tapas no produce, por más agua que tenga en los tanques. Si el insumo no está en el sistema, nadie se entera de que se está acabando hasta que se acabó.
Lotes y vencimiento
Sección titulada «Lotes y vencimiento»RN-STK-08 — Cada cierre de producción genera un lote, vencimiento automático a 30 días
Sección titulada «RN-STK-08 — Cada cierre de producción genera un lote, vencimiento automático a 30 días»RN-STK-11 — El aviso de vencimiento próximo se configura, no se codifica
Sección titulada «RN-STK-11 — El aviso de vencimiento próximo se configura, no se codifica»Estado: ✅ Confirmada — cierra la pregunta 36 (22-ago-2026).
Un lote se marca «vence pronto» cuando le quedan 7 días o menos de vida.
Ese número es el valor inicial, no una constante del negocio: tiene que poder ajustarse desde la administración sin tocar código. Va con los demás umbrales configurables de M12 · Alertas.
Por qué 7 para empezar: la vida útil son 30 días (RN-STK-08), así que siete deja una cuarta parte para reaccionar — y «lo que vence esta semana» se dice fácil en la planta.
Por qué configurable: el número correcto depende de la rotación real, y esa todavía no se midió. Un umbral que avisa tarde no sirve; uno que avisa demasiado pronto entrena a ignorar el aviso, que es peor. Cuando haya datos de venta se va a querer moverlo, y eso no puede exigir un despliegue.
Entregado en M12 (7-sep-2026). Vive en la tabla parametros, clave
dias_aviso_vencimiento, y se mueve desde Alertas en la administración. La
constante DIAS_DE_AVISO_DE_VENCIMIENTO se borró — no quedó como default,
porque un default en el código más una fila en la base son dos lugares donde
configurar lo mismo.
El umbral viaja con los lotes (/stock/:id/lotes devuelve
diasDeAvisoDeVencimiento): configurarlo es de admin, pero mirarlo es de
quien ve stock, y el pos no tiene configuracion:ver.
Estado: ✅ Confirmada — cerrá la pregunta 🟢 “¿Hay control de lotes o vencimiento?” de Qué falta preguntar.
cierre_produccion_diario = { ..., lote_generado: "YYYY-MM-DD-L1", // generado por el sistema al cerrar fecha_empaque: date, ...}
producto_unidad = { sku: ..., lote_id: lote_id, fecha_empaque: date, fecha_vencimiento: date, // = fecha_empaque + 30 días ...}Reglas:
- Vencimiento automático:
vencimiento = empaque + 30 días. No se tipea a mano — lo calcula el sistema. - Lote generado al cerrar la producción: el formato
YYYY-MM-DD-L1(fecha + secuencia) sale del sistema y se imprime en la bolsa física por elpos. - Trazabilidad: cada venta registra el
lote_idvendido. Si hay recall o producto defectuoso, se identifica a qué clientes se les vendió. - FIFO en bodega: las ventas sacan primero el producto con vencimiento más próximo (lote más viejo).
- Vencidos se bloquean automáticamente: el stock con
fecha_vencimiento < hoyno se ofrece para la venta.
Por qué importa: anticipar la trazabilidad desde el MVP. Si en el futuro hay un recall, poder decir “esta venta se hizo con el lote X, esos clientes son los afectados” es invaluable.
Devoluciones y descarte
Sección titulada «Devoluciones y descarte»RN-STK-05 — Devoluciones vuelven al stock si están sanas; vencidas o dañadas se descartan
Sección titulada «RN-STK-05 — Devoluciones vuelven al stock si están sanas; vencidas o dañadas se descartan»Estado: ✅ Confirmada — cerrá la pregunta 🟢 “¿Se aceptan devoluciones de producto, o solo anulación de la venta completa?” de Qué falta preguntar.
Ver RN-VEN-10 para el flujo de la venta con devolución. Esta regla cubre el lado del stock:
| Estado del producto devuelto | Acción de stock |
|---|---|
sano |
Vuelve al mismo lote en BODEGA. Sigue su vida normal. |
vencido |
Descarte directo sin clasificar causa (vencimiento es objetivo). |
danado |
Dispara el flujo de descarte con clasificación de causa (RN-STK-06). |
RN-STK-06 — Descarte de producto: selectivo por unidad, causa obligatoria, sin castigo automático
Sección titulada «RN-STK-06 — Descarte de producto: selectivo por unidad, causa obligatoria, sin castigo automático»Estado: ✅ Confirmada — cerrá la pregunta 🟢 “¿Puede descartarse producto ya envasado por calidad?” de Qué falta preguntar.
Una unidad dañada o vencida se puede descartar sin destruir el lote entero. Solo las unidades afectadas.
descarte = { id: uuid, unidades: [{ sku, lote_id, fecha_vencimiento, ... }, ...], causa: "falla_produccion" | "mal_manejo_cliente" | "otro" | "vencido", registrado_por: user_id, // pos o admin registrado_en: timestamp, observaciones: string, reemplazo_generado_id: venta_id | null, // si causa == falla_produccion cliente_afectado_id: cliente_id | null, // si aplica}Política por causa:
| Causa | ¿Reemplazo al cliente? | ¿Quién paga? | Sistema registra |
|---|---|---|---|
falla_produccion |
✅ sí | Aquazaku | Descarte + reposición |
mal_manejo_cliente |
❌ no | Cliente asume | Descarte + entrada al historial del cliente |
vencido |
❌ no | Nadie | Descarte (sin clasificar) |
otro |
depende de revisión admin | depende | Descarte + flag para revisión |
El pos o admin debe clasificar la causa obligatoriamente al registrar. Sin clasificar, no se descarta.
Patrón compartido con RN-BAS-08 (recargo por daño de base):
- El sistema hace visible el historial de descarte por
mal_manejo_clienteper cliente. - El admin decide si inactiva al cliente. NO es castigo automático.
- Visibilidad sin automatización: el poder de decisión queda en el humano.
Una sola bodega
Sección titulada «Una sola bodega»RN-STK-07 — La planta de Campo de la Cruz es la única bodega y el único punto de venta
Sección titulada «RN-STK-07 — La planta de Campo de la Cruz es la única bodega y el único punto de venta»Estado: ✅ Confirmada — cerrá las preguntas 🟢 “¿Hay más de un punto de venta?” y “¿Hay más de una bodega?” de Qué falta preguntar.
stock_locations = ["BODEGA"] // una solaImplicaciones:
- No hay modelo multi-bodega. No hay transferencias entre bodegas.
- No hay stock itinerante (porque no hay
sellercon carga de camión — elsellersolo contacta, ver modelo operativo). posvende directo desdeBODEGA(RN-STK-01).- Si en algún momento Aquazaku abre una segunda planta o vende en otra ciudad, esta regla se reabre como decisión explícita — no es un toggle.
Preguntas abiertas
Sección titulada «Preguntas abiertas»- ¿Se controlan las bolsas como insumo, además de tapas y sellos?
- ¿Se define stock mínimo de tapas y sellos que dispare alerta de reposición?
- ¿Se compran insumos de tratamiento de agua? ¿Se controlan o son gasto?
- ¿Se lleva cuenta corriente con proveedores o se paga contra entrega?
- ¿Cada cuánto se hace inventario físico? — consolidada como pregunta 31.
