# Inventario

## Paso a paso

Las tareas más comunes, resumidas. El detalle de cada una está en las secciones numeradas.

### Dar de alta un producto nuevo

1. En el menú lateral abre **📦 Productos → Nuevo producto**.
2. Escanea el **Código de Barras** (o pulsa **🏷️ Generar código interno** si no trae).
3. Escribe **Nombre**, **Costo**, **Precio** y la **Cantidad** que tienes hoy.
4. Elige **Se vende por** (Pieza o Granel), el **Proveedor** y, si quieres, la **Categoría** y la **Fecha de caducidad**.
5. Pulsa **Guardar**.

Ver sección 5.

### Cambiar el precio de un producto

1. Abre **📦 Productos → Inventario** y busca el producto.
2. En su menú **⋮** elige **✏️**.
3. Cambia el **Precio** y pulsa **Guardar Cambios**.

Ver sección 6.

### Meter mercancía que llegó

- **Con factura o nota del proveedor:** regístrala en [Compras](./compras.md).
- **Sin documento** (resurtido directo, muestra, traspaso):
  1. En **Inventario**, pulsa **📥 Agregar Nuevo Inventario** (o 📥 en el menú **⋮** del producto).
  2. Elige el producto y escribe la cantidad, el costo y la caducidad de esta entrada.
  3. Pulsa **Agregar al Inventario**.

Ver sección 7.

### Corregir el stock después de contar

1. En el menú **⋮** del producto elige **🧮 Ajuste de inventario**.
2. Escribe la **Cantidad contada** y el **Motivo**.
3. Pulsa **Registrar ajuste** (si falta mercancía, confirma con **Sí, descontar**).

Ver sección 8.

### Sacar mercancía caducada o perdida (merma)

1. En el menú **⋮** del producto elige **📋 Ver lotes**.
2. Pulsa **Dar de baja** en el lote afectado.
3. Escribe el motivo y confirma con **Sí, dar de baja**.

Ver sección 9.

## 1. ¿Qué es Inventario?

Es el catálogo de productos de la tienda: precios, costos, existencias y fechas de caducidad. Aquí se ve de un vistazo qué está por agotarse, qué está por caducar y cuánto capital hay invertido en mercancía.

**Quién puede usarlo:** Inventario es de **administrador únicamente** — dar de alta productos, editarlos, agregar existencias o desactivarlos requiere permisos de admin (`requireAdmin`). Un cajero no ve estas acciones.

### 1.1 Cómo se relaciona el stock con los "lotes"

El stock de un producto **no se guarda como un solo número editable a mano**: cada vez que entra mercancía se crea un **lote** (cantidad, costo y fecha de caducidad de esa entrada específica). La cantidad, el costo y la caducidad que se ven en la fila del producto son un **resumen calculado** a partir de sus lotes vigentes (la cantidad es la suma, el costo es el promedio ponderado y la caducidad es la más próxima) — esto permite que un mismo producto tenga, por ejemplo, un lote más viejo por vencer antes y un lote más nuevo con otra fecha, sin perder esa trazabilidad.

Por eso la **cantidad y la caducidad ya no se escriben a mano** en la edición del producto. Solo cambian por alguna de estas vías:

| Quieres... | Usa... |
|---|---|
| Registrar mercancía que llegó de un proveedor con factura, nota o remisión | [Compras](./compras.md) (calcula el costo real por pieza y lleva lo que debes) |
| Registrar mercancía que entró sin documento (resurtido directo, muestra, traspaso) | **📥 Agregar inventario** (sección 7) |
| Corregir el stock porque contaste y no coincide | **🧮 Ajuste de inventario** (sección 8) |
| Sacar mercancía perdida, caducada o devuelta | **Dar de baja** un lote (sección 9) |
| Corregir la fecha de caducidad de un lote | **📅** en el detalle del lote (sección 9) |

## 2. Llegar al módulo

En el menú lateral abre **📦 Productos → Inventario** (el grupo Productos se despliega al darle clic; solo uno de los grupos del menú queda abierto a la vez). En la parte superior:

