{
  "id": "6uBlcsNurf1OeI3R",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Automated Inventory Reorder & Vendor Notification Pipeline",
  "tags": [],
  "nodes": [
    {
      "id": "d009c30d-067d-48b0-8b92-a7e556c10f3c",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        12032,
        992
      ],
      "parameters": {
        "width": 480,
        "height": 896,
        "content": "## Automated Inventory Reorder & Vendor Notification Pipeline\n### How it works\n\n1. The workflow pulls stock and vendor data from Google Sheets on a schedule.\n2. It processes and merges this data, filtering for necessary reorders.\n3. Reorder information is aggregated, updated in a Google Sheet, and pushed to Slack.\n4. A secondary Slack-triggered flow handles customer queries by emailing internal users and updating a spreadsheet log.\n\n### Setup steps\n\n- - [ ] Configure Google Sheets credentials for all sheet nodes.\n- - [ ] Set up a Slack bot token and connect it to the Slack trigger/notification nodes.\n- - [ ] Link your Gmail account for the email notification node.\n- - [ ] Map the specific sheet IDs and ranges for all Google Sheets integrations.\n\n### Customization\n\nUsers can modify the reorder threshold logic in the merge nodes or adjust the Slack channel IDs for different notification routing."
      },
      "typeVersion": 1
    },
    {
      "id": "f1c4e530-a110-42b5-978c-2c83f4961889",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        12592,
        1008
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 464,
        "content": "## Initiate and fetch sheets\n\nTrigger and data retrieval from Google Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "be0bd4fd-1bc2-47e7-9037-ae5c5b27bf9d",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        13040,
        992
      ],
      "parameters": {
        "color": 7,
        "height": 496,
        "content": "## Format source data\n\nFormatting data from product and vendor sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "03861f00-b76c-4834-a666-0c190f261b08",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        13312,
        1104
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 272,
        "content": "## Merge and evaluate conditions\n\nMerging and initial processing logic."
      },
      "typeVersion": 1
    },
    {
      "id": "00c293b4-1819-4719-9988-760f708f006f",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        13984,
        1072
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 304,
        "content": "## Prepare data for aggregation\n\nStandardizing and aggregating data for reorders."
      },
      "typeVersion": 1
    },
    {
      "id": "f5337a58-8b3f-4d3b-aa24-1a8b9696bd56",
      "name": "Sticky Note14",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        14432,
        1072
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 304,
        "content": "## Fetch and process reorders\n\nFetching reorder sheet and processing updates."
      },
      "typeVersion": 1
    },
    {
      "id": "fd130145-edef-4038-a2b3-6540fee3e800",
      "name": "Sticky Note15",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        14864,
        1088
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 272,
        "content": "## Update records and notify Slack\n\nWriting reorder updates and notifying Slack."
      },
      "typeVersion": 1
    },
    {
      "id": "a6ac2d9d-6cea-4b56-bf51-598684bf20a6",
      "name": "Sticky Note16",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        12592,
        1648
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 272,
        "content": "## Slack message trigger flow\n\nSlack event trigger and filtering."
      },
      "typeVersion": 1
    },
    {
      "id": "a9416ccc-fda4-4fff-b560-e0e75daa8f87",
      "name": "Sticky Note17",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        13040,
        1648
      ],
      "parameters": {
        "color": 7,
        "width": 1088,
        "height": 288,
        "content": "## Email notification and status update\n\nFetching context and sending email notifications."
      },
      "typeVersion": 1
    },
    {
      "id": "740499fd-50d9-4e21-9eba-ed8cf6745061",
      "name": "When Scheduled",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        12640,
        1216
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "c329ac19-9792-43b3-bbbd-ad1c6188bfa0",
      "name": "Fetch Product Inventory",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        12864,
        1120
      ],
      "parameters": {
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultUrl": "",
          "cachedResultName": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": ""
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "581dac77-6b11-471c-93c0-14199adb52da",
      "name": "Fetch Vendor Catalog",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        12864,
        1312
      ],
      "parameters": {
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultUrl": "",
          "cachedResultName": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": ""
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "370c40db-20a6-4504-8915-a0250f046f5c",
      "name": "Prepare Product Stock Data",
      "type": "n8n-nodes-base.set",
      "position": [
        13088,
        1120
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "86fd3392-4557-4516-b8cb-a832612e185c",
              "name": "row_number",
              "type": "number",
              "value": "={{ $json.row_number }}"
            },
            {
              "id": "a2587fd9-4452-46fc-ba40-c50e16244914",
              "name": "Product ID",
              "type": "string",
              "value": "={{ $json['Product ID'] }}"
            },
            {
              "id": "663e9b28-57ad-41a3-bea3-62787635da6d",
              "name": "Vendor ID",
              "type": "string",
              "value": "={{ $json['Vendor ID'] }}"
            },
            {
              "id": "6abbbcc7-0f70-4411-9742-dbefa0d34411",
              "name": "Product Name",
              "type": "string",
              "value": "={{ $json['Product Name'] }}"
            },
            {
              "id": "dabadaff-d6d2-4899-9c16-cf33f410b83f",
              "name": "Current Stock",
              "type": "number",
              "value": "={{ $json['Current Stock'] }}"
            },
            {
              "id": "d11cb88b-12b1-4c09-adc9-f0d6ad0c5d28",
              "name": "Last 7 Days Sales",
              "type": "number",
              "value": "={{ $json['Last 7 Days Sales'] }}"
            },
            {
              "id": "065d6fc7-5275-4797-a80f-de07bb218f91",
              "name": "Current Run away",
              "type": "string",
              "value": "={{ Math.round($json['Current Stock'] / ($json['Last 7 Days Sales'] / 7)) }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "18642a3b-da72-4154-8342-b2a09e09b770",
      "name": "Prepare Vendor Delivery Data",
      "type": "n8n-nodes-base.set",
      "position": [
        13088,
        1312
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "373219f8-4e74-48aa-93a6-def3f227a974",
              "name": "Vendor ID",
              "type": "string",
              "value": "={{ $json[\"Vendor ID\"] }}"
            },
            {
              "id": "bf04d7cc-1012-433c-8600-a4c5a662058e",
              "name": "Vendor Name",
              "type": "string",
              "value": "={{ $json[\"Vendor Name\"] }}"
            },
            {
              "id": "179185f3-fc1e-4d9d-b926-6327e758dc99",
              "name": "Email Address",
              "type": "string",
              "value": "={{ $json[\"Email Address\"] }}"
            },
            {
              "id": "8df7b4e0-a31e-4796-9b82-b0e7a49f975d",
              "name": "Avg Delivery Time",
              "type": "string",
              "value": "={{ $json[\"Avg. Delivery Time\"] }}"
            },
            {
              "id": "7cdf33f9-0697-4f00-8c1d-f800e13571d2",
              "name": "Offered Product IDs",
              "type": "string",
              "value": "={{ $json[\"Offered Product IDs\"] }}"
            },
            {
              "id": "b7cb475c-8e7f-484b-a2f6-1da2631d39eb",
              "name": "Product Descriptions",
              "type": "string",
              "value": "={{ $json[\"Product Descriptions\"] }}"
            },
            {
              "id": "fd3d8b46-d131-4441-9194-b7f29c387f7a",
              "name": "Safe Hold time",
              "type": "string",
              "value": "={{ $json[\"Avg. Delivery Time\"] +2 }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "f5ef58e1-b121-4970-acb5-e3b0414c28a0",
      "name": "Merge Inventory and Vendors",
      "type": "n8n-nodes-base.merge",
      "position": [
        13360,
        1216
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "fieldsToMatchString": "[\"Vendor ID\"]"
      },
      "typeVersion": 3.2
    },
    {
      "id": "cadb68e2-a9fa-4b79-9ed5-2e15583169db",
      "name": "Calculate Reorder Needs",
      "type": "n8n-nodes-base.code",
      "position": [
        13584,
        1216
      ],
      "parameters": {
        "jsCode": "for (const item of $input.all()) {\n  const json = item.json;\n  const currentStock = Number(json['Current Stock']) || 0;\n  const last7DaysSales = Number(json['Last 7 Days Sales']) || 0;\n  const dailySales = last7DaysSales / 7;\n  const rawDeliveryTime = json['Avg Delivery Time'] || json['Avg. Delivery Time'] || json['Avg. Delivery Time '] || \"0\";\n  const leadTime = parseFloat(rawDeliveryTime.toString().replace(/[^0-9.]/g, '')) || 0;\n  const dynamicBuffer = Math.max(2, Math.min(14, Math.round(14 * dailySales)));\n  const targetStock = (leadTime + dynamicBuffer) * dailySales;\n  json['Reorder Quantity'] = Math.max(0, Math.ceil(targetStock - currentStock));\n  json['Debug - Clean Lead Time'] = leadTime;\n  json['Debug - Daily Sales'] = Number(dailySales.toFixed(2));\n  json['Debug - Target Stock'] = Number(targetStock.toFixed(2));\n}\nreturn $input.all();"
      },
      "typeVersion": 2
    },
    {
      "id": "d6cdc09f-ec03-4df7-b20f-e385f2a82c31",
      "name": "If Reorder Needed",
      "type": "n8n-nodes-base.if",
      "position": [
        13808,
        1216
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "2ce6c0d9-377e-419f-93b0-3df022321c89",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json['Reorder Quantity'] }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "cf506143-d1c6-4d7b-8d39-bada509b11c8",
      "name": "Format Reorder Data",
      "type": "n8n-nodes-base.set",
      "position": [
        14032,
        1200
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "fca8dec5-b0e4-4a6a-a574-675c9f0cb571",
              "name": "row_number",
              "type": "number",
              "value": "={{ $json.row_number }}"
            },
            {
              "id": "d2af2257-3f80-4242-ac23-9cedf24f8d85",
              "name": "product_string",
              "type": "string",
              "value": "={{ $json[\"Product ID\"] }} ({{ $json[\"Product Name\"] }})"
            },
            {
              "id": "a523512c-4a01-4449-8a5f-e736a9a49568",
              "name": "Product ID",
              "type": "string",
              "value": "={{ $json[\"Product ID\"] }}"
            },
            {
              "id": "0032b7a8-13d6-48ef-a594-054faadefa22",
              "name": "Vendor ID",
              "type": "string",
              "value": "={{ $json[\"Vendor ID\"] }}"
            },
            {
              "id": "b509b378-b9bd-4482-beb5-9f80bef827a9",
              "name": "Product Name",
              "type": "string",
              "value": "={{ $json[\"Product Name\"] }}"
            },
            {
              "id": "94bb26ad-f6fd-460f-8ece-d7ebaad9a61b",
              "name": "Current Stock",
              "type": "number",
              "value": "={{ $json[\"Current Stock\"] }}"
            },
            {
              "id": "0a65ae84-3154-4bcf-8c5f-4c0a8fcd1075",
              "name": "Last 7 Days Sales",
              "type": "number",
              "value": "={{ $json[\"Last 7 Days Sales\"] }}"
            },
            {
              "id": "aac91f83-4484-43c4-8115-75b9893dedac",
              "name": "Current Run away",
              "type": "string",
              "value": "={{ $json[\"Current Run away\"] }}"
            },
            {
              "id": "9f9fa635-41a0-4678-8038-d94f6ae27aee",
              "name": "Vendor Name",
              "type": "string",
              "value": "={{ $json[\"Vendor Name\"] }}"
            },
            {
              "id": "7d51b3cc-48c8-4709-9df7-d90aee0f9c87",
              "name": "Email Address",
              "type": "string",
              "value": "={{ $json[\"Email Address\"] }}"
            },
            {
              "id": "a9427f50-7044-4114-9788-ed5341ae5b9b",
              "name": "Avg Delivery Time",
              "type": "string",
              "value": "={{ $json[\"Avg Delivery Time\"] }}"
            },
            {
              "id": "56e7b1cc-6f3f-4fd8-b23b-69ba45fd26ea",
              "name": "Offered Product IDs",
              "type": "string",
              "value": "={{ $json[\"Offered Product IDs\"] }}"
            },
            {
              "id": "0ae28021-3065-48dc-8cea-93b3ff4834c9",
              "name": "Product Descriptions",
              "type": "string",
              "value": "={{ $json[\"Product Descriptions\"] }}"
            },
            {
              "id": "735f0d2e-4677-4dfa-a9af-82f82297d1e8",
              "name": "Safe Hold time",
              "type": "string",
              "value": "={{ $json[\"Safe Hold time\"] }}"
            },
            {
              "id": "64d0c84c-6a4e-4e55-b132-220c477b34bb",
              "name": "Reorder Quantity",
              "type": "number",
              "value": "={{ $json[\"Reorder Quantity\"] }}"
            },
            {
              "id": "c1a8256d-a53f-49f3-9ceb-3350374cf1d1",
              "name": "Debug - Clean Lead Time",
              "type": "number",
              "value": "={{ $json[\"Debug - Clean Lead Time\"] }}"
            },
            {
              "id": "8205d1b8-03d2-450a-98dc-60484f36301c",
              "name": "Debug - Daily Sales",
              "type": "number",
              "value": "={{ $json[\"Debug - Daily Sales\"] }}"
            },
            {
              "id": "977988c9-066e-4271-b7f7-e898d89258fa",
              "name": "Debug - Target Stock",
              "type": "number",
              "value": "={{ $json[\"Debug - Target Stock\"] }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "b6fadeca-ca34-4315-8001-d78f24be77a8",
      "name": "Aggregate Reorder Items",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        14256,
        1200
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "a3ffd1e6-8812-4c25-82ae-a671a5ab1959",
      "name": "Fetch Existing Reorders",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        14480,
        1200
      ],
      "parameters": {
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultUrl": "",
          "cachedResultName": ""
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": ""
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7,
      "alwaysOutputData": true
    },
    {
      "id": "5d22c97f-a638-48c7-9153-896d0e8e635f",
      "name": "Filter Reorder Records",
      "type": "n8n-nodes-base.code",
      "position": [
        14688,
        1200
      ],
      "parameters": {
        "jsCode": "// --- PHASE 1: DATA GATHERING & FILTERING ---\n\n// 1. Grab the historical data (flowing directly into this node)\nconst orderHistory = $input.all(); \n\n// 2. Reach back to grab the fresh low-stock alerts\n// IMPORTANT: Ensure \"Edit Fields1\" matches the exact name of your node!\nconst incomingOrders = $items(\"Format Reorder Data\"); \n\nconst COOLDOWN_DAYS = 14;\nconst now = new Date();\nconst itemsToOrder = [];\n\n// 3. Loop through low stock items to filter out ineligible ones\nfor (const item of incomingOrders) {\n    const productString = item.json.product_string; \n\n    const recentlyOrdered = orderHistory.some(historyItem => {\n        // If the product strings don't match, skip to the next row\n        if (historyItem.json.product_string !== productString) return false;\n\n        // Make sure we are reading the status in lowercase just to be safe\n        const currentStatus = (historyItem.json.status || \"\").toLowerCase();\n\n        // SHIELD 1: The Status Check\n        // If the order is currently pending or sent, do not reorder it!\n        if (currentStatus === 'pending' || currentStatus === 'sent') {\n            return true; // Flag as \"recently ordered\" to block it\n        }\n\n        // SHIELD 2: The 14-Day Date Check\n        // If it is completely finished, check if it was ordered recently\n        if (currentStatus === 'completed' && historyItem.json.reorder_date) {\n            const orderDate = new Date(historyItem.json.reorder_date);\n            \n            // Safety check to ensure n8n can actually read the date format\n            if (!isNaN(orderDate.getTime())) {\n                const daysSinceOrder = (now - orderDate) / (1000 * 60 * 60 * 24);\n                return daysSinceOrder <= COOLDOWN_DAYS; \n            }\n        }\n\n        // If it's not pending/sent, and it's older than 14 days, let it through!\n        return false;\n    });\n\n    // If it passed both shields, push it to our final array to be ordered\n    if (!recentlyOrdered) {\n        itemsToOrder.push(item);\n    }\n}\n\n\n// --- PHASE 2: VENDOR GROUPING ---\n\nconst groupedVendors = {};\n\n// Iterate through the filtered, clean items to group them by Vendor\nitemsToOrder.forEach(item => {\n    const data = item.json;\n    const vendorId = data[\"Vendor ID\"];\n\n    // Initialize vendor group\n    if (!groupedVendors[vendorId]) {\n        groupedVendors[vendorId] = {\n            \"Vendor ID\": vendorId,\n            \"Vendor Name\": data[\"Vendor Name\"],\n            \"Email Address\": data[\"Email Address\"],\n            \"Products String\": [],\n            \"Total Reorder Quantity\": 0,\n            \"Structured Line Items\": []\n        };\n    }\n\n    // Use existing product_string if available, else build it\n    const productString =\n        data.product_string ||\n        `${data[\"Product ID\"]} (${data[\"Product Name\"]})`;\n\n    groupedVendors[vendorId][\"Products String\"].push(productString);\n\n    // Aggregate reorder quantity\n    groupedVendors[vendorId][\"Total Reorder Quantity\"] += Number(data[\"Reorder Quantity\"] || 0);\n\n    // Structured items\n    groupedVendors[vendorId][\"Structured Line Items\"].push({\n        \"Product ID\": data[\"Product ID\"],\n        \"Product Name\": data[\"Product Name\"],\n        \"Reorder Quantity\": data[\"Reorder Quantity\"],\n        \"Current Stock\": data[\"Current Stock\"]\n    });\n});\n\n\n// --- PHASE 3: FINAL OUTPUT FORMATTING ---\n\n// Convert back to n8n output format\nconst result = Object.values(groupedVendors).map(vendor => {\n    vendor[\"Products String\"] = vendor[\"Products String\"].join(\", \");\n\n    return {\n        json: vendor\n    };\n});\n\n// Output the clean, grouped list!\nreturn result;"
      },
      "typeVersion": 2
    },
    {
      "id": "0891948d-5fbd-48a2-a8eb-0ed5e6eb7b65",
      "name": "Prepare Reorder Payload",
      "type": "n8n-nodes-base.set",
      "position": [
        14912,
        1200
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "2aea43e7-a433-47f8-b41b-f1b9c1c5e801",
              "name": "product_reorder_id",
              "type": "string",
              "value": "={{ 'p' + $now.valueOf() + Math.random().toString(36).substring(2, 6) }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "966a9a53-a385-44d9-a42a-31ab8cfc3507",
      "name": "Upsert Reorder in Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        15136,
        1200
      ],
      "parameters": {
        "columns": {
          "value": {
            "status": "pending",
            "Vendor ID": "={{ $('Filter Reorder Records').item.json[\"Vendor ID\"] }}",
            "Vendor Name": "={{ $('Filter Reorder Records').item.json[\"Vendor Name\"] }}",
            "reorder_date": "={{ $now }}",
            "Email Address": "={{ $('Filter Reorder Records').item.json[\"Email Address\"] }}",
            "product_string": "={{ $('Filter Reorder Records').item.json[\"Products String\"] }}",
            "product_reorder_id": "={{ 'p' + $now.valueOf() + Math.random().toString(36).substring(2, 6) }}",
            "Total Reorder Quantity": "={{ $('Filter Reorder Records').item.json[\"Total Reorder Quantity\"] }}",
            "products_with_quantity": "={{\n$('Filter Reorder Records').item.json[\"Structured Line Items\"]\n.map((item, index) => \n`${index + 1}. ${item[\"Product Name\"]}\n   Product ID: ${item[\"Product ID\"]}\n   Reorder Quantity: ${item[\"Reorder Quantity\"]}\n   Current Stock: ${item[\"Current Stock\"]}`\n)\n.join('\\n\\n')\n}}"
          },
          "schema": [
            {
              "id": "product_reorder_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "product_reorder_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Vendor ID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Vendor ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Vendor Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Vendor Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Address",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Email Address",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "product_string",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "product_string",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "products_with_quantity",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "products_with_quantity",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total Reorder Quantity",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Total Reorder Quantity",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "reorder_date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "reorder_date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "product_reorder_id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1vGmcxlf5NTgyd0fKt7O5Qwbu4ijLsfAiG6Tg-C7w81k/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1vGmcxlf5NTgyd0fKt7O5Qwbu4ijLsfAiG6Tg-C7w81k",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1vGmcxlf5NTgyd0fKt7O5Qwbu4ijLsfAiG6Tg-C7w81k/edit?usp=drivesdk",
          "cachedResultName": "Product_Reorder_Data"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "35e32d58-c554-46dd-9ecf-421a326ca747",
      "name": "Post Reorder to Slack",
      "type": "n8n-nodes-base.slack",
      "position": [
        15360,
        1200
      ],
      "parameters": {
        "text": "=\ud83d\udea8 *Stock Restock Update Required* \ud83d\udea8\n\n\ud83c\udfe2 *Vendor:* {{ $json[\"Vendor Name\"] }}\n\ud83c\udd94 *Vendor ID:* {{ $json[\"Vendor ID\"] }}\n\ud83d\udce7 *Contact:* {{ $json[\"Email Address\"] }}\n\ud83d\udd16 *Reorder ID:* {{ $json[\"product_reorder_id\"] }}\n\n\ud83d\udce6 *Products Requiring Restock:*\n\n{{ $json[\"products_with_quantity\"] }}\n\n\ud83d\uded2 *Total Reorder Quantity:* *{{ $json[\"Total Reorder Quantity\"] }} units*\n\n\u26a0\ufe0f Stock levels for the above items require replenishment to maintain inventory availability.\n",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": ""
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "445ab1e6-0aa9-4c39-81a2-ad441aedb809",
      "name": "When Slack Message Received",
      "type": "n8n-nodes-base.slackTrigger",
      "position": [
        12640,
        1760
      ],
      "parameters": {
        "options": {
          "resolveIds": false
        },
        "trigger": [
          "reaction_added"
        ],
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": ""
        }
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "73717657-b04f-40c6-b536-d32bd0be7b31",
      "name": "If Approval Came from the valid authority user?",
      "type": "n8n-nodes-base.if",
      "position": [
        12864,
        1760
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "54555b44-d132-4866-a1e2-7e9e96189fcb",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.user }}",
              "rightValue": "enter-your-authoritive-person-slack-id-here"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "6e3b9d74-f916-45bd-9135-f21b0cbe406c",
      "name": "Fetch Slack Thread Replies",
      "type": "n8n-nodes-base.slack",
      "position": [
        13088,
        1760
      ],
      "parameters": {
        "ts": "={{ $json.item.ts }}",
        "filters": {},
        "resource": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": ""
        },
        "operation": "replies"
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.5
    },
    {
      "id": "f9fd3ba0-4515-445d-af28-bc897b7f6e29",
      "name": "Parse Slack Message Data",
      "type": "n8n-nodes-base.code",
      "notes": "// Extract the text from the incoming item\nconst inputText = $input.first().json.text;\n\n// Execute the regex match\nconst match = inputText.match(/ReorderID:\\*\\s*([^\\n_]+)/);\nconst reorderId = match ? match[1].trim() : null;\n\n// n8n requires returning an array of objects wrapped in a 'json' key\nreturn [\n  {\n    json: {\n      reorderId: reorderId\n    }\n  }\n];",
      "position": [
        13312,
        1760
      ],
      "parameters": {
        "jsCode": "// 1. Map over all incoming items safely\nreturn $input.all().map(item => {\n  const inputText = item.json.text || \"\";\n  \n  // 2. Extract the ID\n  const match = inputText.match(/Reorder ID:\\*\\s*([^\\n_]+)/);\n  const reorderId = match ? match[1].trim() : null;\n  \n  // 3. Return the structurally correct n8n object\n  return {\n    json: {\n      reorderId: reorderId\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "c308a08f-01bb-45f1-8817-975f47fae975",
      "name": "Get Reorder Sheet Row",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        13536,
        1760
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $json.reorderId }}",
              "lookupColumn": "product_reorder_id"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1vGmcxlf5NTgyd0fKt7O5Qwbu4ijLsfAiG6Tg-C7w81k/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1vGmcxlf5NTgyd0fKt7O5Qwbu4ijLsfAiG6Tg-C7w81k",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1vGmcxlf5NTgyd0fKt7O5Qwbu4ijLsfAiG6Tg-C7w81k/edit?usp=drivesdk",
          "cachedResultName": "Product_Reorder_Data"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "99134749-16ae-45af-83fb-abcebe671c80",
      "name": "Send Email via Gmail",
      "type": "n8n-nodes-base.gmail",
      "position": [
        13760,
        1760
      ],
      "parameters": {
        "sendTo": "={{ $json[\"Email Address\"] }}",
        "message": "=<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Product Reorder Email</title>\n\n<style>\nbody {\n    margin: 0;\n    padding: 0;\n    background-color: #f5f7fb;\n    font-family: Arial, Helvetica, sans-serif;\n}\n\n.wrapper {\n    width: 100%;\n    padding: 40px 20px;\n}\n\n.container {\n    max-width: 650px;\n    margin: auto;\n    background: #ffffff;\n    border-radius: 14px;\n    overflow: hidden;\n    box-shadow: 0 8px 30px rgba(0,0,0,0.08);\n}\n\n.header {\n    background: #111827;\n    padding: 28px;\n    text-align: center;\n}\n\n.header h1 {\n    color: white;\n    margin: 0;\n    font-size: 24px;\n    font-weight: 600;\n}\n\n.content {\n    padding: 35px;\n    color: #374151;\n    line-height: 1.7;\n}\n\n.greeting {\n    font-size: 16px;\n    margin-bottom: 25px;\n}\n\n.info-box {\n    background: #f9fafb;\n    border: 1px solid #e5e7eb;\n    border-radius: 10px;\n    padding: 18px;\n    margin: 25px 0;\n}\n\n.info-row {\n    margin-bottom: 12px;\n}\n\n.label {\n    font-weight: 600;\n    color: #111827;\n}\n\n.products-box {\n    background: #f3f4f6;\n    border-radius: 10px;\n    padding: 18px;\n    border-left: 4px solid #111827;\n    margin-top: 20px;\n    white-space: pre-line;\n}\n\n.note {\n    margin-top: 30px;\n}\n\n.footer {\n    padding: 25px;\n    text-align: center;\n    border-top: 1px solid #e5e7eb;\n    color: #6b7280;\n    font-size: 13px;\n}\n</style>\n</head>\n\n<body>\n\n<div class=\"wrapper\">\n\n<div class=\"container\">\n\n    <div class=\"header\">\n        <h1>Inventory Reorder Request</h1>\n    </div>\n\n    <div class=\"content\">\n\n        <div class=\"greeting\">\n            Dear {{ $json[\"Vendor Name\"] }},\n        </div>\n\n        <p>\n            Please process the following product reorder for our inventory.\n        </p>\n\n        <div class=\"info-box\">\n\n            <div class=\"info-row\">\n                <span class=\"label\">Order Reference:</span>\n                {{ $json.product_reorder_id }}\n            </div>\n\n            <div class=\"info-row\">\n                <span class=\"label\">Total Items to Reorder:</span>\n                {{ $json[\"Total Reorder Quantity\"] }}\n            </div>\n\n        </div>\n\n        <div>\n            <span class=\"label\">Reorder Details</span>\n\n            <div class=\"products-box\">\n                {{ $json.products_with_quantity }}\n            </div>\n        </div>\n\n        <div class=\"note\">\n            Please confirm receipt of this order and provide an estimated delivery date.\n        </div>\n\n        <p style=\"margin-top:30px;\">\n            Thank you,<br>\n            <strong>Enter Your Company Name</strong>\n        </p>\n\n    </div>\n\n    <div class=\"footer\">\n        Inventory Management System \u2022 Enter-your-company-name-here\n    </div>\n\n</div>\n\n</div>\n\n</body>\n</html>",
        "options": {},
        "subject": "=Purchase Reorder Request.... {{$json.product_reorder_id}}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "fca4daa7-68b5-4ec1-8880-786796ce3fb1",
      "name": "Update Reorder Status in Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        13984,
        1760
      ],
      "parameters": {
        "columns": {
          "value": {
            "status": "SENT",
            "reorder_date": "={{ $now }}",
            "product_reorder_id": "={{ $('Get Reorder Sheet Row').item.json.product_reorder_id }}"
          },
          "schema": [
            {
              "id": "product_reorder_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "product_reorder_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Vendor ID",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Vendor ID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Vendor Name",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Vendor Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email Address",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Email Address",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "product_string",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "product_string",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "products_with_quantity",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "products_with_quantity",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total Reorder Quantity",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Total Reorder Quantity",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "reorder_date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "reorder_date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "product_reorder_id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1vGmcxlf5NTgyd0fKt7O5Qwbu4ijLsfAiG6Tg-C7w81k/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1vGmcxlf5NTgyd0fKt7O5Qwbu4ijLsfAiG6Tg-C7w81k",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1vGmcxlf5NTgyd0fKt7O5Qwbu4ijLsfAiG6Tg-C7w81k/edit?usp=drivesdk",
          "cachedResultName": "Product_Reorder_Data"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    }
  ],
  "active": true,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "e461f988-1676-491a-9942-e74530d2d7a3",
  "nodeGroups": [],
  "connections": {
    "When Scheduled": {
      "main": [
        [
          {
            "node": "Fetch Product Inventory",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Vendor Catalog",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If Reorder Needed": {
      "main": [
        [
          {
            "node": "Format Reorder Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Reorder Data": {
      "main": [
        [
          {
            "node": "Aggregate Reorder Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Vendor Catalog": {
      "main": [
        [
          {
            "node": "Prepare Vendor Delivery Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Email via Gmail": {
      "main": [
        [
          {
            "node": "Update Reorder Status in Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Reorder Sheet Row": {
      "main": [
        [
          {
            "node": "Send Email via Gmail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Reorder Records": {
      "main": [
        [
          {
            "node": "Prepare Reorder Payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate Reorder Items": {
      "main": [
        [
          {
            "node": "Fetch Existing Reorders",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Reorder Needs": {
      "main": [
        [
          {
            "node": "If Reorder Needed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Existing Reorders": {
      "main": [
        [
          {
            "node": "Filter Reorder Records",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Product Inventory": {
      "main": [
        [
          {
            "node": "Prepare Product Stock Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Reorder Payload": {
      "main": [
        [
          {
            "node": "Upsert Reorder in Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Slack Message Data": {
      "main": [
        [
          {
            "node": "Get Reorder Sheet Row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upsert Reorder in Sheets": {
      "main": [
        [
          {
            "node": "Post Reorder to Slack",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Slack Thread Replies": {
      "main": [
        [
          {
            "node": "Parse Slack Message Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Product Stock Data": {
      "main": [
        [
          {
            "node": "Merge Inventory and Vendors",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Inventory and Vendors": {
      "main": [
        [
          {
            "node": "Calculate Reorder Needs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When Slack Message Received": {
      "main": [
        [
          {
            "node": "If Approval Came from the valid authority user?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Vendor Delivery Data": {
      "main": [
        [
          {
            "node": "Merge Inventory and Vendors",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "If Approval Came from the valid authority user?": {
      "main": [
        [
          {
            "node": "Fetch Slack Thread Replies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}