{"id":328,"date":"2026-11-02T21:20:25","date_gmt":"2026-11-02T20:20:25","guid":{"rendered":"https:\/\/n8nfacil.com\/?p=328"},"modified":"2026-11-02T21:20:26","modified_gmt":"2026-11-02T20:20:26","slug":"n8n-control-stock-reposicion","status":"publish","type":"post","link":"https:\/\/n8nfacil.com\/en\/n8n-control-stock-reposicion\/","title":{"rendered":"Control de stock con n8n: prepara una propuesta de reposici\u00f3n y detecta datos err\u00f3neos"},"content":{"rendered":"<p><strong>Pr\u00e1ctica local con datos ficticios.<\/strong> Pruebas de n8n 2.44.5 realizadas el 2 de noviembre de 2026. No requiere credenciales externas.<\/p><p>Un aviso de \u201cstock bajo\u201d sirve de poco si el dato viene como texto, es negativo o tiene un objetivo menor que el m\u00ednimo. En esta pr\u00e1ctica construiremos un informe que distingue tres situaciones: productos para reponer, productos sin cambio y registros que necesitan revisi\u00f3n. El resultado es una propuesta que una persona puede comprobar, no una compra autom\u00e1tica.<\/p><h2>Define la regla antes de automatizar<\/h2><p>La pol\u00edtica ser\u00e1: proponer reposici\u00f3n cuando <strong>stock &lt; minimo<\/strong> y calcular unidades como <strong>objetivo \u2212 stock<\/strong>. Si el stock es exactamente igual al m\u00ednimo, no se propone reposici\u00f3n. Exigimos n\u00fameros enteros no negativos y objetivo mayor o igual que m\u00ednimo. Son reglas de este ejercicio: un almac\u00e9n que vende por peso o acepta reservas pendientes necesitar\u00e1 otro modelo.<\/p><figure class=\"wp-block-table\"><table><thead><tr><th>Campo<\/th><th>Significado<\/th><th>Ejemplo<\/th><\/tr><\/thead><tbody><tr><td>sku<\/td><td>Identificador del producto<\/td><td>A-01<\/td><\/tr><tr><td>stock<\/td><td>Unidades disponibles del ejemplo<\/td><td>2<\/td><\/tr><tr><td>minimo<\/td><td>Umbral que activa la propuesta<\/td><td>5<\/td><\/tr><tr><td>objetivo<\/td><td>Existencias a las que se quiere llegar<\/td><td>10<\/td><\/tr><\/tbody><\/table><\/figure><p>Con A-01 se proponen ocho unidades para alcanzar diez, no tres para alcanzar el m\u00ednimo. Mantener esa diferencia visible evita confundir el umbral de aviso con el nivel de reposici\u00f3n. No incluimos unidades ya pedidas, plazos del proveedor, demanda prevista ni tama\u00f1o m\u00ednimo del pedido.<\/p><h2>1. Construye el recorrido local<\/h2><p>Nivel intermedio. Necesitas n8n funcionando y conocimientos b\u00e1sicos de elementos, JSON y expresiones. La pr\u00e1ctica 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.<\/p><p>Crea un workflow vac\u00edo. A\u00f1ade Manual Trigger y tres nodos Code conectados en este orden: <strong>Ejecutar prueba \u2192 Datos de ejemplo \u2192 Evaluar registros \u2192 Informe del lote<\/strong>. En los tres nodos Code selecciona JavaScript y <strong>Run Once for All Items<\/strong>. Este modo permite comparar un lote y construir un informe \u00fanico. Los nombres son etiquetas del proyecto: ren\u00f3mbralos para seguir las explicaciones.<\/p><p>Hemos elegido Code para mantener visibles las reglas de validaci\u00f3n y conservar tambi\u00e9n los registros problem\u00e1ticos. No es la \u00fanica implementaci\u00f3n posible: una combinaci\u00f3n de Edit Fields, IF, Remove Duplicates y Aggregate puede repartir el trabajo entre m\u00e1s nodos. Aqu\u00ed el objetivo es comprender una pol\u00edtica completa antes de conectar servicios.<\/p><figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/n8nfacil.com\/wp-content\/uploads\/2026\/11\/13-stock-flujo.jpg\" alt=\"Workflow de inventario ejecutado con seis productos ficticios.\" width=\"1101\" height=\"874\" loading=\"lazy\"\/><figcaption>Workflow de inventario ejecutado con seis productos ficticios.<\/figcaption><\/figure><h2>2. Carga seis productos ficticios<\/h2><p>En Datos de ejemplo pega el siguiente c\u00f3digo. Conserva el valor de D-04 como texto para comprobar que el flujo no lo convierte silenciosamente en un n\u00famero.<\/p><pre><code>return [\n  {\n    \"sku\": \" A-01 \",\n    \"stock\": 2,\n    \"minimo\": 5,\n    \"objetivo\": 10\n  },\n  {\n    \"sku\": \"B-02\",\n    \"stock\": 5,\n    \"minimo\": 5,\n    \"objetivo\": 12\n  },\n  {\n    \"sku\": \"C-03\",\n    \"stock\": 0,\n    \"minimo\": 2,\n    \"objetivo\": 6\n  },\n  {\n    \"sku\": \"D-04\",\n    \"stock\": \"3\",\n    \"minimo\": 5,\n    \"objetivo\": 10\n  },\n  {\n    \"sku\": \"E-05\",\n    \"stock\": -1,\n    \"minimo\": 2,\n    \"objetivo\": 8\n  },\n  {\n    \"sku\": \"F-06\",\n    \"stock\": 4,\n    \"minimo\": 6,\n    \"objetivo\": 3\n  }\n].map(json =&gt; ({json}));<\/code><\/pre><p>La lista contiene un producto bajo m\u00ednimo, otro justo en el l\u00edmite, uno sin existencias y tres registros problem\u00e1ticos. No es un inventario de ninguna empresa ni una extracci\u00f3n de una tienda real.<\/p><h2>3. Eval\u00faa cada registro<\/h2><p>Pega este c\u00f3digo en Evaluar registros. Number.isInteger exige un n\u00famero entero real: la cadena \u00ab3\u00bb no cumple. Elegimos separar ese error para revisar el origen del dato, en vez de interpretar autom\u00e1ticamente cualquier texto recibido.<\/p><pre><code>return $input.all().map(item =&gt; {\n  const f = item.json;\n  const sku = typeof f.sku === 'string' ? f.sku.trim() : '';\n  const motivos = [];\n  if (!sku) motivos.push('sku_ausente');\n  for (const campo of ['stock', 'minimo', 'objetivo']) {\n    if (!Number.isInteger(f[campo]) || f[campo] &lt; 0) motivos.push(campo + '_invalido');\n  }\n  if (Number.isInteger(f.objetivo) &amp;&amp; Number.isInteger(f.minimo) &amp;&amp; f.objetivo &lt; f.minimo) motivos.push('objetivo_menor_minimo');\n  const estado = motivos.length ? 'revisar' : f.stock &lt; f.minimo ? 'reponer' : 'sin_cambio';\n  const unidades = estado === 'reponer' ? Math.max(0, f.objetivo - f.stock) : 0;\n  return {json: {sku, stock: f.stock, minimo: f.minimo, objetivo: f.objetivo, estado, unidades, motivos}};\n});<\/code><\/pre><p>El campo motivos puede contener m\u00e1s de una causa. Si el objetivo es menor que el m\u00ednimo, el registro se env\u00eda a revisar aunque se pueda realizar una resta. Si hay errores, unidades es cero: no representa una recomendaci\u00f3n de no comprar, sino que no existe una propuesta fiable para esa fila.<\/p><p>El SKU se recorta, pero no se convierte a may\u00fasculas ni se comprueba su unicidad. Dos filas con el mismo SKU seguir\u00edan presentes y podr\u00edan duplicar una propuesta. Antes de usar datos reales necesitas una regla de unicidad y saber si las filas representan productos, almacenes o ubicaciones distintas.<\/p><h2>4. Resume la propuesta y las excepciones<\/h2><p>En Informe del lote pega el siguiente c\u00f3digo. Mantiene propuestas, revisar y sin_cambio como listas separadas y suma \u00fanicamente las unidades de las propuestas v\u00e1lidas.<\/p><pre><code>const filas = $input.all().map(item =&gt; item.json);\nconst propuestas = filas.filter(f =&gt; f.estado === 'reponer');\nconst revisar = filas.filter(f =&gt; f.estado === 'revisar');\nconst sin_cambio = filas.filter(f =&gt; f.estado === 'sin_cambio');\nreturn [{json: {productos: filas.length, total_reponer: propuestas.length,\n  unidades_propuestas: propuestas.reduce((s, f) =&gt; s + f.unidades, 0),\n  total_revisar: revisar.length, total_sin_cambio: sin_cambio.length,\n  propuestas, revisar, sin_cambio}}];<\/code><\/pre><h2>5. Contrasta el informe con una cuenta manual<\/h2><figure class=\"wp-block-table\"><table><thead><tr><th>Producto<\/th><th>Decisi\u00f3n<\/th><th>Unidades propuestas<\/th><\/tr><\/thead><tbody><tr><td>A-01<\/td><td>Reponer: 2 est\u00e1 por debajo de 5<\/td><td>8<\/td><\/tr><tr><td>B-02<\/td><td>Sin cambio: 5 es igual al m\u00ednimo<\/td><td>0<\/td><\/tr><tr><td>C-03<\/td><td>Reponer: 0 est\u00e1 por debajo de 2<\/td><td>6<\/td><\/tr><tr><td>D-04<\/td><td>Revisar: stock es texto<\/td><td>0<\/td><\/tr><tr><td>E-05<\/td><td>Revisar: stock negativo<\/td><td>0<\/td><\/tr><tr><td>F-06<\/td><td>Revisar: objetivo menor que m\u00ednimo<\/td><td>0<\/td><\/tr><\/tbody><\/table><\/figure><p>La salida debe resumir seis productos, dos propuestas, catorce unidades propuestas, tres registros para revisar y uno sin cambio. Verifica tambi\u00e9n los SKU de cada lista. No multipliques catorce por un precio gen\u00e9rico para anunciar ahorro o coste: aqu\u00ed no hay precios ni condiciones de compra.<\/p><h2>Pruebas del l\u00edmite y de entradas no v\u00e1lidas<\/h2><p>Probamos otra entrada con stock igual al m\u00ednimo, 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\u00ednimo confirm\u00f3 el uso de \u201cmenor que\u201d, mientras que el decimal qued\u00f3 apartado por la regla de unidades enteras.<\/p><h2>Errores habituales y c\u00f3mo investigarlos<\/h2><p>Si un dato visualmente num\u00e9rico termina en revisar, abre la entrada JSON: 3 y \u00ab3\u00bb tienen tipos distintos. Si propones unidades con stock igual al m\u00ednimo, revisa que no hayas cambiado &lt; por &lt;=. 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.<\/p><p>Un nodo ejecutado correctamente no acredita que el inventario sea reciente. Nuestro flujo no consulta fechas ni verifica reservas. La pr\u00e1ctica tampoco comprueba un origen vac\u00edo ni su comportamiento con un cat\u00e1logo grande. Documenta esas situaciones y pru\u00e9balas antes de a\u00f1adir una programaci\u00f3n peri\u00f3dica.<\/p><h2>Antes de convertirlo en una automatizaci\u00f3n de negocio<\/h2><p>Conecta primero una copia de lectura del inventario, define la antig\u00fcedad m\u00e1xima del dato y prueba las reglas con la persona responsable. A\u00f1ade una aprobaci\u00f3n 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\u00f3n. Este workflow no realiza esas tareas.<\/p><p>Para reforzar la base, consulta <a href=\"https:\/\/n8nfacil.com\/nodo-if-n8n-clasificar-pedidos\/\">condiciones con IF<\/a>, <a href=\"https:\/\/n8nfacil.com\/switch-n8n-clasificar-solicitudes\/\">rutas con Switch<\/a> y <a href=\"https:\/\/n8nfacil.com\/aggregate-n8n-agrupar-pedidos\/\">res\u00famenes con Aggregate<\/a>. Puedes reconstruir etapas equivalentes con esos nodos, conservando la misma tabla de resultados para comparar las implementaciones.<\/p><p>Consulta la <a href=\"https:\/\/docs.n8n.io\/integrations\/builtin\/core-nodes\/n8n-nodes-base.code\/\">documentaci\u00f3n oficial del nodo Code<\/a> para sus modos de ejecuci\u00f3n y la <a href=\"https:\/\/docs.n8n.io\/data\/data-structure\/\">estructura de datos de n8n<\/a> para entender los objetos con una propiedad json. Los c\u00f3digos de esta gu\u00eda son propios del proyecto.<\/p><figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/n8nfacil.com\/wp-content\/uploads\/2026\/11\/13-stock-resultado.jpg\" alt=\"El informe devuelve dos productos para reponer y catorce unidades propuestas.\" width=\"1101\" height=\"874\" loading=\"lazy\"\/><figcaption>El informe devuelve dos productos para reponer y catorce unidades propuestas.<\/figcaption><\/figure><h2>Descarga el proyecto para repetir la pr\u00e1ctica<\/h2><p><a href=\"https:\/\/n8nfacil.com\/wp-content\/uploads\/2026\/11\/13-reposicion-stock.zip\">Descargar workflow y archivos de pr\u00e1ctica en ZIP<\/a>. Incluye el JSON de n8n, los c\u00f3digos de los nodos, instrucciones y resultados de las pruebas. No incluye la base de datos de la instalaci\u00f3n ni credenciales.<\/p><p><strong>Autor: Javier Fern\u00e1ndez.<\/strong> Soy estudiante y comparto lo que aprendo con proyectos de pr\u00e1ctica. Las pruebas descritas utilizan datos ficticios. <a href=\"https:\/\/n8nfacil.com\/sobre\/\">Conoce el proyecto<\/a> o <a href=\"https:\/\/n8nfacil.com\/contacto\/\">comunica un error<\/a> indicando el paso y la versi\u00f3n de n8n.<\/p>","protected":false},"excerpt":{"rendered":"<p>Un proyecto de inventario con seis productos ficticios: propone unidades para reponer, conserva los casos sin cambio y separa los datos que no son fiables.<\/p>","protected":false},"author":1,"featured_media":332,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-328","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-condiciones-rutas"],"_links":{"self":[{"href":"https:\/\/n8nfacil.com\/en\/wp-json\/wp\/v2\/posts\/328","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/n8nfacil.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/n8nfacil.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/n8nfacil.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/n8nfacil.com\/en\/wp-json\/wp\/v2\/comments?post=328"}],"version-history":[{"count":2,"href":"https:\/\/n8nfacil.com\/en\/wp-json\/wp\/v2\/posts\/328\/revisions"}],"predecessor-version":[{"id":335,"href":"https:\/\/n8nfacil.com\/en\/wp-json\/wp\/v2\/posts\/328\/revisions\/335"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/n8nfacil.com\/en\/wp-json\/wp\/v2\/media\/332"}],"wp:attachment":[{"href":"https:\/\/n8nfacil.com\/en\/wp-json\/wp\/v2\/media?parent=328"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/n8nfacil.com\/en\/wp-json\/wp\/v2\/categories?post=328"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/n8nfacil.com\/en\/wp-json\/wp\/v2\/tags?post=328"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}