Ir al contenido

Productos y catálogo

Este documento define qué se vende. No cuánto hay (eso es Stock), ni cómo se cobra (eso es Ventas), ni qué envases están afuera (eso es Botellones y bases).

Es el catálogo: la lista de cosas que un pos puede elegir al registrar una venta, con su precio y su equivalencia en litros.


El error más caro de este módulo es tratar estas tres como si fueran lo mismo.

Producto Presentación Envase retornable
Qué es Lo que el cliente compra Cómo viene empacado El recipiente que vuelve
Ejemplo Recarga de botellón Paca de 20 bolsas de 600 ml El botellón físico
Se vende Sí — es un atributo del producto No
Tiene precio Sí — No (RN-ENV-06)
Sale y vuelve No — Sí
Vive en Este documento Este documento Botellones y bases

La paca sale y no vuelve. El botellón sale, se espera que vuelva, y a veces no vuelve. Son dos ciclos de vida distintos y un solo campo stock no los representa.


Estado: ✅ Confirmada — verificada con Aquazaku.

Esta tabla es el puente entre el agua y el catálogo. Todo el balance de producción depende de ella.

Presentación Contenido unitario Unidades Litros
Paca de bolsas 600 ml 600 ml 20 12 L
Paca de bolsas 300 ml 300 ml 50 15 L
Botellón 20 L — 20 L

Las equivalencias son dato de configuración, no código — RN-PRD-01. El día que salga una bolsa de 500 ml o una paca de 24, el sistema tiene que absorberlo sin un despliegue.


RN-CAT-01 — El catálogo es la única fuente de qué se puede vender

Sección titulada «RN-CAT-01 — El catálogo es la única fuente de qué se puede vender»

Estado: 🟡 Supuesto

Una venta solo puede referirse a un producto que existe en el catálogo y está activo. No hay producto “suelto”, ni línea de venta con descripción libre.

Por qué: una línea de venta con texto libre no se puede contar, ni costear, ni descontar de stock. El primer producto fuera del catálogo rompe el balance de litros de Producción sin dejar rastro.


RN-CAT-02 — Un producto no se borra, se desactiva

Sección titulada «RN-CAT-02 — Un producto no se borra, se desactiva»

Estado: 🟡 Supuesto

Un producto que deja de venderse se marca inactivo. Desaparece de la pantalla de venta, pero sigue existiendo para las ventas históricas, los lotes en stock y los reportes.

Por qué: una venta de marzo apunta a ese producto. Borrarlo deja comprobantes que ya no se pueden leer y reportes que no cuadran. Es el mismo principio que RN-CLI-02 para clientes.

Condición para desactivar: que no queden unidades en stock — implementada en M2 (22-ago-2026).

Un producto inactivo con saldo es inventario fantasma: nadie puede venderlo, porque no aparece en la pantalla de venta, ni descartarlo, porque para descartarlo primero hay que encontrarlo. Queda ocupando lugar en la bodega y en ninguna cuenta.

Cuentan también las unidades de lotes vencidos: están físicamente ahí y hay que descartarlas antes de dar el producto por terminado.


Estado: 🟡 Supuesto

Cada producto lleva sus tres precios encima: precio_residencial, precio_comercial y precio_minimo — tal como los modela RN-VEN-12.

Por qué: no es una preferencia de diseño, se deriva del roadmap. M6 (Ventas) depende de M0, M1, M2 y M5 — no de M10. Si los precios vivieran en M10, no se podría registrar una venta hasta tener M10 construido, y el orden de módulos dejaría de cerrar.

M10 (Precios y promociones) no se lleva los precios: agrega códigos de descuento encima (RN-VEN-13). El precio de lista sigue siendo del producto.


RN-CAT-04 — El precio mínimo es un piso, no un cuarto precio

Sección titulada «RN-CAT-04 — El precio mínimo es un piso, no un cuarto precio»

Estado: ✅ Confirmada — se deriva de RN-VEN-13.

precio_minimo no es una tercera lista de precios. Es el piso absoluto que ningún descuento puede perforar:

precio_final = max(precio_lista − descuento, precio_minimo)

Por qué: un código de descuento mal cargado no puede dejar una venta en $0. El piso es la red de seguridad, y por eso vive en el producto y no en el código de descuento — el que se equivoca es el código, no el producto.