- **← Volver al Inicio**
- **📥 Agregar Nuevo Inventario** — registrar entrada de mercancía a un producto existente (crea un lote nuevo). Si la mercancía viene con factura o nota de un proveedor, mejor regístrala en [Compras](./compras.md).
- **📦 Importar del Catálogo** — abre el [Catálogo Precargado de Abarrotes de México](./catalogo-precargado.md) para dar de alta varios productos frecuentes de un solo clic, en vez de capturarlos a mano.
- **➕ Nuevo Producto** — te lleva a la pantalla de registro de un producto totalmente nuevo.

## 3. La tabla de productos

Columnas: ID, Producto (nombre + descripción), Proveedor, Categoría, Costo Unit., Precio Venta, Margen (%), Stock Actual, Valor Total (precio × cantidad), Caducidad y Acciones.

La **Categoría** es opcional: se puede asignar al registrar o editar un producto, o llega ya asignada al importar desde el [Catálogo Precargado](./catalogo-precargado.md). Un producto sin categoría muestra "Sin categoría" en esa columna.

### 3.1 Indicadores de stock

| Badge | Significado |
|---|---|
| ✔ (verde) | Stock normal. |
| ⚠ Bajo (verde/amarillo con número) | Quedan 5 unidades o menos. |
| ✕ Agotado | Cantidad en 0. |

### 3.2 Indicadores de caducidad

- Se muestra la fecha de caducidad **más próxima** entre los lotes con existencia del producto (o "N/A" si no aplica, como productos sin fecha). Cada lote puede tener la suya (ver la sección 9).
- **VENCIDO** — si la fecha ya pasó.
- **Por vencer** — si caduca dentro de los próximos 30 días.

### 3.3 Margen

Se calcula como `precio - costo` y el porcentaje que representa sobre el precio de venta. Si un producto no tiene `costo` explícito (dato legado), el sistema asume un costo del **72% del precio** como estimado.

### 3.4 Buscar y filtrar

- **Buscador**: por nombre, descripción o proveedor.
- **Filtro Activos / Inactivos / Todos**: por defecto solo se ven los productos activos. Elige "Inactivos" para encontrar un producto desactivado y reactivarlo. Los inactivos se ven atenuados y con la etiqueta **Inactivo**.
- **Filtro de estado**: Todos / ⚠️ Bajo Stock (≤5) / ✕ Agotados / ⏰ Próximos a vencer (<30 días) / 🚫 Vencidos.
- **Filtro de código de barras**: Con y sin código / 🏷️ Sin código de barras / ▮▯▮ Con código de barras. Sirve para ver qué productos todavía necesitan código (ver [Etiquetas](./etiquetas.md)).
- **Filtro de proveedor**: limita la lista a un proveedor específico, o a **Sin proveedor** para ver los productos que no tienen uno asignado.
- **Filtro de categoría**: limita la lista a una categoría específica (Bebidas, Lácteos, Limpieza del Hogar, etc.).
- El contador junto a los filtros muestra cuántos productos coinciden.

## 4. Acciones por producto (menú ⋮)

Cada fila tiene un botón **⋮** que abre sus acciones:

| Ícono | Acción |
|---|---|
| 📥 | Agregar inventario (registrar entrada / lote) para ese producto. No aparece en productos inactivos. |
| 🧮 | Ajuste de inventario: corregir el stock con un conteo físico. No aparece en productos inactivos. |
| 📋 | Ver los lotes registrados de ese producto (origen, caducidad por lote y bajas). |
| 🔖 | Solo crear el código de barras interno del producto, con confirmación y sin imprimir (solo aparece si el producto no tiene código) — ver el [manual de Etiquetas](./etiquetas.md). |
| 🏷️ | Imprimir la etiqueta con código de barras del producto (abre la pantalla Etiquetas con el producto marcado). |
| ✏️ | Editar los datos del producto. |
| 🚫 / ✅ | Desactivar el producto (pide confirmación) o reactivarlo si ya estaba inactivo. Ver la sección 10. |

## 5. Registrar un producto nuevo

