Práctica local con datos ficticios. Pruebas de n8n 2.44.5 realizadas el 2 de noviembre de 2026. No requiere credenciales externas.

Un aviso de “stock bajo” sirve de poco si el dato viene como texto, es negativo o tiene un objetivo menor que el mínimo. En esta práctica construiremos un informe que distingue tres situaciones: productos para reponer, productos sin cambio y registros que necesitan revisión. El resultado es una propuesta que una persona puede comprobar, no una compra automática.

Define la regla antes de automatizar

La política será: proponer reposición cuando stock < minimo y calcular unidades como objetivo − stock. Si el stock es exactamente igual al mínimo, no se propone reposición. Exigimos números enteros no negativos y objetivo mayor o igual que mínimo. Son reglas de este ejercicio: un almacén que vende por peso o acepta reservas pendientes necesitará otro modelo.

CampoSignificadoEjemplo
skuIdentificador del productoA-01
stockUnidades disponibles del ejemplo2
minimoUmbral que activa la propuesta5
objetivoExistencias a las que se quiere llegar10

Con A-01 se proponen ocho unidades para alcanzar diez, no tres para alcanzar el mínimo. Mantener esa diferencia visible evita confundir el umbral de aviso con el nivel de reposición. No incluimos unidades ya pedidas, plazos del proveedor, demanda prevista ni tamaño mínimo del pedido.

1. Construye el recorrido local

Nivel intermedio. Necesitas n8n funcionando y conocimientos básicos de elementos, JSON y expresiones. La práctica se ejecuta manualmente, con datos ficticios y sin conectar cuentas externas. No escribe en un CRM, no manda correos y no modifica un inventario real.

Crea un workflow vacío. Añade Manual Trigger y tres nodos Code conectados en este orden: Ejecutar prueba → Datos de ejemplo → Evaluar registros → Informe del lote. En los tres nodos Code selecciona JavaScript y Run Once for All Items. Este modo permite comparar un lote y construir un informe único. Los nombres son etiquetas del proyecto: renómbralos para seguir las explicaciones.

Hemos elegido Code para mantener visibles las reglas de validación y conservar también los registros problemáticos. No es la única implementación posible: una combinación de Edit Fields, IF, Remove Duplicates y Aggregate puede repartir el trabajo entre más nodos. Aquí el objetivo es comprender una política completa antes de conectar servicios.

Workflow de inventario ejecutado con seis productos ficticios.
Workflow de inventario ejecutado con seis productos ficticios.

2. Carga seis productos ficticios

En Datos de ejemplo pega el siguiente código. Conserva el valor de D-04 como texto para comprobar que el flujo no lo convierte silenciosamente en un número.

return [
  {
    "sku": " A-01 ",
    "stock": 2,
    "minimo": 5,
    "objetivo": 10
  },
  {
    "sku": "B-02",
    "stock": 5,
    "minimo": 5,
    "objetivo": 12
  },
  {
    "sku": "C-03",
    "stock": 0,
    "minimo": 2,
    "objetivo": 6
  },
  {
    "sku": "D-04",
    "stock": "3",
    "minimo": 5,
    "objetivo": 10
  },
  {
    "sku": "E-05",
    "stock": -1,
    "minimo": 2,
    "objetivo": 8
  },
  {
    "sku": "F-06",
    "stock": 4,
    "minimo": 6,
    "objetivo": 3
  }
].map(json => ({json}));

La lista contiene un producto bajo mínimo, otro justo en el límite, uno sin existencias y tres registros problemáticos. No es un inventario de ninguna empresa ni una extracción de una tienda real.

3. Evalúa cada registro

Pega este código en Evaluar registros. Number.isInteger exige un número entero real: la cadena «3» no cumple. Elegimos separar ese error para revisar el origen del dato, en vez de interpretar automáticamente cualquier texto recibido.

return $input.all().map(item => {
  const f = item.json;
  const sku = typeof f.sku === 'string' ? f.sku.trim() : '';
  const motivos = [];
  if (!sku) motivos.push('sku_ausente');
  for (const campo of ['stock', 'minimo', 'objetivo']) {
    if (!Number.isInteger(f[campo]) || f[campo] < 0) motivos.push(campo + '_invalido');
  }
  if (Number.isInteger(f.objetivo) && Number.isInteger(f.minimo) && f.objetivo < f.minimo) motivos.push('objetivo_menor_minimo');
  const estado = motivos.length ? 'revisar' : f.stock < f.minimo ? 'reponer' : 'sin_cambio';
  const unidades = estado === 'reponer' ? Math.max(0, f.objetivo - f.stock) : 0;
  return {json: {sku, stock: f.stock, minimo: f.minimo, objetivo: f.objetivo, estado, unidades, motivos}};
});