Invariante: precio_minimo ≤ precio_comercial y precio_minimo ≤ precio_residencial. Un producto que no lo cumpla está mal cargado y el sistema tiene que rechazarlo al guardarlo, no al vender.


Sección titulada «RN-CAT-05 — Comprar botellones no entra producto al catálogo»

Estado: ✅ Confirmada — RN-ENV-06.

Cuando Aquazaku compra botellones para ampliar el parque, eso registra un activo retornable, no una entrada de producto vendible. No toca el catálogo ni el stock de producto terminado.

Por qué: es la frontera entre los dos ciclos de vida. Cruzarla hace que el sistema crea que tiene producto para vender cuando lo que tiene son envases vacíos.


RN-CAT-06 — El catálogo lo edita solo admin

Sección titulada «RN-CAT-06 — El catálogo lo edita solo admin»

Estado: ✅ Confirmada — por Aquazaku, 21-ago-2026. El precio es un parámetro del sistema y solo admin lo cambia.

pos, seller y contador leen el catálogo. Solo admin crea productos, edita precios y desactiva.

Por qué: el precio es la variable más sensible del negocio. Un pos que puede editar el precio de lista vuelve inútil todo el sistema de descuentos con piso — bajaría el precio en vez de pedir un código.

Todo cambio de precio se audita (RN-ACC-04): quién lo cambió, cuándo, de cuánto a cuánto.


RN-CAT-07 — Cambiar un precio no reescribe las ventas pasadas

Sección titulada «RN-CAT-07 — Cambiar un precio no reescribe las ventas pasadas»

Estado: ✅ Confirmada — RN-VEN-04.

El precio se congela en el comprobante al momento de vender. Editar el catálogo mañana no toca la venta de hoy.

Por qué: un comprobante es un hecho histórico. Si el reporte de marzo cambia porque alguien tocó un precio en agosto, la contabilidad deja de ser verificable.


RN-CAT-08 — La primera entrega y la recarga son el mismo producto

Sección titulada «RN-CAT-08 — La primera entrega y la recarga son el mismo producto»

Estado: ✅ Confirmada — por Aquazaku, 21-ago-2026.

Un cliente que nunca tuvo botellón paga exactamente lo mismo que uno que recarga: el precio del agua. No se le cobra el envase, ni depósito, ni garantía.

Por lo tanto el catálogo tiene un solo producto de botellón — Recarga de botellón 20 L — y no dos.

Por qué: el botellón no se vende, se intercambia (RN-BAS-08: sin garantía nunca, sin depósito). Si el catálogo tuviera dos productos con precios distintos, estaría cobrando un envase que el negocio no cobra.

Dónde queda la diferencia entonces: en el saldo de envases, no en la plata. La primera entrega aumenta en uno el saldo de botellones del cliente (RN-ENV-04); la recarga lo deja igual (RN-ENV-03). Misma venta, distinto movimiento de envase — y ese movimiento es de M7, no del catálogo.


RN-CAT-09 — El precio declara qué incluye, aunque hoy no haya IVA

Sección titulada «RN-CAT-09 — El precio declara qué incluye, aunque hoy no haya IVA»

Estado: 🟡 Supuesto — el hecho de negocio está confirmado; el mecanismo es propuesta nuestra.

Hoy Aquazaku no retiene IVA ni declara nada. Pero va a llegar el momento de conectar con facturación electrónica, retenciones y declaraciones según la ley colombiana — es la misma expectativa que ya sostiene RN-VEN-11.

La respuesta no es construir el motor de impuestos ahora. Es no perder la información que lo hace posible después.

producto = {
...,
precio_residencial: number,
precio_comercial: number,
precio_minimo: number,
precio_incluye_impuestos: bool, // hoy: true (el precio es el que se cobra)
tarifa_iva_porcentaje: number, // hoy: 0
...
}
venta_linea = {
...,
precio_aplicado: number,
precio_incluia_impuestos: bool, // snapshot, igual que el precio
tarifa_iva_aplicada: number, // snapshot
...
}

Por qué el snapshot y no solo el producto: el precio se congela en el comprobante (RN-VEN-04), y la situación tributaria tiene que congelarse con él. El día que Aquazaku empiece a discriminar IVA y actualice el catálogo, las ventas viejas tienen que seguir diciendo qué representaban.