1. Clic en **➕ Nuevo Producto** (te lleva a la pantalla de registro, no a un modal).
2. Llena el formulario:
   - **Código de Barras** (opcional) — escanea el empaque con el lector o escríbelo. Si el producto no trae código de fábrica (tortas, sándwiches...), el botón **🏷️ Generar código interno** lo crea por ti (pide confirmación y solo está activo con el campo vacío) — ver el [manual de Etiquetas](./etiquetas.md).
   - **Nombre** (obligatorio).
   - **Descripción** (opcional).
   - **Costo** — lo que te cuesta a ti comprarlo. Al capturarlo junto con el precio, se muestra en vivo el **margen estimado por pieza** ($ y %).
   - **Precio** — precio de venta al público.
   - **Cantidad** — existencias iniciales.
   - **Se vende por** — "Pieza" (por defecto) o "Peso / Granel (kg)". Marcarlo como Granel habilita cantidades decimales y la venta por peso/importe en el POS — ver el [manual de Venta a Granel / Básculas](./venta-a-granel.md).
   - **Proveedor** — se elige de la lista de [proveedores](./proveedores.md) ya registrados (es opcional: deja **-- Sin proveedor --** si no lo sabes o no lo necesitas). Si el proveedor que necesitas no existe aún, clic en el botón **➕** junto al selector: abre "Registrar Nuevo Proveedor" sin salir de esta pantalla, y al guardarlo queda seleccionado automáticamente.
   - **Categoría** (opcional) — Bebidas, Lácteos, Limpieza del Hogar, etc. Sirve para filtrar la tabla de Inventario después. También tiene su botón **➕** para agregar una categoría nueva sin salir de la pantalla (ver la nota sobre categorías en la sección 6 — no se guardan en la base de datos, solo mientras dure la sesión del navegador).
   - **Fecha de caducidad** (si aplica).
   - Fecha de registro / actualización se llenan automáticamente con el día de hoy.
3. Clic en **Guardar** (o el botón equivalente del formulario). Al guardar exitosamente, el sistema te regresa automáticamente a la pantalla de Inventario.
4. **Cancelar** limpia el formulario y regresa a Inicio sin guardar nada.

La **Cantidad** que captures aquí crea el primer lote del producto, con origen **Inicial** (ver la sección 9). Después de dar de alta el producto, la cantidad solo se mueve por Compras, Agregar inventario, Ajuste de inventario o ventas.

**Validaciones:** nombre obligatorio; costo, precio y cantidad deben ser números válidos y no negativos.

### 5.1 IEPS y claves del SAT

Estos campos sirven para **facturar** (CFDI) y son **opcionales**. Si no los llenas, el producto se vende y se cobra igual; solo cambia cómo sale en la factura.

- **IEPS del producto** (solo en México; el campo no aparece en otros países): el Impuesto Especial sobre Producción y Servicios. Solo se capturan las **tasas** (8 % botanas y dulces, bebidas alcohólicas, tabacos). Las cuotas por litro de refrescos van incluidas en el precio, no se capturan aquí. "Sin IEPS" es lo normal para la mayoría de los abarrotes.
- **Clave de producto SAT** (8 dígitos): la clave del catálogo del SAT que describe el producto. Puedes escribirla directamente o elegirla de la lista de sugerencias que aparece al escribir.
  - **¿No sabes la clave? Búscala por nombre:** debajo del campo de clave hay un buscador con el texto "¿No sabes la clave? Búscala por nombre (refresco, jamón, pan…)". Escribe lo que vendes (por ejemplo "refresco", "jamón" o "pan"); no importan los acentos ni las mayúsculas. Aparece una lista de claves con su descripción; haz clic en la que corresponda y la clave se llena sola. Si escribes solo números, aparecen las claves que empiezan con esos números. Si no hay coincidencias, el sistema te lo dice.
  - Si haces clic en el buscador sin escribir nada, aparecen las claves de abarrotes más comunes para elegir de ahí.
  - Debajo de la clave aparece su descripción oficial, para confirmar que es la que quieres. Si escribes una clave que no está en el catálogo de sugerencias, el sistema te pide verificarla en el catálogo oficial del SAT. Si una clave dice "sin confirmar en la guía del SAT: verifícala", revísala antes de facturar.
