{
  "id": "5DYragY8HoMNyMHF",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "WooCommerce Inventory Reorder Automation with n8n, Gmail & Slack Alerts",
  "tags": [],
  "nodes": [
    {
      "id": "a40203de-1271-4844-9d40-24ba95a8ce6f",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1632,
        -480
      ],
      "parameters": {
        "color": 7,
        "width": 720,
        "height": 624,
        "content": "## Inventory & Sales Intake\n\n\n### \u2022Trigger :- The workflow starts automatically based on a scheduled trigger.\n### \u2022 WooCommerce Node :- Order data is fetched from WooCommerce using the Orders API.\n### \u2022 Code :- Sales quantities are calculated per SKU from order line items.\n### This step converts raw order data into meaningful sales metrics.\n\n### - If order data is unavailable or invalid, the workflow stops further processing.\n### - This prevents incorrect sales calculations and downstream errors.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "1cd9d374-16bc-41e8-8194-320518dbf48e",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -848,
        -480
      ],
      "parameters": {
        "color": 7,
        "width": 624,
        "height": 624,
        "content": "## Product Mapping & Eligibility Validation\n\n### Product inventory details are fetched and aligned with sales data.\n### Current stock levels and low-stock thresholds are retrieved for each product.\n### Sales data and product inventory are merged into a single dataset.\n### Reorder eligibility is validated using OR-based logic:\n### \u2022 stock quantity is below the low-stock level\n### \u2022 OR sales velocity exceeds the defined threshold\n\n### Products that fail validation are excluded from further processing.\n### This prevents unnecessary purchase orders and alert noise."
      },
      "typeVersion": 1
    },
    {
      "id": "6df12f5e-3acf-46c5-b98f-eed2c11b0f3c",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -128,
        -480
      ],
      "parameters": {
        "color": 7,
        "width": 576,
        "height": 624,
        "content": "## Reorder Calculation & Notifications\n\n### Code :-\n### The workflow calculates the required reorder quantity for eligible products.\n### Average daily sales, lead time and safety stock are applied to compute reorder quantity.\n### Once calculated, notifications are sent to the purchasing team.\n### Notifications include:\n\u2022 Email with reorder details\n\u2022 Slack alert for real-time visibility"
      },
      "typeVersion": 1
    },
    {
      "id": "5018ae67-c1a8-4521-8b99-6e2a21b95858",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2336,
        -592
      ],
      "parameters": {
        "width": 672,
        "height": 1024,
        "content": "## How it Works:\n\u2022 This workflow automatically monitors product inventory and recent sales activity on a scheduled basis.\n\n\u2022 On each execution, the workflow fetches recent WooCommerce orders and calculates SKU-wise sales quantities to understand current demand trends.\n\n\u2022 It then retrieves live product inventory data, including current stock levels and low-stock thresholds and validates whether products meet reorder conditions based on stock depletion or sales velocity.\n\n\u2022 When a product qualifies for replenishment, the workflow calculates an optimal reorder quantity using average daily sales, lead time and safety stock logic.\n\n\u2022 Once the reorder quantity is determined, the workflow sends automated notifications to the purchasing team via email and Slack. Products that do not meet reorder criteria are safely ignored.\n\n\u2022 Overall, this workflow enables proactive inventory replenishment, prevents stockouts, reduces manual monitoring and improves purchasing efficiency without human intervention.\n\n### Setup Steps:\n\n1. Create a Schedule Trigger in n8n to run the workflow at a defined interval (daily, hourly or custom).\n\n2. Configure the WooCommerce Orders API node to fetch recent orders required for sales analysis.\n\n3. Add a JavaScript Code node to normalize order data and calculate total quantities sold per SKU.\n\n4. Configure the WooCommerce Products API node to retrieve current stock levels and low-stock thresholds for all products.\n\n5. Use a Merge node to combine sales data with product inventory data into a unified dataset.\n\n6. Add a Filter node to validate reorder eligibility based on:\n\n\u2022 stock quantity less than or equal to low-stock threshold\n\n\u2022OR recent sales exceeding the defined sales velocity threshold\n\n7. Add a JavaScript Code node to calculate reorder quantity using average daily sales, lead time and safety stock.\n\n8. Configure an Email node to send reorder details to the purchasing team for action.\n\n9. Configure a Slack node to send real-time alerts with product and reorder information for internal visibility"
      },
      "typeVersion": 1
    },
    {
      "id": "8cee01d6-fb79-4c60-a64e-daa179bfff12",
      "name": "Merge Sales & Inventory Data",
      "type": "n8n-nodes-base.merge",
      "position": [
        -592,
        -80
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "343bbd75-fa34-49db-b63a-77e2a9f5aec2",
      "name": "Inventory Check",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1584,
        -80
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 21
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "e213338f-4aa3-4b73-bd97-9ae1e58e958e",
      "name": "Fetch Orders",
      "type": "n8n-nodes-base.wooCommerce",
      "position": [
        -1344,
        -80
      ],
      "parameters": {
        "options": {},
        "resource": "order",
        "operation": "getAll",
        "returnAll": true
      },
      "credentials": {
        "wooCommerceApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "6a6da4b9-e73d-499e-99bd-b5a48d187acd",
      "name": "SKU Sales Volume",
      "type": "n8n-nodes-base.code",
      "position": [
        -1104,
        -80
      ],
      "parameters": {
        "jsCode": "const sales = {};\n\nfor (const order of items) {\n  for (const item of order.json.line_items || []) {\n    if (!item.sku) continue;\n    sales[item.sku] = (sales[item.sku] || 0) + item.quantity;\n  }\n}\n\nreturn Object.entries(sales).map(([sku, soldQty]) => ({\n  json: { sku, soldQty }\n}));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "02720b8b-1aa6-4bf5-b3d7-3ebc04bcd17a",
      "name": "Fetch Products",
      "type": "n8n-nodes-base.wooCommerce",
      "position": [
        -800,
        -80
      ],
      "parameters": {
        "options": {},
        "operation": "getAll"
      },
      "credentials": {
        "wooCommerceApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "0e358072-e091-4aa7-a961-54849ab7205e",
      "name": "Reorder Check",
      "type": "n8n-nodes-base.filter",
      "position": [
        -384,
        -80
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "e8c8c12a-f69e-4544-ae61-c9f4d89447d7",
              "operator": {
                "type": "number",
                "operation": "lte"
              },
              "leftValue": "={{ $json.stock_quantity }}",
              "rightValue": "={{ $json.low_stock_amount }}"
            },
            {
              "id": "c4bef731-2e7f-42b0-9868-d91473187af2",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $('SKU Sales Volume').item.json.soldQty }}",
              "rightValue": "={{ $json.low_stock_amount * 1.5}}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "858fef79-d415-4ce5-ace1-8fae9ee66804",
      "name": "Reorder Calc",
      "type": "n8n-nodes-base.code",
      "position": [
        -64,
        -80
      ],
      "parameters": {
        "jsCode": "const leadDays = 7;\nconst safetyStock = 5;\n\nconst dailyAvg = Math.ceil( $('SKU Sales Volume').first().json.soldQty/ 7);\nconst reorderQty = (dailyAvg * leadDays) + safetyStock;\n\nreturn [{\n  json: {\n    sku: $('SKU Sales Volume').first().json.sku,\n    productName:$('Fetch Products').first().json.name,\n    reorderQty,\n    currentStock: $('Fetch Products').first().json.stock_quantity\n  }\n}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "96a631d1-e691-4e0f-99f2-b0f6635dbe5f",
      "name": "Send Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        128,
        -80
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "=<h3>Purchase Order Created Automatically</h3>  <p>A product has reached its reorder condition.</p>  <table border=\"1\" cellpadding=\"6\" cellspacing=\"0\">   <tr><td><b>SKU</b></td><td>{{ $json.sku }}</td></tr>   <tr><td><b>Product</b></td><td>{{ $json.productName }}</td></tr>   <tr><td><b>Current Stock</b></td><td>{{ $json.currentStock }}</td></tr>   <tr><td><b>Reorder Quantity</b></td><td>{{ $json.reorderQty }}</td></tr>   <tr><td><b>Created At</b></td><td>{{ $now }}</td></tr> </table>  <p>Please review and proceed with supplier ordering.</p>",
        "options": {},
        "subject": "Auto PO Created"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "7caf25c1-6bd3-4033-ad45-a06d3f52bfe6",
      "name": "Slack Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        320,
        -80
      ],
      "parameters": {
        "text": "=\ud83d\udce6 *Auto Purchase Order Triggered*  \u2022 *Product:* {{ $json.productName }} \u2022 *SKU:* {{ $json.sku }} \u2022 *Current Stock:* {{ $json.currentStock }} \u2022 *Reorder Qty:* {{ $json.reorderQty }}  \u23f1 Triggered automatically via n8n",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0A3WQEKQ58",
          "cachedResultName": "n8n-demo"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "55dfa8a0-d434-4baa-b16a-1607b794da3b",
  "connections": {
    "Send Email": {
      "main": [
        [
          {
            "node": "Slack Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Orders": {
      "main": [
        [
          {
            "node": "SKU Sales Volume",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Reorder Calc": {
      "main": [
        [
          {
            "node": "Send Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Reorder Check": {
      "main": [
        [
          {
            "node": "Reorder Calc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Products": {
      "main": [
        [
          {
            "node": "Merge Sales & Inventory Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Inventory Check": {
      "main": [
        [
          {
            "node": "Fetch Orders",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SKU Sales Volume": {
      "main": [
        [
          {
            "node": "Fetch Products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Sales & Inventory Data": {
      "main": [
        [
          {
            "node": "Reorder Check",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}