Sin eso, dentro de dos años nadie puede responder si aquellos $10.000 de 2026 eran base gravable o total con impuesto. Y no se puede reconstruir: es información que solo existía en el momento de la venta.

El costo de la alternativa: guardar el precio como un número pelado sale gratis hoy y carísimo después. Es exactamente el argumento de RN-VEN-11 — “sin el campo, perdemos la información” — aplicado al precio en vez de a la intención de facturar.


RN-CAT-10 — La paca es indivisible: no se venden bolsas sueltas

Sección titulada «RN-CAT-10 — La paca es indivisible: no se venden bolsas sueltas»

Estado: ✅ Confirmada — por Aquazaku, 21-ago-2026.

La paca es la unidad atómica del sistema. Se produce por paca, se stockea por paca y se vende por paca. No hay media paca ni bolsas sueltas.

Por qué importa más allá del catálogo: si se vendieran bolsas sueltas, el stock tendría que contar unidades dentro de cada paca, y una paca abierta sería un estado nuevo que hoy no existe. Eso se propaga a Stock —los lotes dejarían de contarse en pacas— y a Producción, donde el cierre diario genera lote por paca.

Manteniendo la paca indivisible, la misma unidad sirve para los tres módulos y no hace falta convertir en ninguna frontera.


RN-CAT-11 — El código lo genera el sistema; la identidad sigue siendo el UUID

Sección titulada «RN-CAT-11 — El código lo genera el sistema; la identidad sigue siendo el UUID»

Estado: ✅ Confirmada — por Aquazaku, 21-ago-2026. Hoy no usan códigos propios.

Cada producto lleva un código corto y legible que genera el sistema:

P20U_600ML Paca de 20 bolsas de 600 ml
P50U_300ML Paca de 50 bolsas de 300 ml
BOT_20L Recarga de botellón de 20 L

Cada número trae su unidad pegada. 20U son veinte unidades, 600ML son seiscientos mililitros. No hay convención que recordar: un código como P20U_600ML se lee igual aunque nunca hayas visto el sistema, mientras que un PACA-20-600 obliga a saber cuál de los dos números es cuál.

El botellón se mide en litros porque así lo nombra el negocio —“botellón de veinte litros”— y con la unidad explícita eso deja de ser una excepción incómoda.

Pero el código no es la identidad. La identidad es el UUID interno — mismo principio que RN-CLI-01 para clientes: el documento sirve para buscar, no para identificar.

Por qué separarlos: el día que un código se escriba mal, o que Aquazaku quiera renombrar BOT_20L a RECARGA_20L, no puede arrastrar consigo las ventas históricas, los lotes ni los movimientos de stock. Todo eso apunta al UUID.

El código lleva lo que distingue al producto

Sección titulada «El código lleva lo que distingue al producto»

Que el código incluya cantidad y contenido no es adorno: es lo que hace que dos productos distintos nunca generen el mismo código.

Producto Código
Paca de 20 bolsas de 600 ml P20U_600ML
Paca de 24 bolsas de 600 ml — RN-PRD-01 la anticipa P24U_600ML
Bolsa de 500 ml en paca de 24 P24U_500ML

Sin eso haría falta desambiguar con un contador, y PACA-600-2 no le dice nada a nadie: solo que es “la segunda”. El pos que la ve en pantalla tendría que ir a mirar el detalle igual, y ahí el código falló en su única tarea.

El sufijo queda para un solo caso: que un producto se desactive y meses después se reintroduzca idéntico. Ahí P20U_600ML_2 sí significa algo — es la segunda encarnación, y el código viejo sigue tomado a propósito.

El código es único y no se reusa. Si un producto se desactiva (RN-CAT-02), su código queda tomado: reciclarlo haría que un comprobante viejo parezca referirse al producto nuevo.


Ninguna. Las cuatro que estaban abiertas se cerraron el 21-ago-2026: RN-CAT-06 y 08 (precio y primera entrega), RN-CAT-09 (IVA), RN-CAT-10 (paca indivisible) y RN-CAT-11 (código).

El dominio de M1 está completo y se puede escribir la spec.