- **Unidad SAT**: "Automática" (por defecto) usa **H87 (pieza)** o **KGM (kilogramo)** según si el producto se vende por pieza o por peso. Solo cámbiala si tu proveedor de facturación te pide otra unidad.
- **Clave genérica**: si dejas la clave de producto vacía, la factura usa la clave genérica **01010101** ("No existe en el catálogo") y el sistema te avisa al facturar. Funciona, pero algunos clientes (sobre todo empresas) pueden pedir una clave específica; en ese caso captura la clave correcta en la ficha del producto.
- **IEPS en la factura**: el IEPS solo se desglosa en la factura si el cliente lo pide. Si no, el precio de venta sigue incluyendo el impuesto como siempre.

## 6. Editar un producto existente

1. Clic en **✏️** en la fila del producto.
2. Se abre un modal con: código de barras, nombre, descripción, costo, precio, cantidad en existencia, se vende por, proveedor, categoría y caducidad más próxima. También se ve el margen de ganancia calculado en vivo.
3. **La cantidad en existencia y la caducidad más próxima aparecen bloqueadas**: son el resultado de los lotes y ya no se editan aquí. Debajo hay un recuadro que lo explica ("La cantidad y la caducidad salen de los lotes del producto y no se editan aquí. Para meter mercancía usa Compras o Agregar inventario; para corregir un conteo físico usa Ajuste de inventario.") con tres atajos: **📥 Agregar inventario**, **🧮 Ajuste de inventario** y **📋 Ver lotes**. Al pulsar uno se cierra la edición y se abre esa pantalla.
4. **El costo** también depende de los lotes:
   - **Con existencias**, la casilla de costo está bloqueada ("Se calcula con los lotes en existencia."): es el promedio ponderado de los lotes que hay.
   - **Sin existencias** (stock en 0), se puede editar ("Sin existencias: costo de referencia para la próxima entrada.").
5. Si el proveedor que necesitas todavía no existe, clic en el botón **➕** junto al selector de Proveedor: abre el modal de "Registrar Nuevo Proveedor" **sin cerrar** el modal de edición del producto. Al guardarlo, el modal de proveedor se cierra solo y el nuevo proveedor queda seleccionado automáticamente en el producto que estabas editando.
6. Lo mismo aplica para Categoría: el botón **➕** junto al selector abre "Nueva Categoría" sin salir del modal de edición; al guardar, la categoría queda seleccionada en el producto. A diferencia de los proveedores (que se guardan en el sistema), la lista de categorías **no se guarda por separado**: vive en la memoria del navegador, así que una categoría agregada así solo aparece en esa pestaña mientras no recargues la página. El producto sí guarda el nombre de su categoría de forma permanente, pero otra persona (u otra sesión) que abra el sistema no verá esa categoría en su selector hasta que algún producto con ese nombre exista y se vuelva a capturar ahí.
7. Clic en **Guardar Cambios**.

Lo que sí se edita aquí: nombre, descripción, código de barras, precio, "se vende por", proveedor, categoría, IEPS y claves del SAT (ver la sección 5.1) y (solo sin existencias) el costo.

**Importante:** si por cualquier vía se intenta cambiar la cantidad, la caducidad, o el costo de un producto con existencias, el sistema lo rechaza con el mensaje de que "se calcula con los lotes y ya no se edita aquí" y te indica usar Compras, "Agregar inventario", "Ajuste de inventario" o la baja de lote.

## 7. Agregar nuevo inventario (entrada de mercancía)

Crea un **lote** independiente (con su propia cantidad, costo y caducidad) en vez de solo sumar un número al stock. La ventana explica: "Registra mercancía recibida como un lote nuevo, sin modificar el costo ni la caducidad del stock que ya estaba en inventario."

> **¿Viene de un proveedor con factura o nota?** La ventana trae el aviso "¿Viene de un proveedor con factura o nota? **Regístrala en Compras** para llevar costo y cuentas por pagar." El enlace te lleva a [Compras](./compras.md). Usa "Agregar inventario" para entradas sin documento de proveedor (resurtido directo, muestras, traspasos): aquí **no** se lleva la cuenta de lo que debes.

