This workflow corresponds to n8n.io template #13961 — we link there as the canonical source.
This workflow follows the Gmail → Google Sheets recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "ZNZoKQqrjNYW86W1",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "AI-Powered D2C Supply Chain That Monitors Inventory and Raises POs Automatically",
"tags": [],
"nodes": [
{
"id": "0620182f-f823-4314-bef7-b0407101813a",
"name": "Read Inventory Master",
"type": "n8n-nodes-base.googleSheets",
"position": [
160,
368
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit#gid=0",
"cachedResultName": "Inventory Master"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit?usp=drivesdk",
"cachedResultName": "D2C Supply Chain Brain"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": true,
"typeVersion": 4.2
},
{
"id": "f50a2acb-4424-41c8-9ac0-18e46b90694e",
"name": "Read Sales Log",
"type": "n8n-nodes-base.googleSheets",
"position": [
368,
368
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1969703549,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit#gid=1969703549",
"cachedResultName": "Sales Log"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit?usp=drivesdk",
"cachedResultName": "D2C Supply Chain Brain"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": true,
"typeVersion": 4.2
},
{
"id": "c3eea98f-c39b-4614-b3bd-94b9a70338ed",
"name": "IF Dead or Overstock",
"type": "n8n-nodes-base.if",
"position": [
1200,
480
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "5844217f-de21-4899-8a2e-074eeb28dd03",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.flag }}",
"rightValue": "\ud83d\udfe1"
}
]
}
},
"typeVersion": 2
},
{
"id": "ef6ce76b-5d3b-4d00-8e3d-d6c41344499d",
"name": "IF Stockout Risk",
"type": "n8n-nodes-base.if",
"position": [
784,
368
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0f4652d3-0d18-4a8c-8708-52771aed2ffb",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.flag }}",
"rightValue": "\ud83d\udd34"
}
]
}
},
"typeVersion": 2
},
{
"id": "9377ea2f-47f6-4ae2-b7ef-3f8be41c343c",
"name": "Read Inventory Master1",
"type": "n8n-nodes-base.googleSheets",
"position": [
176,
864
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit#gid=0",
"cachedResultName": "Inventory Master"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit?usp=drivesdk",
"cachedResultName": "D2C Supply Chain Brain"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": true,
"typeVersion": 4.2
},
{
"id": "1602da5d-5c06-4cdb-aca2-f6e7bd303f89",
"name": "Read Inventory Master2",
"type": "n8n-nodes-base.googleSheets",
"position": [
224,
1216
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit#gid=0",
"cachedResultName": "Inventory Master"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit?usp=drivesdk",
"cachedResultName": "D2C Supply Chain Brain"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": true,
"typeVersion": 4.2
},
{
"id": "c83fe074-7e1c-4c43-9ca3-da59ad4a2f53",
"name": "Read sales log",
"type": "n8n-nodes-base.googleSheets",
"position": [
208,
1600
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1969703549,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit#gid=1969703549",
"cachedResultName": "Sales Log"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit?usp=drivesdk",
"cachedResultName": "D2C Supply Chain Brain"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": true,
"typeVersion": 4.2
},
{
"id": "ffab12e1-850f-4494-b434-d7d019be6012",
"name": "Read Inventory Master3",
"type": "n8n-nodes-base.googleSheets",
"position": [
464,
1600
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit#gid=0",
"cachedResultName": "Inventory Master"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit?usp=drivesdk",
"cachedResultName": "D2C Supply Chain Brain"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": true,
"typeVersion": 4.2
},
{
"id": "5186099d-1f5f-4452-88b8-8e207ad7b9f2",
"name": "Build Forecast Prompt",
"type": "n8n-nodes-base.code",
"position": [
880,
1600
],
"parameters": {
"jsCode": "const skus = items.map(i => i.json);\nconst month = new Date().toLocaleString('default', { month: 'long' });\n\nreturn [{\n json: {\n prompt: `You are a D2C demand forecasting expert. Based on the last 90 days of sales data, predict demand for the next 30 days for each SKU.\n\nCurrent month: ${month}\n\nConsider:\n- Seasonal trends for this month\n- Sales velocity from last 90 days\n- Product category demand patterns\n- Festival/holiday seasons if applicable\n\nRespond ONLY in this JSON format:\n{\n \"forecast_month\": \"string\",\n \"forecasts\": [\n {\n \"sku_id\": \"string\",\n \"product_name\": \"string\",\n \"category\": \"string\",\n \"predicted_units_30d\": number,\n \"current_stock\": number,\n \"stock_needed\": number,\n \"action\": \"reorder now | stock up | sufficient | reduce\",\n \"seasonality_note\": \"string\",\n \"confidence\": \"high | medium | low\"\n }\n ]\n}\n\nRules:\n- stock_needed = predicted_units_30d - current_stock (if negative set to 0)\n- If stock_needed > 0: action = reorder now or stock up\n- If current_stock > predicted_units_30d * 2: action = reduce\n- Otherwise: action = sufficient\n- Add seasonality_note based on month and category\n\nSales Data:\n${JSON.stringify(skus, null, 2)}`\n }\n}];"
},
"typeVersion": 2
},
{
"id": "068f460e-5619-4ab0-b888-795d31a74786",
"name": "Build Forecast Email",
"type": "n8n-nodes-base.code",
"position": [
1872,
1600
],
"parameters": {
"jsCode": "const forecasts = items;\nconst month = forecasts[0]?.json.forecast_month || 'This Month';\n\nlet email = `D2C Demand Forecast Report \u2014 ${month}\\n`;\nemail += `Generated: ${new Date().toDateString()}\\n`;\nemail += `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n\\n`;\n\nconst reorder = forecasts.filter(f => f.json.action === 'reorder now');\nconst stockUp = forecasts.filter(f => f.json.action === 'stock up');\nconst reduce = forecasts.filter(f => f.json.action === 'reduce');\n\nif (reorder.length > 0) {\n email += `\ud83d\udea8 REORDER NOW\\n\\n`;\n reorder.forEach(f => {\n email += `Product: ${f.json.product_name}\\n`;\n email += `Predicted Demand (30d): ${f.json.predicted_units_30d} units\\n`;\n email += `Current Stock: ${f.json.current_stock} units\\n`;\n email += `Units to Order: ${f.json.stock_needed} units\\n`;\n email += `Note: ${f.json.seasonality_note}\\n`;\n email += `Confidence: ${f.json.confidence}\\n\\n`;\n });\n}\n\nif (stockUp.length > 0) {\n email += `\ud83d\udce6 STOCK UP SOON\\n\\n`;\n stockUp.forEach(f => {\n email += `Product: ${f.json.product_name}\\n`;\n email += `Predicted Demand (30d): ${f.json.predicted_units_30d} units\\n`;\n email += `Units to Order: ${f.json.stock_needed} units\\n`;\n email += `Note: ${f.json.seasonality_note}\\n\\n`;\n });\n}\n\nif (reduce.length > 0) {\n email += `\u2b07\ufe0f CONSIDER REDUCING\\n\\n`;\n reduce.forEach(f => {\n email += `Product: ${f.json.product_name} \u2014 overstock likely next 30 days\\n`;\n });\n}\n\nemail += `\\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n`;\nemail += `Total SKUs needing action: ${forecasts.length}`;\n\nreturn [{ json: { email_body: email, total_action: forecasts.length, month } }];"
},
"typeVersion": 2
},
{
"id": "bde2be38-dadd-40d9-ba76-3293523b4474",
"name": "\ud83d\udd50 Daily 8AM Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
16,
-64
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 8
}
]
}
},
"typeVersion": 1.3
},
{
"id": "1a31a9c6-e84e-4d1c-97d6-2a1de903b70d",
"name": "Fetch Products (DummyJSON)",
"type": "n8n-nodes-base.httpRequest",
"position": [
224,
-64
],
"parameters": {
"url": "https://dummyjson.com/products?limit=20",
"options": {}
},
"typeVersion": 4.3
},
{
"id": "bedcf14a-df6e-49f1-ba87-c28776d02d22",
"name": "Simulate Daily Sales",
"type": "n8n-nodes-base.code",
"position": [
432,
-64
],
"parameters": {
"jsCode": "const products = items[0].json.products;\n\nreturn products.map(p => {\n const unitsSold = Math.floor(Math.random() * 15) + 1;\n const remaining = p.stock - unitsSold;\n return {\n json: {\n sku_id: p.id,\n product_name: p.title,\n category: p.category,\n current_stock: p.stock,\n units_sold: unitsSold,\n remaining_stock: remaining < 0 ? 0 : remaining,\n supplier_email: \"user@example.com\",\n reorder_point: 20,\n lead_time_days: 7,\n status: \"active\",\n date: new Date().toISOString().split('T')[0]\n }\n };\n});"
},
"typeVersion": 2
},
{
"id": "3fa0f789-297b-4700-9f9b-112a839559ae",
"name": "Log to Sales Log",
"type": "n8n-nodes-base.googleSheets",
"position": [
640,
-64
],
"parameters": {
"columns": {
"value": {
"date": "={{ $json.date }}",
"sku_id": "={{ $json.sku_id }}",
"units_sold": "={{ $json.units_sold }}",
"product_name": "={{ $json.product_name }}",
"remaining_stock": "={{ $json.remaining_stock }}"
},
"schema": [
{
"id": "date",
"type": "string",
"display": true,
"required": false,
"displayName": "date",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "sku_id",
"type": "string",
"display": true,
"required": false,
"displayName": "sku_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "product_name",
"type": "string",
"display": true,
"required": false,
"displayName": "product_name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "units_sold",
"type": "string",
"display": true,
"required": false,
"displayName": "units_sold",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "remaining_stock",
"type": "string",
"display": true,
"required": false,
"displayName": "remaining_stock",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 1969703549,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit#gid=1969703549",
"cachedResultName": "Sales Log"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit?usp=drivesdk",
"cachedResultName": "D2C Supply Chain Brain"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": false,
"typeVersion": 4.7
},
{
"id": "19ba04ad-07a7-4e3e-9e8a-ad08eeadcb82",
"name": "Write to Inventory Master",
"type": "n8n-nodes-base.googleSheets",
"position": [
816,
-64
],
"parameters": {
"columns": {
"value": {
"sku_id": "={{ $('Simulate Daily Sales').item.json.sku_id }}",
"status": "={{ \"active\" }}",
"category": "={{ $('Simulate Daily Sales').item.json.category }}",
"product_name": "={{ $('Simulate Daily Sales').item.json.product_name }}",
"current_stock": "={{ $('Simulate Daily Sales').item.json.current_stock }}",
"reorder_point": "={{ $('Simulate Daily Sales').item.json.reorder_point }}",
"lead_time_days": "={{ $('Simulate Daily Sales').item.json.lead_time_days }}",
"supplier_email": "={{ $('Simulate Daily Sales').item.json.supplier_email }}"
},
"schema": [
{
"id": "sku_id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "sku_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "product_name",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "product_name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "category",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "category",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "current_stock",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "current_stock",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "reorder_point",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "reorder_point",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "lead_time_days",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "lead_time_days",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "supplier_email",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "supplier_email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "status",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "avg_daily_sales",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "avg_daily_sales",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "days_remaining",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "days_remaining",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "flag",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "flag",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit#gid=0",
"cachedResultName": "Inventory Master"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit?usp=drivesdk",
"cachedResultName": "D2C Supply Chain Brain"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": false,
"typeVersion": 4.7
},
{
"id": "54ec7660-44a0-4a71-93c6-810d56611026",
"name": "Daily 8:05AM Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-32,
368
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 8,
"triggerAtMinute": 5
}
]
}
},
"typeVersion": 1.1
},
{
"id": "2aa23deb-d39f-4991-bc4b-dda02f0df9ec",
"name": "Calculate Velocity & Flags",
"type": "n8n-nodes-base.code",
"position": [
576,
368
],
"parameters": {
"jsCode": "const inventory = $('Read Inventory Master').all();\nconst salesLog = $('Read Sales Log').all();\n\nconst today = new Date();\nconst sevenDaysAgo = new Date(today - 7 * 24 * 60 * 60 * 1000);\n\nreturn inventory.map(item => {\n const sku = item.json.sku_id;\n\n const recentSales = salesLog.filter(s => {\n const saleDate = new Date(s.json.date);\n return s.json.sku_id == sku && saleDate >= sevenDaysAgo;\n });\n\n const totalSold = recentSales.reduce((sum, s) => sum + Number(s.json.units_sold), 0);\n const avgDailySales = totalSold / 7;\n const currentStock = Number(item.json.current_stock);\n const daysRemaining = avgDailySales > 0 ? Math.floor(currentStock / avgDailySales) : 999;\n\n let flag = '\ud83d\udfe2 Healthy';\n if (daysRemaining < 14) flag = '\ud83d\udd34 Stockout Risk';\n else if (totalSold === 0) flag = '\ud83d\udfe1 Dead Stock';\n else if (daysRemaining > 60) flag = '\ud83d\udfe1 Overstock';\n\n return {\n json: {\n sku_id: sku,\n product_name: item.json.product_name,\n category: item.json.category,\n current_stock: currentStock,\n avg_daily_sales: avgDailySales.toFixed(2),\n days_remaining: daysRemaining,\n flag,\n supplier_email: item.json.supplier_email,\n date: new Date().toISOString().split('T')[0]\n }\n };\n});"
},
"typeVersion": 2
},
{
"id": "14ccf51c-ea11-4931-9d81-09f6556809e3",
"name": "Alert \u2014 Stockout Risk",
"type": "n8n-nodes-base.gmail",
"position": [
1168,
256
],
"parameters": {
"sendTo": "={{ $json.supplier_email }}",
"message": "=Product: {{ $json.product_name }}\nCategory: {{ $json.category }}\nCurrent Stock: {{ $json.current_stock }} units\nDays Remaining: {{ $json.days_remaining }} days\nAvg Daily Sales: {{ $json.avg_daily_sales }} units/day\n\nAction: Reorder immediately before stockout.",
"options": {},
"subject": "=\ud83d\udd34 Stockout Alert \u2014 {{ $json.product_name }}",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "0feee8fb-8e80-4c46-b0f3-88eb33d85d82",
"name": "Alert \u2014 Dead Stock",
"type": "n8n-nodes-base.gmail",
"position": [
1456,
480
],
"parameters": {
"sendTo": "={{ $json.supplier_email }}",
"message": "=Product: {{ $json.product_name }}\nCategory: {{ $json.category }}\nCurrent Stock: {{ $json.current_stock }} units\nDays Remaining: {{ $json.days_remaining }} days\nLast 7 days sold: 0 units\n\nAction: Review pricing, create a bundle, or consider discontinuing.",
"options": {},
"subject": "=\ud83d\udfe1 Dead Stock Warning \u2014 {{ $json.product_name }}",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "45503525-894c-4456-bf01-c15db6f485a2",
"name": "Update Flags (Stockout)",
"type": "n8n-nodes-base.googleSheets",
"position": [
1408,
256
],
"parameters": {
"columns": {
"value": {
"flag": "={{ $('IF Stockout Risk').item.json.flag }}",
"sku_id": "={{ $('IF Stockout Risk').item.json.sku_id }}",
"product_name": "={{ $('IF Stockout Risk').item.json.product_name }}",
"days_remaining": "={{ $('IF Stockout Risk').item.json.days_remaining }}",
"avg_daily_sales": "={{ $('IF Stockout Risk').item.json.avg_daily_sales }}"
},
"schema": [
{
"id": "sku_id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "sku_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "product_name",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "product_name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "category",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "category",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "current_stock",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "current_stock",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "reorder_point",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "reorder_point",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "lead_time_days",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "lead_time_days",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "supplier_email",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "supplier_email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "status",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "avg_daily_sales",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "avg_daily_sales",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "days_remaining",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "days_remaining",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "flag",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "flag",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"sku_id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit#gid=0",
"cachedResultName": "Inventory Master"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit?usp=drivesdk",
"cachedResultName": "D2C Supply Chain Brain"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "b8be79b7-3b1b-4248-b9f9-2d9671e6a386",
"name": "Update Flags (Dead Stock)",
"type": "n8n-nodes-base.googleSheets",
"position": [
1648,
480
],
"parameters": {
"columns": {
"value": {
"flag": "={{ $('IF Dead or Overstock').item.json.flag }}",
"sku_id": "={{ $('IF Dead or Overstock').item.json.sku_id }}",
"days_remaining": "={{ $('IF Dead or Overstock').item.json.days_remaining }}",
"avg_daily_sales": "={{ $('IF Dead or Overstock').item.json.avg_daily_sales }}"
},
"schema": [
{
"id": "sku_id",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "sku_id",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "product_name",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "product_name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "category",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "category",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "current_stock",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "current_stock",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "reorder_point",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "reorder_point",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "lead_time_days",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "lead_time_days",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "supplier_email",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "supplier_email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "status",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "avg_daily_sales",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "avg_daily_sales",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "days_remaining",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "days_remaining",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "flag",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "flag",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"sku_id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit#gid=0",
"cachedResultName": "Inventory Master"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit?usp=drivesdk",
"cachedResultName": "D2C Supply Chain Brain"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "4dac2963-f047-42cc-83a1-f1a5c91f2d03",
"name": "Daily 8:10AM Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-32,
864
],
"parameters": {
"rule": {
"interval": [
{
"triggerAtHour": 8,
"triggerAtMinute": 10
}
]
}
},
"typeVersion": 1.1
},
{
"id": "9ab21aa5-8d68-4ea2-928c-455f7eac796a",
"name": "Filter Stockout SKUs",
"type": "n8n-nodes-base.if",
"position": [
432,
864
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0f4652d3-0d18-4a8c-8708-52771aed2ffb",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.flag }}",
"rightValue": "\ud83d\udd34"
}
]
}
},
"typeVersion": 2
},
{
"id": "881626ca-0549-4ba2-b94f-1559f0754976",
"name": "Calculate Reorder Quantity",
"type": "n8n-nodes-base.code",
"position": [
688,
848
],
"parameters": {
"jsCode": "return items.map(item => {\n const avgDailySales = Number(item.json.avg_daily_sales);\n const leadTimeDays = Number(item.json.lead_time_days) || 7;\n const currentStock = Number(item.json.current_stock);\n\n // Skip if avg_daily_sales is 0 (SW2 hasn't populated it yet)\n if (avgDailySales === 0) {\n return {\n json: {\n ...item.json,\n skipped: true,\n skip_reason: \"avg_daily_sales is 0 \u2014 SW2 may not have run yet\"\n }\n };\n }\n\n const bufferStock = Math.ceil(avgDailySales * 7);\n const reorderQty = Math.ceil((avgDailySales * leadTimeDays) + bufferStock - currentStock);\n const poNumber = `PO-${item.json.sku_id}-${Date.now()}`;\n\n return {\n json: {\n ...item.json,\n skipped: false,\n reorder_qty: reorderQty > 0 ? reorderQty : 10,\n buffer_stock: bufferStock,\n po_number: poNumber,\n po_date: new Date().toISOString().split('T')[0]\n }\n };\n});"
},
"typeVersion": 2
},
{
"id": "b5d419e0-0a13-46e4-b2fe-37329e91720b",
"name": "Skip Zero-Velocity SKUs",
"type": "n8n-nodes-base.filter",
"position": [
896,
848
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "76dc6fbd-9e47-4fcf-842a-150737045ae4",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.skipped }}",
"rightValue": "=false"
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.3
},
{
"id": "c7632c00-f89d-43b7-86cf-ba8cfb803a9d",
"name": "Send PO to Supplier",
"type": "n8n-nodes-base.gmail",
"position": [
1152,
848
],
"parameters": {
"sendTo": "={{ \"forreferal04@gmail.com\" || !$json.supplier_email }}",
"message": "=Dear Supplier,\n\nPlease find below our purchase order details:\n\nPO Number: {{ $json.po_number }}\nDate: {{ $json.po_date }}\n\nProduct: {{ $json.product_name }}\nSKU ID: {{ $json.sku_id }}\nQuantity Required: {{ $json.reorder_qty }} units\n\nCurrent Stock: {{ $json.current_stock }} units\nExpected Stockout In: {{ $json.days_remaining }} days\n\nPlease confirm availability and expected delivery date.",
"options": {},
"subject": "=Purchase Order {{ $json.po_number }} \u2014 {{ $json.product_name }}",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "550d47a4-1b60-4d46-b894-a308292c49d9",
"name": "Log PO to Tracker",
"type": "n8n-nodes-base.googleSheets",
"position": [
1424,
848
],
"parameters": {
"columns": {
"value": {
"status": "={{ \"Sent\" }}",
"sku_id ": "={{ $('Calculate Reorder Quantity').item.json.sku_id }}",
"quantity": "={{ $('Calculate Reorder Quantity').item.json.reorder_qty }}",
"po_number": "={{ $('Calculate Reorder Quantity').item.json.po_number }}",
"date_raised": "={{ $('Calculate Reorder Quantity').item.json.po_date }}",
"product_name": "={{ $('Calculate Reorder Quantity').item.json.product_name }}",
"supplier_email": "={{ $('Calculate Reorder Quantity').item.json.supplier_email }}"
},
"schema": [
{
"id": "po_number",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "po_number",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "sku_id ",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "sku_id ",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "product_name",
"type": "string",
"display": true,
"required": false,
"displayName": "product_name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "quantity",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "quantity",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "supplier_email",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "supplier_email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "status",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "date_raised",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "date_raised",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 2137496817,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit#gid=2137496817",
"cachedResultName": "PO Tracker"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1F_dtklvZsxtENwuDGk_lxFLDjWgKqmaBdDm99GLNraY/edit?usp=drivesdk",
"cachedResultName": "D2C Supply Chain Brain"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"executeOnce": false,
"typeVersion": 4.7
},
{
"id": "6d9acff7-f4dd-4066-b975-f395b92851e8",
"name": "Notify \u2014 PO Raised",
"type": "n8n-nodes-base.gmail",
"position": [
1648,
848
],
"parameters": {
"sendTo": "={{ $json.supplier_email }}",
"message": "=PO {{ $json.po_number }} has been sent to {{ $json.supplier_email }}\n\nProduct: {{ $json.product_name }}\nQuantity Ordered: {{ $('Calculate Reorder Quantity').item.json.reorder_qty }} units\nReason: Stock will run out in {{ $('Calculate Reorder Quantity').item.json.days_remaining }} days",
"options": {},
"subject": "=\u2705 PO Raised \u2014 {{ $json.product_name }}",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "a9a0e2dc-b3ec-4fb2-b97a-a8feaa22c28a",
"name": "Weekly Sunday 9AM Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-32,
1216
],
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtHour": 9
}
]
}
},
"typeVersion": 1.1
},
{
"id": "fbcc1836-0d7c-4567-965d-7dba92c56f60",
"name": "Filter Dead & Overstock SKUs",
"type": "n8n-nodes-base.if",
"position": [
448,
1216
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "5844217f-de21-4899-8a2e-074eeb28dd03",
"operator": {
"type": "string",
"operation": "contains"
},
"leftValue": "={{ $json.flag }}",
"rightValue": "\ud83d\udfe1"
}
]
}
},
"typeVersion": 2
},
{
"id": "bc88e652-9cd7-4f3b-a4fe-d71f7cc76b5f",
"name": "Build GPT Prompt",
"type": "n8n-nodes-base.code",
"position": [
704,
1200
],
"parameters": {
"jsCode": "const skus = items.map(item => ({\n sku_id: item.json.sku_id,\n product_name: item.json.product_name,\n category: item.json.category,\n current_stock: item.json.current_stock,\n avg_daily_sales: item.json.avg_daily_sales,\n days_remaining: item.json.days_remaining,\n flag: item.json.flag\n}));\n\nreturn [{\n json: {\n prompt: `You are a D2C inventory strategist. Analyze the following slow-moving or dead stock SKUs and recommend actions.\n\nFor each SKU respond ONLY in this JSON format:\n{\n \"recommendations\": [\n {\n \"sku_id\": \"string\",\n \"product_name\": \"string\",\n \"flag\": \"string\",\n \"action\": \"bundle | discount | kill | monitor\",\n \"discount_percent\": number or null,\n \"reason\": \"string\",\n \"urgency\": \"high | medium | low\"\n }\n ]\n}\n\nSKU Data:\n${JSON.stringify(skus, null, 2)}\n\nRules:\n- If stock > 100 and daily sales < 1: recommend kill or heavy discount (30-50%)\n- If stock 50-100 and daily sales < 2: recommend bundle or moderate discount (15-25%)\n- If days_remaining > 60: recommend monitor or light discount (10-15%)\n- Always give a clear reason`\n }\n}];"
},
"typeVersion": 2
},
{
"id": "9f5e2a85-dcc3-4417-bd05-9e1a92ce6d46",
"name": "Inventory Strategist",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
912,
1200
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o",
"cachedResultName": "GPT-4O"
},
"options": {},
"responses": {
"values": [
{
"content": "={{ $json.prompt }}"
}
]
},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "19c59165-b6fd-4720-9692-7ad8f486a4dc",
"name": "Parse AI Recommendations",
"type": "n8n-nodes-base.code",
"position": [
1312,
1200
],
"parameters": {
"jsCode": "const response = items[0].json.output[0].content[0].text;\nconst cleaned = response.replace(/```json|```/g, '').trim();\nconst parsed = JSON.parse(cleaned);\n\nreturn parsed.recommendations.map(rec => ({\n json: rec\n}));"
},
"typeVersion": 2
},
{
"id": "e7fa7049-e1c8-4522-81c5-01268c567303",
"name": "Build Weekly Digest Email",
"type": "n8n-nodes-base.code",
"position": [
1584,
1200
],
"parameters": {
"jsCode": "const recs = items;\n\nlet emailBody = `D2C Supply Chain \u2014 Weekly Dead Inventory Report\\n`;\nemailBody += `Generated: ${new Date().toDateString()}\\n`;\nemailBody += `\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n\\n`;\n\nconst high = recs.filter(r => r.json.urgency === 'high');\nconst medium = recs.filter(r => r.json.urgency === 'medium');\nconst low = recs.filter(r => r.json.urgency === 'low');\n\nif (high.length > 0) {\n emailBody += `\ud83d\udd34 HIGH URGENCY (Act This Week)\\n\\n`;\n high.forEach(r => {\n emailBody += `Product: ${r.json.product_name}\\n`;\n emailBody += `Action: ${r.json.action.toUpperCase()}`;\n if (r.json.discount_percent) emailBody += ` \u2014 ${r.json.discount_percent}% off`;\n emailBody += `\\nReason: ${r.json.reason}\\n\\n`;\n });\n}\n\nif (medium.length > 0) {\n emailBody += `\ud83d\udfe1 MEDIUM URGENCY (Act This Month)\\n\\n`;\n medium.forEach(r => {\n emailBody += `Product: ${r.json.product_name}\\n`;\n emailBody += `Action: ${r.json.action.toUpperCase()}`;\n if (r.json.discount_percent) emailBody += ` \u2014 ${r.json.discount_percent}% off`;\n emailBody += `\\nReason: ${r.json.reason}\\n\\n`;\n });\n}\n\nif (low.length > 0) {\n emailBody += `\ud83d\udfe2 LOW URGENCY (Monitor)\\n\\n`;\n low.forEach(r => {\n emailBody += `Product: ${r.json.product_name} \u2014 ${r.json.action.toUpperCase()}\\n`;\n });\n}\n\nemailBody += `\\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n`;\nemailBody += `Total SKUs flagged: ${recs.length}`;\n\nreturn [{ json: { email_body: emailBody, total_flagged: recs.length } }];"
},
"typeVersion": 2
},
{
"id": "c15efca7-1dd2-44cb-8546-6b5fc54eb591",
"name": "Send Weekly Digest",
"type": "n8n-nodes-base.gmail",
"position": [
1840,
1200
],
"parameters": {
"sendTo": "= your_email_id",
"message": "={{ $json.email_body }}",
"options": {},
"subject": "=\ud83d\udce6 Weekly Dead Inventory Report \u2014 {{ $json.total_flagged }} SKUs Need Attention",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "b4ba5ab1-ba8e-4afe-838b-2773dd798453",
"name": "Weekly Sunday 9:30AM Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
0,
1600
],
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtHour": 9,
"triggerAtMinute": 30
}
]
}
},
"typeVersion": 1.1
},
{
"id": "f43d4ac3-1246-4900-be86-ab15e9878f5c",
"name": "Aggregate 90 Day Sales",
"type": "n8n-nodes-base.code",
"position": [
672,
1600
],
"parameters": {
"jsCode": "const salesLog = $('Read sales log').all();\nconst inventory = $('Read Inventory Master3').all();\n\nconst today = new Date();\nconst ninetyDaysAgo = new Date(today - 90 * 24 * 60 * 60 * 1000);\n\n// Group sales by SKU\nconst skuSales = {};\nsalesLog.forEach(s => {\n const saleDate = new Date(s.json.date);\n if (saleDate >= ninetyDaysAgo) {\n const sku = String(s.json.sku_id);\n if (!skuSales[sku]) skuSales[sku] = { total_sold: 0, days_count: 0 };\n skuSales[sku].total_sold += Number(s.json.units_sold);\n skuSales[sku].days_count += 1;\n }\n});\n\n// Merge with inventory\nconst result = inventory.map(item => {\n const sku = String(item.json.sku_id);\n const sales = skuSales[sku] || { total_sold: 0, days_count: 0 };\n const avgDaily = sales.days_count > 0 ? (sales.total_sold / sales.days_count).toFixed(2) : 0;\n\n return {\n json: {\n sku_id: sku,\n product_name: item.json.product_name,\n category: item.json.category,\n current_stock: item.json.current_stock,\n total_sold_90d: sales.total_sold,\n avg_daily_sales_90d: avgDaily,\n lead_time_days: item.json.lead_time_days || 7\n }\n };\n});\n\nreturn result;"
},
"typeVersion": 2
},
{
"id": "2034f56f-9831-4cb5-818d-6ad551378384",
"name": "Demand Forecaster",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
1072,
1600
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o",
"cachedResultName": "GPT-4O"
},
"options": {},
"responses": {
"values": [
{
"content": "={{ $json.prompt }}"
}
]
},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "2ea28460-d886-441a-abaa-b19370fa58fa",
"name": "Parse Forecast Response",
"type": "n8n-nodes-base.code",
"position": [
1440,
1600
],
"parameters": {
"jsCode": "const response = items[0].json.output[0].content[0].text;\nconst cleaned = response.replace(/```json|```/g, '').trim();\nconst parsed = JSON.parse(cleaned);\n\nreturn parsed.forecasts.map(f => ({\n json: {\n ...f,\n forecast_month: parsed.forecast_month\n }\n}));"
},
"typeVersion": 2
},
{
"id": "fb22c616-16fa-4330-a3fc-8077a096bf01",
"name": "Filter Actionable SKUs",
"type": "n8n-nodes-base.filter",
"position": [
1648,
1600
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "ac4cb7c4-eb57-416f-99da-a4ab3d12a140",
"operator": {
"type": "string",
"operation": "notEquals"
},
"leftValue": "={{ $json.action }}",
"rightValue": "={{ \"sufficient\" }}"
}
]
}
},
"typeVersion": 2.3
},
{
"id": "95f32b05-b06f-4e95-99bc-60377e400c05",
"name": "Send Forecast Report",
"type": "n8n-nodes-base.gmail",
"position": [
2096,
1600
],
"parameters": {
"sendTo": "= your_email_id",
"message": "={{ $json.email_body }}",
"options": {},
"subject": "=\ud83d\udcca 30-Day Demand Forecast \u2014 {{ $json.total_action }} SKUs Need Action \u2014 {{ $json.month }}",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "e4d83949-0cd3-4ced-aa4d-ce3ae332c6cb",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-960,
-512
],
"parameters": {
"width": 384,
"height": 656,
"content": "## \ud83d\uded2 D2C Supply Chain Brain Overview\n\nThis workflow runs your inventory on autopilot. \nIt pulls product data daily, tracks how fast things \nare selling, flags what's about to run out, raises \npurchase orders automatically, and sends you a \nweekly report on dead stock \u2014 all without you \ntouching anything.\n\n### HOW IT WORKS\n\nEvery morning at 8AM, it fetches product data and \nsimulates daily sales. Then it calculates stock \nhealth per SKU and emails you if something needs \nattention. Stockout? PO goes to supplier automatically. \nDead stock sitting around? GPT tells you what to do \nwith it. Every Sunday you also get a 30-day demand \nforecast so you're always buying ahead, not behind.\n\n### SETUP STEPS\n\n1. Copy the Google Sheet template and paste your \n Sheet ID in all Google Sheets nodes\n2. Add your Gmail OAuth2 credentials\n3. Add your OpenAI API key\n4. Replace your_email_id with your email\n"
},
"typeVersion": 1
},
{
"id": "acc64139-6caf-4a61-b456-975626daae91",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-128,
-176
],
"parameters": {
"color": 7,
"width": 1168,
"height": 304,
"content": "Runs daily at 8AM. Pulls 20 products from DummyJSON, simulates daily sales, and writes everything into Inventory Master and Sales Log. This feeds all other sub-workflows."
},
"typeVersion": 1
},
{
"id": "78a3f77b-9824-4d67-9d47-c42ba21ab8ce",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-144,
208
],
"parameters": {
"color": 7,
"width": 2000,
"height": 464,
"content": "Runs at 8:05AM daily. Reads last 7 days of sales, calculates velocity per SKU, flags each one as \ud83d\udd34 \ud83d\udfe1 or \ud83d\udfe2, updates the sheet, and fires email alerts if action is needed."
},
"typeVersion": 1
},
{
"id": "c9d24c85-2585-4c63-8b53-596d255a6342",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-112,
752
],
"parameters": {
"color": 7,
"width": 2000,
"height": 304,
"content": "Runs at 8:10AM daily. Picks up \ud83d\udd34 SKUs from the sheet, calculates reorder quantity using lead time and buf
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2googleSheetsOAuth2ApiopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Stop finding out you're out of stock after a customer already tried to buy. This workflow monitors your entire product inventory daily, calculates how fast each SKU is selling, and automatically raises purchase orders to your supplier before you hit zero — all without you…
Source: https://n8n.io/workflows/13961/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
The scoreboard shows you what happened. This workflow tells you why it happened. Every time an IPL match ends this automation detects the completed result, fetches the full scorecard, and sends it to
Limit Code. Uses httpRequest, gmail, scheduleTrigger, markdown. Scheduled trigger; 23 nodes.
Limit Code. Uses stickyNote, gmail, httpRequest, markdown. Scheduled trigger; 23 nodes.
Wait Splitout. Uses gmail, httpRequest, splitOut, html. Scheduled trigger; 21 nodes.
Wait Splitout. Uses gmail, httpRequest, splitOut, html. Scheduled trigger; 21 nodes.