{
  "id": "flk0u88HjAaG2LEf",
  "name": "Multi-Warehouse Inventory Sync with Google Sheets & Email Alerts",
  "tags": [],
  "nodes": [
    {
      "id": "01889a3e-2114-48d1-b95c-d15f544888bb",
      "name": "\u23f0 Hourly Reconciliation Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -2080,
        0
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "8ddc77f0-6103-4f44-a9d4-c24ea2b109bc",
      "name": "\ud83d\udce5 Platform Webhook Receiver",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -2752,
        -272
      ],
      "parameters": {
        "path": "inventory-webhook",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "e85773c1-3541-41aa-9fd5-3b962ca4f224",
      "name": "\ud83d\udcdd Parse Trigger Data",
      "type": "n8n-nodes-base.set",
      "position": [
        -1888,
        192
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "triggerType",
              "name": "triggerType",
              "type": "string",
              "value": "={{ $json.body ? 'webhook' : 'schedule' }}"
            },
            {
              "id": "sku",
              "name": "sku",
              "type": "string",
              "value": "={{ $json.body?.sku || 'ALL' }}"
            },
            {
              "id": "platform",
              "name": "platform",
              "type": "string",
              "value": "={{ $json.body?.platform || 'ALL' }}"
            },
            {
              "id": "syncMode",
              "name": "syncMode",
              "type": "string",
              "value": "={{ $json.body?.sku ? 'single' : 'full' }}"
            }
          ]
        }
      },
      "typeVersion": 3.3
    },
    {
      "id": "1400a211-e04c-4a41-916d-0d7857de5cb6",
      "name": "\ud83d\udecd\ufe0f Fetch Shopify Inventory",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1664,
        16
      ],
      "parameters": {
        "url": "https://{{ $env.SHOPIFY_STORE }}.myshopify.com/admin/api/2024-01/products.json",
        "options": {
          "timeout": 30000
        },
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "limit",
              "value": "250"
            },
            {
              "name": "fields",
              "value": "id,title,variants"
            }
          ]
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "48d97f0b-ab09-40cb-b6d1-63f0413a3f0f",
      "name": "\ud83d\uded2 Fetch WooCommerce Inventory",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1648,
        192
      ],
      "parameters": {
        "url": "={{ $env.WOOCOMMERCE_URL }}/wp-json/wc/v3/products",
        "options": {
          "timeout": 30000
        },
        "sendQuery": true,
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBasicAuth",
        "queryParameters": {
          "parameters": [
            {
              "name": "per_page",
              "value": "100"
            },
            {
              "name": "status",
              "value": "publish"
            }
          ]
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "a0c14f75-e5d6-4f93-9e00-099b90fd4ce1",
      "name": "\ud83d\udd00 Merge All Platform Data",
      "type": "n8n-nodes-base.merge",
      "position": [
        -1408,
        176
      ],
      "parameters": {
        "mode": "combine",
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "55b1e266-2955-4278-8c10-7aa6db851e12",
      "name": "\ud83d\udd0d Compare & Identify Discrepancies",
      "type": "n8n-nodes-base.code",
      "position": [
        -1184,
        176
      ],
      "parameters": {
        "jsCode": "// Inventory Data Normalization & Comparison Engine\n// Standardizes data from all platforms and identifies discrepancies\n\nconst inputData = $input.all();\n\n// Initialize storage\nconst inventoryByPlatform = {\n  shopify: [],\n  woocommerce: [],\n  magento: [],\n  erpnext: [],\n  customdb: []\n};\n\n// Parse and normalize data from each platform\nfor (const item of inputData) {\n  const json = item.json;\n  \n  // Shopify data\n  if (json.products) {\n    for (const product of json.products) {\n      for (const variant of product.variants || []) {\n        inventoryByPlatform.shopify.push({\n          sku: variant.sku || variant.id.toString(),\n          quantity: variant.inventory_quantity || 0,\n          productName: product.title,\n          variantId: variant.id,\n          platform: 'shopify',\n          lastUpdated: variant.updated_at\n        });\n      }\n    }\n  }\n  \n  // WooCommerce data\n  if (json.id && json.sku && json.stock_quantity !== undefined) {\n    inventoryByPlatform.woocommerce.push({\n      sku: json.sku,\n      quantity: parseInt(json.stock_quantity) || 0,\n      productName: json.name,\n      productId: json.id,\n      platform: 'woocommerce',\n      lastUpdated: json.date_modified\n    });\n  }\n  \n  // Magento data\n  if (json.items) {\n    for (const product of json.items) {\n      if (product.extension_attributes?.stock_item) {\n        inventoryByPlatform.magento.push({\n          sku: product.sku,\n          quantity: parseInt(product.extension_attributes.stock_item.qty) || 0,\n          productName: product.name,\n          productId: product.id,\n          platform: 'magento',\n          lastUpdated: product.updated_at\n        });\n      }\n    }\n  }\n  \n  // ERPNext data (Master source)\n  if (json.data) {\n    for (const item of json.data) {\n      inventoryByPlatform.erpnext.push({\n        sku: item.item_code,\n        quantity: parseInt(item.stock_qty) || 0,\n        productName: item.name,\n        platform: 'erpnext',\n        isMaster: true,\n        lastUpdated: item.modified\n      });\n    }\n  }\n  \n  // Custom Database data\n  if (json.sku && json.quantity !== undefined) {\n    inventoryByPlatform.customdb.push({\n      sku: json.sku,\n      quantity: parseInt(json.quantity) || 0,\n      warehouseLocation: json.warehouse_location,\n      platform: 'customdb',\n      lastUpdated: json.last_updated\n    });\n  }\n}\n\n// Consolidate all SKUs\nconst allSKUs = new Set();\nfor (const platform in inventoryByPlatform) {\n  for (const item of inventoryByPlatform[platform]) {\n    if (item.sku) allSKUs.add(item.sku);\n  }\n}\n\n// Compare inventory across platforms for each SKU\nconst discrepancies = [];\nconst consistentItems = [];\n\nfor (const sku of allSKUs) {\n  const skuData = {\n    sku: sku,\n    platforms: {}\n  };\n  \n  // Collect data from each platform\n  for (const platform in inventoryByPlatform) {\n    const platformItem = inventoryByPlatform[platform].find(item => item.sku === sku);\n    if (platformItem) {\n      skuData.platforms[platform] = {\n        quantity: platformItem.quantity,\n        lastUpdated: platformItem.lastUpdated,\n        productName: platformItem.productName,\n        isMaster: platformItem.isMaster || false,\n        productId: platformItem.productId,\n        variantId: platformItem.variantId\n      };\n    }\n  }\n  \n  // Calculate statistics\n  const quantities = Object.values(skuData.platforms).map(p => p.quantity);\n  const avgQuantity = quantities.reduce((a, b) => a + b, 0) / quantities.length;\n  const maxQuantity = Math.max(...quantities);\n  const minQuantity = Math.min(...quantities);\n  const variance = maxQuantity - minQuantity;\n  const variancePercent = avgQuantity > 0 ? (variance / avgQuantity) * 100 : 0;\n  \n  skuData.statistics = {\n    average: avgQuantity,\n    max: maxQuantity,\n    min: minQuantity,\n    variance: variance,\n    variancePercent: variancePercent.toFixed(2),\n    platformCount: Object.keys(skuData.platforms).length\n  };\n  \n  // Determine if there's a discrepancy\n  if (variance > 0 && variancePercent > 5) {\n    // Significant discrepancy found\n    skuData.hasDiscrepancy = true;\n    skuData.severity = variancePercent > 20 ? 'critical' : variancePercent > 10 ? 'warning' : 'info';\n    skuData.recommendedAction = 'ai_review';\n    \n    // Use ERPNext as source of truth if available\n    if (skuData.platforms.erpnext) {\n      skuData.sourceOfTruth = 'erpnext';\n      skuData.correctQuantity = skuData.platforms.erpnext.quantity;\n      skuData.recommendedAction = 'sync_to_erpnext';\n    } else {\n      // Use most recently updated platform\n      let mostRecent = null;\n      let mostRecentTime = null;\n      \n      for (const [platform, data] of Object.entries(skuData.platforms)) {\n        const updateTime = new Date(data.lastUpdated);\n        if (!mostRecentTime || updateTime > mostRecentTime) {\n          mostRecentTime = updateTime;\n          mostRecent = platform;\n        }\n      }\n      \n      skuData.sourceOfTruth = mostRecent;\n      skuData.correctQuantity = skuData.platforms[mostRecent].quantity;\n      skuData.recommendedAction = `sync_to_${mostRecent}`;\n    }\n    \n    discrepancies.push(skuData);\n  } else {\n    // Inventory is consistent\n    skuData.hasDiscrepancy = false;\n    skuData.severity = 'none';\n    consistentItems.push(skuData);\n  }\n}\n\n// Sort discrepancies by severity\ndiscrepancies.sort((a, b) => {\n  const severityOrder = { critical: 0, warning: 1, info: 2 };\n  return severityOrder[a.severity] - severityOrder[b.severity];\n});\n\n// Return comprehensive analysis\nreturn [{\n  json: {\n    summary: {\n      totalSKUs: allSKUs.size,\n      discrepanciesFound: discrepancies.length,\n      consistentItems: consistentItems.length,\n      criticalDiscrepancies: discrepancies.filter(d => d.severity === 'critical').length,\n      warningDiscrepancies: discrepancies.filter(d => d.severity === 'warning').length,\n      platformsConnected: Object.keys(inventoryByPlatform).filter(p => inventoryByPlatform[p].length > 0).length,\n      timestamp: new Date().toISOString()\n    },\n    discrepancies: discrepancies,\n    consistentItems: consistentItems.slice(0, 10), // Sample of consistent items\n    platformData: inventoryByPlatform\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "148d6a37-1d40-453e-a682-f2afcb90931c",
      "name": "\u2753 Has Discrepancies?",
      "type": "n8n-nodes-base.if",
      "position": [
        -960,
        176
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "has-discrepancies",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.summary.discrepanciesFound }}",
              "rightValue": 0
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "ab9dd3c3-8a6a-4fbf-b715-31852d9d63a0",
      "name": "\ud83d\udccb Split Discrepancies for AI Review",
      "type": "n8n-nodes-base.code",
      "position": [
        -704,
        80
      ],
      "parameters": {
        "jsCode": "// Split discrepancies into individual items for AI analysis\nconst data = $input.first().json;\nconst discrepancies = data.discrepancies || [];\n\n// Return each discrepancy as separate item for AI processing\nreturn discrepancies.map(item => ({\n  json: {\n    sku: item.sku,\n    platforms: item.platforms,\n    statistics: item.statistics,\n    severity: item.severity,\n    sourceOfTruth: item.sourceOfTruth,\n    correctQuantity: item.correctQuantity,\n    recommendedAction: item.recommendedAction,\n    originalData: item\n  }\n}));"
      },
      "typeVersion": 2
    },
    {
      "id": "b9ca15c4-4ad0-4ca5-8aaa-c63805a2b3d0",
      "name": "\ud83d\udcdd Prepare Update Actions",
      "type": "n8n-nodes-base.code",
      "position": [
        -2624,
        -400
      ],
      "parameters": {
        "jsCode": "// Parse AI response and prepare update actions\nconst item = $input.first().json;\n\nlet aiDecision;\ntry {\n  // Extract JSON from AI response\n  const responseText = item.response || item.text || JSON.stringify(item);\n  const jsonMatch = responseText.match(/\\{[\\s\\S]*\\}/);\n  if (jsonMatch) {\n    aiDecision = JSON.parse(jsonMatch[0]);\n  } else {\n    throw new Error('No JSON found in AI response');\n  }\n} catch (error) {\n  console.error('Failed to parse AI response:', error);\n  // Fallback to original recommendation\n  aiDecision = {\n    decision: 'approve',\n    sourceOfTruth: item.sourceOfTruth,\n    correctQuantity: item.correctQuantity,\n    reasoning: 'Using original recommendation due to AI parse error',\n    confidence: 'low',\n    requiresManualReview: true\n  };\n}\n\n// Prepare update instructions for each platform\nconst updates = [];\n\nif (aiDecision.decision === 'approve' && !aiDecision.requiresManualReview) {\n  for (const [platform, data] of Object.entries(item.platforms)) {\n    if (platform !== aiDecision.sourceOfTruth && data.quantity !== aiDecision.correctQuantity) {\n      updates.push({\n        platform: platform,\n        sku: item.sku,\n        currentQuantity: data.quantity,\n        newQuantity: aiDecision.correctQuantity,\n        productId: data.productId,\n        variantId: data.variantId,\n        action: 'update',\n        reason: aiDecision.reasoning\n      });\n    }\n  }\n}\n\nreturn [{\n  json: {\n    sku: item.sku,\n    aiDecision: aiDecision,\n    updates: updates,\n    originalData: item,\n    timestamp: new Date().toISOString(),\n    requiresManualReview: aiDecision.requiresManualReview || aiDecision.decision !== 'approve'\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "0870838d-5ca8-4692-bd7b-784bdb5a0b68",
      "name": "\ud83d\udea8 Needs Manual Review?",
      "type": "n8n-nodes-base.if",
      "position": [
        -2464,
        -400
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "needs-manual-review",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.requiresManualReview }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "f6bf18e8-b3e4-48ab-9fdc-b4feeb8295e9",
      "name": "\ud83d\udd00 Split Updates by Platform",
      "type": "n8n-nodes-base.code",
      "position": [
        -2304,
        -224
      ],
      "parameters": {
        "jsCode": "// Split updates by platform for parallel execution\nconst item = $input.first().json;\nconst updates = item.updates || [];\n\nif (updates.length === 0) {\n  return [{ json: { message: 'No updates needed', sku: item.sku } }];\n}\n\nreturn updates.map(update => ({\n  json: {\n    ...update,\n    sku: item.sku,\n    aiDecision: item.aiDecision\n  }\n}));"
      },
      "typeVersion": 2
    },
    {
      "id": "7345be2f-446c-44a8-a51c-edfc70aab70d",
      "name": "\ud83d\udd00 Route Updates to Platforms",
      "type": "n8n-nodes-base.switch",
      "position": [
        -2080,
        -224
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "shopify",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "5b747c86-4713-42ff-9ec6-a5e64dd1ef8a",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.platform }}",
                    "rightValue": "shopify"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "woocommerce",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "2d5fbb50-7488-4e14-83a6-9abce83cfc78",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.platform }}",
                    "rightValue": "woocommerce"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "2dbb54af-3007-40ec-88ce-c61c9efb7662",
      "name": "\ud83d\udecd\ufe0f Update Shopify",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1856,
        -320
      ],
      "parameters": {
        "url": "=https://{{ $env.SHOPIFY_STORE }}.myshopify.com/admin/api/2024-01/inventory_levels/set.json",
        "method": "PUT",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "location_id",
              "value": "={{ $env.SHOPIFY_LOCATION_ID }}"
            },
            {
              "name": "inventory_item_id",
              "value": "={{ $json.variantId }}"
            },
            {
              "name": "available",
              "value": "={{ $json.newQuantity }}"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "925d0b5f-3040-4118-b2ab-90d19c9747c0",
      "name": "\ud83d\uded2 Update WooCommerce",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -1856,
        -144
      ],
      "parameters": {
        "url": "={{ $env.WOOCOMMERCE_URL }}/wp-json/wc/v3/products/{{ $json.productId }}",
        "method": "PUT",
        "options": {},
        "jsonBody": "={\n  \"stock_quantity\": {{ $json.newQuantity }}\n}",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBasicAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "af4349e9-c55d-4136-ac7c-c8bea746c26c",
      "name": "\ud83d\udd00 Merge Update Results",
      "type": "n8n-nodes-base.merge",
      "position": [
        -1632,
        -224
      ],
      "parameters": {
        "mode": "combine",
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "4147cc43-a94d-4645-a6c2-aa4b67e23b2d",
      "name": "\ud83d\udcca Log to Google Sheets Audit",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1376,
        -352
      ],
      "parameters": {
        "columns": {
          "value": {
            "sku": "={{ $json.sku }}",
            "action": "={{ $json.action }}",
            "reason": "={{ $json.reason }}",
            "platform": "={{ $json.platform }}",
            "timestamp": "={{ $now.toISO() }}",
            "confidence": "={{ $json.aiDecision?.confidence }}",
            "newQuantity": "={{ $json.newQuantity }}",
            "oldQuantity": "={{ $json.currentQuantity }}",
            "manualReview": "={{ $json.requiresManualReview }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Audit Log"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $env.GOOGLE_SHEETS_AUDIT_ID }}"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "6861a3f1-bb62-4cc5-ab13-8193aa4465d6",
      "name": "\ud83d\udce7 Send Notification?",
      "type": "n8n-nodes-base.if",
      "position": [
        -1216,
        -352
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "is-critical",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.aiDecision?.requiresManualReview || $json.severity === 'critical' }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "38882834-1ccc-496a-b5e2-a84d79b91fba",
      "name": "\u2709\ufe0f Send Alert Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -1008,
        -368
      ],
      "parameters": {
        "sendTo": "={{ $env.NOTIFICATION_EMAIL }}",
        "message": "=<html>\n<body style=\"font-family: Arial, sans-serif;\">\n  <h2>Inventory Synchronization Alert</h2>\n  \n  <div style=\"background: #fff3cd; padding: 15px; border-radius: 5px; margin: 20px 0;\">\n    <h3>\u26a0\ufe0f Manual Review Required</h3>\n    <p><strong>SKU:</strong> {{ $json.sku }}</p>\n    <p><strong>Severity:</strong> {{ $json.severity }}</p>\n  </div>\n  \n  <h3>Current Inventory Status:</h3>\n  <table style=\"border-collapse: collapse; width: 100%;\">\n    <tr style=\"background: #f8f9fa;\">\n      <th style=\"border: 1px solid #ddd; padding: 8px;\">Platform</th>\n      <th style=\"border: 1px solid #ddd; padding: 8px;\">Quantity</th>\n      <th style=\"border: 1px solid #ddd; padding: 8px;\">Last Updated</th>\n    </tr>\n    {{ Object.entries($json.platforms).map(([platform, data]) => `\n    <tr>\n      <td style=\"border: 1px solid #ddd; padding: 8px;\">${platform}</td>\n      <td style=\"border: 1px solid #ddd; padding: 8px;\">${data.quantity}</td>\n      <td style=\"border: 1px solid #ddd; padding: 8px;\">${data.lastUpdated}</td>\n    </tr>\n    `).join('') }}\n  </table>\n  \n  <h3>AI Analysis:</h3>\n  <p><strong>Recommended Action:</strong> {{ $json.aiDecision?.reasoning }}</p>\n  <p><strong>Confidence:</strong> {{ $json.aiDecision?.confidence }}</p>\n  \n  <p style=\"margin-top: 30px; color: #6c757d; font-size: 12px;\">\n    Timestamp: {{ $now.toISO() }}<br>\n    This is an automated message from the Inventory Sync System.\n  </p>\n</body>\n</html>",
        "options": {},
        "subject": "=\ud83d\udea8 Inventory Sync Alert: {{ $json.sku }}"
      },
      "typeVersion": 2.1
    },
    {
      "id": "3a7c80d3-b584-4f0d-9e56-133835759f2b",
      "name": "\ud83d\udce4 Return Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -720,
        -192
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "={{ {\n  \"success\": true,\n  \"summary\": $('\ud83d\udd0d Compare & Identify Discrepancies').item.json.summary,\n  \"discrepanciesProcessed\": $('\ud83d\udcdd Prepare Update Actions').all().length,\n  \"updatesApplied\": $('\ud83d\udd00 Merge Update Results').all().length,\n  \"timestamp\": $now.toISO()\n} }}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "99763021-7179-4d4a-b37b-35d5cf2d03a4",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2784,
        -784
      ],
      "parameters": {
        "width": 448,
        "height": 256,
        "content": "## How It Works\nA webhook or timer triggers the workflow to automatically fetch inventory data from multiple platforms. Stock levels are compared across stores to identify discrepancies, and any inconsistencies are updated on the respective platforms in real time. All changes and updates are recorded in Google Sheets for easy tracking, and email alerts are sent to notify relevant team members of any exceptions or issues that require attention. This ensures inventory accuracy and timely response to stock mismatches.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "36d24781-1b5a-4d91-9001-0682255e8a35",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1824,
        -784
      ],
      "parameters": {
        "color": 4,
        "width": 400,
        "height": 272,
        "content": "## Setup Instructions\n1. Add Shopify/WooCommerce API credentials.\n2. Link Google Sheets and Gmail.\n3. Adjust sync frequency in Function nodes.\n\n## Prerequisites\n- Shopify/WooCommerce API keys\n- Google Sheets access\n- Gmail credentials\n- n8n instance\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "3f2a21ab-a4b3-4728-9e2b-722c86e29d48",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1392,
        -784
      ],
      "parameters": {
        "color": 3,
        "width": 304,
        "height": 256,
        "content": "## Customization\n- Add ERPNext or custom APIs\n- Enable Slack notifications\n- AI discrepancy detection\n\n## Benefits\n- Real-time inventory accuracy\n- Automated cross-platform updates\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f647ebf9-8bf3-46ea-adb6-defc4c7ebca8",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2304,
        -784
      ],
      "parameters": {
        "width": 448,
        "height": 208,
        "content": "## Setup Steps\n1. Add Shopify and/or WooCommerce API credentials to enable secure data access.\n2. Connect Google Sheets for comprehensive logging of all inventory updates and Gmail for sending timely email alerts.\n3. Configure the sync frequency within the Function nodes to control how often inventory data is fetched, compared, and updated."
      },
      "typeVersion": 1
    },
    {
      "id": "d8b80508-910b-4a02-ba69-25f0e97f5047",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2784,
        -512
      ],
      "parameters": {
        "color": 7,
        "width": 608,
        "height": 528,
        "content": "## Data Collection\nFetches current inventory from Shopify and WooCommerce APIs, then normalizes product data into a consistent format for comparison."
      },
      "typeVersion": 1
    },
    {
      "id": "0d490778-6491-4c03-801f-b5e754c14658",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1424,
        -96
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 448,
        "content": "## Discrepancy Detection\nCompares stock levels by SKU across platforms. Flags mismatches and determines which platform has the authoritative count.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f2b64093-ddd3-4618-ba92-3083d48b2dbc",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2160,
        -512
      ],
      "parameters": {
        "color": 7,
        "width": 720,
        "height": 896,
        "content": "## Platform Updates\nPushes corrected inventory values back to Shopify and WooCommerce to maintain sync across both stores."
      },
      "typeVersion": 1
    },
    {
      "id": "2a8cb55f-7e37-450a-a7a7-ee071d95f0cb",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -768,
        -512
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 864,
        "content": "## Logging & Alerts\nRecords all sync operations to Google Sheets with timestamps. Sends email notifications for discrepancies or sync failures.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e9a33c02-317b-4922-970f-787d277b9a48",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1424,
        -512
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 384,
        "content": "## Error Handling\nCatches API failures, connection issues, or data format problems. Ensures partial failures don't break the entire sync process."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "a8bfad8f-43f0-4527-bf3e-33d9759dd9bc",
  "connections": {
    "\u2753 Has Discrepancies?": {
      "main": [
        [
          {
            "node": "\ud83d\udccb Split Discrepancies for AI Review",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\ud83d\udce4 Return Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udecd\ufe0f Update Shopify": {
      "main": [
        [
          {
            "node": "\ud83d\udd00 Merge Update Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u2709\ufe0f Send Alert Email": {
      "main": [
        [
          {
            "node": "\ud83d\udce4 Return Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcdd Parse Trigger Data": {
      "main": [
        [
          {
            "node": "\ud83d\udecd\ufe0f Fetch Shopify Inventory",
            "type": "main",
            "index": 0
          },
          {
            "node": "\ud83d\uded2 Fetch WooCommerce Inventory",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udce7 Send Notification?": {
      "main": [
        [
          {
            "node": "\u2709\ufe0f Send Alert Email",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\ud83d\udce4 Return Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\uded2 Update WooCommerce": {
      "main": [
        [
          {
            "node": "\ud83d\udd00 Merge Update Results",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "\ud83d\udd00 Merge Update Results": {
      "main": [
        [
          {
            "node": "\ud83d\udcca Log to Google Sheets Audit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udea8 Needs Manual Review?": {
      "main": [
        [
          {
            "node": "\ud83d\udcca Log to Google Sheets Audit",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\ud83d\udd00 Split Updates by Platform",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcdd Prepare Update Actions": {
      "main": [
        [
          {
            "node": "\ud83d\udea8 Needs Manual Review?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd00 Merge All Platform Data": {
      "main": [
        [
          {
            "node": "\ud83d\udd0d Compare & Identify Discrepancies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udce5 Platform Webhook Receiver": {
      "main": [
        [
          {
            "node": "\ud83d\udcdd Parse Trigger Data",
            "type": "main",
            "index": 0
          },
          {
            "node": "\ud83d\udcdd Prepare Update Actions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd00 Split Updates by Platform": {
      "main": [
        [
          {
            "node": "\ud83d\udd00 Route Updates to Platforms",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcca Log to Google Sheets Audit": {
      "main": [
        [
          {
            "node": "\ud83d\udce7 Send Notification?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd00 Route Updates to Platforms": {
      "main": [
        [
          {
            "node": "\ud83d\udecd\ufe0f Update Shopify",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\ud83d\uded2 Update WooCommerce",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udecd\ufe0f Fetch Shopify Inventory": {
      "main": [
        [
          {
            "node": "\ud83d\udd00 Merge All Platform Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\uded2 Fetch WooCommerce Inventory": {
      "main": [
        [
          {
            "node": "\ud83d\udd00 Merge All Platform Data",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "\u23f0 Hourly Reconciliation Trigger": {
      "main": [
        [
          {
            "node": "\ud83d\udcdd Parse Trigger Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd0d Compare & Identify Discrepancies": {
      "main": [
        [
          {
            "node": "\u2753 Has Discrepancies?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}