1. Clic en **📥 Agregar Nuevo Inventario** (desde el encabezado, sin producto preseleccionado, o desde el ícono 📥 de una fila específica, que ya viene preseleccionado).
2. Elige el **producto** (si no vino preseleccionado). Al elegirlo, el campo de costo se autocompleta con el costo actual de ese producto (puedes cambiarlo si esta entrada tuvo otro costo).
3. Ingresa la **cantidad recibida** (debe ser mayor a 0). En productos por pieza son números enteros; en productos a granel (kg) admite decimales.
4. Confirma o ajusta el **costo unitario** de esta entrada.
5. Ingresa la **fecha de caducidad** de este lote, si aplica.
6. Opcional: escribe el **motivo de la entrada** (hasta 200 caracteres; ej. "Resurtido directo, muestra, traspaso"). Queda guardado en el lote y se ve en la columna Origen.
7. Clic en **Agregar al Inventario**.

El producto queda con un nuevo lote de origen **Manual**; la cantidad, costo y caducidad mostrados en la tabla principal del producto se recalculan a partir de **todos** sus lotes vigentes.

## 8. Ajuste de inventario (conteo físico)

Úsalo cuando **contaste la mercancía en el anaquel y el número no coincide con el del sistema** (conteo mensual, robo, error de captura, algo que se regaló). En lugar de escribir el nuevo stock encima, el ajuste deja constancia de la diferencia.

1. En el menú **⋮** del producto elige **🧮 Ajuste de inventario** (o el atajo dentro de la edición del producto). No aparece en productos inactivos.
2. Verás el nombre del producto y la **Existencia en sistema**.
3. Escribe la **Cantidad contada** (lo que realmente hay; en productos por pieza, un número entero; en kg admite decimales). Debajo, **Diferencia** te dice en vivo cuánto sobra ("Sobran") o cuánto falta ("Faltan").
4. Escribe el **Motivo** (obligatorio, hasta 200 caracteres; ej. "Conteo físico mensual, robo, error de captura").
5. Clic en **Registrar ajuste**.

**Cómo se aplica:**

- **Si sobra mercancía** (contaste más): se crea un **lote nuevo de origen Ajuste** con la diferencia, al **costo actual** del producto y sin fecha de caducidad (si la tiene, edítala después con 📅).
- **Si falta mercancía** (contaste menos): el sistema primero te pide confirmar ("¿Registrar ajuste con faltante?", botón rojo **Sí, descontar**) y luego **descuenta la diferencia de los lotes** en el mismo orden en que se venden: primero los que **caducan antes** y, al final, los que no tienen caducidad. Un lote que se vacía queda en 0 con la baja registrada ("Ajuste de inventario: *tu motivo*"); uno que se reduce solo baja su cantidad.
- Si la cantidad contada es igual a la del sistema, avisa "La cantidad contada coincide con la del sistema" y no hace nada.