El campo motivos puede contener más de una causa. Si el objetivo es menor que el mínimo, el registro se envía a revisar aunque se pueda realizar una resta. Si hay errores, unidades es cero: no representa una recomendación de no comprar, sino que no existe una propuesta fiable para esa fila.

El SKU se recorta, pero no se convierte a mayúsculas ni se comprueba su unicidad. Dos filas con el mismo SKU seguirían presentes y podrían duplicar una propuesta. Antes de usar datos reales necesitas una regla de unicidad y saber si las filas representan productos, almacenes o ubicaciones distintas.

4. Resume la propuesta y las excepciones

En Informe del lote pega el siguiente código. Mantiene propuestas, revisar y sin_cambio como listas separadas y suma únicamente las unidades de las propuestas válidas.

const filas = $input.all().map(item => item.json);
const propuestas = filas.filter(f => f.estado === 'reponer');
const revisar = filas.filter(f => f.estado === 'revisar');
const sin_cambio = filas.filter(f => f.estado === 'sin_cambio');
return [{json: {productos: filas.length, total_reponer: propuestas.length,
  unidades_propuestas: propuestas.reduce((s, f) => s + f.unidades, 0),
  total_revisar: revisar.length, total_sin_cambio: sin_cambio.length,
  propuestas, revisar, sin_cambio}}];

5. Contrasta el informe con una cuenta manual

ProductoDecisiónUnidades propuestas
A-01Reponer: 2 está por debajo de 58
B-02Sin cambio: 5 es igual al mínimo0
C-03Reponer: 0 está por debajo de 26
D-04Revisar: stock es texto0
E-05Revisar: stock negativo0
F-06Revisar: objetivo menor que mínimo0

La salida debe resumir seis productos, dos propuestas, catorce unidades propuestas, tres registros para revisar y uno sin cambio. Verifica también los SKU de cada lista. No multipliques catorce por un precio genérico para anunciar ahorro o coste: aquí no hay precios ni condiciones de compra.

Pruebas del límite y de entradas no válidas

Probamos otra entrada con stock igual al mínimo, stock una unidad por debajo, una cantidad decimal y un producto con todos los valores a cero. Se obtuvo una sola propuesta de seis unidades, un registro para revisar y dos sin cambio. El caso igual al mínimo confirmó el uso de “menor que”, mientras que el decimal quedó apartado por la regla de unidades enteras.

Errores habituales y cómo investigarlos

Si un dato visualmente numérico termina en revisar, abre la entrada JSON: 3 y «3» tienen tipos distintos. Si propones unidades con stock igual al mínimo, revisa que no hayas cambiado < por <=. Si el total parece exagerado, compara la lista de propuestas, busca SKU repetidos y revisa si objetivo significa existencias finales o cantidad que se desea pedir.

Un nodo ejecutado correctamente no acredita que el inventario sea reciente. Nuestro flujo no consulta fechas ni verifica reservas. La práctica tampoco comprueba un origen vacío ni su comportamiento con un catálogo grande. Documenta esas situaciones y pruébalas antes de añadir una programación periódica.

Antes de convertirlo en una automatización de negocio

Conecta primero una copia de lectura del inventario, define la antigüedad máxima del dato y prueba las reglas con la persona responsable. Añade una aprobación humana antes de generar cualquier pedido. Si ejecutas el informe cada hora, necesitas evitar avisar repetidamente sobre la misma incidencia y manejar cambios entre la lectura y la decisión. Este workflow no realiza esas tareas.

Para reforzar la base, consulta condiciones con IF, rutas con Switch y resúmenes con Aggregate. Puedes reconstruir etapas equivalentes con esos nodos, conservando la misma tabla de resultados para comparar las implementaciones.

Consulta la documentación oficial del nodo Code para sus modos de ejecución y la estructura de datos de n8n para entender los objetos con una propiedad json. Los códigos de esta guía son propios del proyecto.

El informe devuelve dos productos para reponer y catorce unidades propuestas.
El informe devuelve dos productos para reponer y catorce unidades propuestas.

Descarga el proyecto para repetir la práctica

Descargar workflow y archivos de práctica en ZIP. Incluye el JSON de n8n, los códigos de los nodos, instrucciones y resultados de las pruebas. No incluye la base de datos de la instalación ni credenciales.

Autor: Javier Fernández. Soy estudiante y comparto lo que aprendo con proyectos de práctica. Las pruebas descritas utilizan datos ficticios. Conoce el proyecto o comunica un error indicando el paso y la versión de n8n.


Leave a Reply

Your email address will not be published. Required fields are marked *