Nada se borra: el ajuste recibe un folio (**AJU-####**) y queda en el historial con la existencia en sistema, la cantidad contada, la diferencia, el motivo y quién lo hizo. **No se puede deshacer**; si te equivocaste, haz otro ajuste con el número correcto.

## 9. Ver lotes, editar su caducidad y darlos de baja (merma)

1. En el menú **⋮** del producto elige **📋 Ver lotes**.
2. Se muestra una tabla con cada lote: **Cantidad**, **Costo Unit.**, **Caducidad**, **Fecha de Ingreso** y **Origen**.
3. La columna **Origen** dice de dónde vino cada lote:

| Origen | Significado |
|---|---|
| **Compra CMP-####** | Entró con una compra confirmada en [Compras](./compras.md). |
| **Inicial** | El primer lote, el de la cantidad capturada al dar de alta el producto. |
| **Manual** | Lo registraste con 📥 Agregar inventario (se muestra el motivo, si lo escribiste). |
| **Ajuste** | Lo creó un ajuste de inventario porque sobraba mercancía (se muestra el motivo). |

4. **📅 Caducidad por lote:** cada lote vigente tiene un botón **📅**. Abre "Caducidad del lote" con la fecha actual; cámbiala (o déjala vacía para "sin caducidad") y **Guardar**. Esto solo cambia ese lote y el sistema recalcula la caducidad más próxima del producto. Un lote dado de baja ya no se puede editar.
5. **Dar de baja:** cada lote vigente tiene un botón **Dar de baja**. Úsalo cuando la mercancía de ese lote se perdió o salió de la tienda (merma, caducó, se devolvió al proveedor, se capturó por error).
6. Escribe el **motivo** (obligatorio) y confirma en el diálogo rojo **"Sí, dar de baja"**.

Los lotes **no se eliminan**: el lote dado de baja queda en 0 unidades, se ve tachado en la tabla con su fecha y motivo, y el sistema **recalcula automáticamente** el stock, costo y caducidad del producto con los lotes que siguen vigentes. Una baja no se puede deshacer; si fue un error, registra la mercancía otra vez con **📥 Agregar Nuevo Inventario**.

## 10. Desactivar o reactivar un producto

Los productos **no se eliminan** (así no se pierde su historial de ventas, devoluciones ni su código de barras). En su lugar:

1. En el menú **⋮** del producto elige **🚫 Desactivar** y confirma en el diálogo **"Sí, desactivar"**.
2. Un producto inactivo **deja de venderse**: no aparece en el buscador del Punto de Venta, y si se escanea su código el POS avisa **"Producto desactivado"**. Tampoco aparece en las alertas de stock bajo/caducidad del Inicio ni en Etiquetas, y si estaba en un ticket en espera se omite al retomarlo.
3. Sus existencias, lotes y código de barras se conservan (el código sigue reservado para ese producto).
4. Para volver a venderlo, cambia el filtro a **Inactivos**, abre su menú **⋮** y elige **✅ Reactivar** (no pide confirmación).

## 11. Preguntas frecuentes

**¿Por qué el costo de un producto viejo es el 72% del precio si nunca lo capturé así?**
Es un valor estimado que el sistema calcula automáticamente para productos que no tienen un costo explícito guardado (datos antiguos o migrados). En cuanto le registres una compra o le agregues inventario con un costo real, ese estimado deja de usarse (si el producto no tiene existencias, también puedes capturar un costo de referencia al editarlo).

**¿Por qué no puedo editar la cantidad ni la caducidad de un producto?**
Porque son el resumen de sus lotes. Para meter mercancía usa [Compras](./compras.md) (con documento de proveedor) o "Agregar Nuevo Inventario"; para corregir un conteo usa "Ajuste de inventario"; para la fecha de un lote usa 📅 en Ver lotes. Así cada movimiento queda con su origen y su motivo.

**Conté la mercancía y no coincide con el sistema, ¿qué hago?**
Haz un **🧮 Ajuste de inventario** con la cantidad contada y el motivo. Si sobraba, se crea un lote de ajuste; si faltaba, se descuenta de los lotes que caducan primero.

**¿Por qué no puedo cambiar el costo de un producto?**
Con existencias, el costo es el promedio de los lotes que hay en el anaquel, así que se mueve con cada compra o entrada. Solo cuando el producto está en 0 puedes escribir un costo de referencia para la próxima vez. Si el costo de un lote está mal, dalo de baja y regístralo de nuevo con el costo correcto.

**Un producto muestra "Bajo Stock" pero acabo de recibir mercancía, ¿por qué no se actualizó?**
Verifica que hayas guardado la entrada en "Agregar Nuevo Inventario" o confirmado la compra en [Compras](./compras.md) (no solo la hayas abierto o dejado en borrador) y que el filtro de la tabla no esté limitando la vista — el filtro de estado se queda activo hasta que lo cambies manualmente.

**¿Puedo ver el historial de cuándo entró cada lote?**
Sí, en el modal de lotes (📋) se muestra la fecha de ingreso de cada uno, su origen (compra, inicial, manual o ajuste) y, en los lotes dados de baja, también la fecha y el motivo de la baja.

**¿Por qué ya no puedo eliminar un producto?**
Para proteger la información del negocio: un producto borrado se llevaría su rastro en ventas, reportes y etiquetas pegadas. Desactívalo; deja de estorbar en el POS y lo puedes recuperar cuando quieras.
