{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "af991423-1760-4a50-aee3-e090ff436eaf",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1340,
        -80
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "months",
              "triggerAtHour": 8
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "99a30399-cc1c-4687-bc32-607a89815326",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        -740,
        -80
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "61173acd-0f6c-4dd6-9cdf-bc8f166d6c63",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.items.length }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "f3161640-ce57-4439-ab03-3b4859d5e5db",
      "name": "Fetch Orders since 1 year ago",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -920,
        -80
      ],
      "parameters": {
        "url": "=https://magekwik.com/rest/V1/orders?searchCriteria[filter_groups][0][filters][0][field]=created_at&searchCriteria[filter_groups][0][filters][0][value]={{$json[\"sixMonthsAgo\"]}} 00:00:00&searchCriteria[filter_groups][0][filters][0][condition_type]=gteq&searchCriteria[pageSize]=0",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "6b053d22-682d-4fae-9569-4eb51d838163",
      "name": "Calculate date an year ago (ISO)",
      "type": "n8n-nodes-base.code",
      "position": [
        -1140,
        -80
      ],
      "parameters": {
        "jsCode": "const date = new Date();\ndate.setMonth(date.getMonth() - 12);\nreturn [{ json: { sixMonthsAgo: date.toISOString().split('T')[0] } }];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "34243a56-cab5-40a8-85f7-fd3229058760",
      "name": "Extract Sold SKUs from orders",
      "type": "n8n-nodes-base.code",
      "position": [
        -440,
        -80
      ],
      "parameters": {
        "jsCode": "const soldSkusSet = new Set();\n// orders response is in items\nconst orders = items[0].json.items || [];\n\norders.forEach(order => {\n  if (order.items && Array.isArray(order.items)) {\n    order.items.forEach(item => {\n      if(item.sku) soldSkusSet.add(item.sku);\n    });\n  }\n});\n\nreturn [{ json: { soldSkus: Array.from(soldSkusSet) } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "91bfa661-893f-4940-84b4-a3f61bb098c0",
      "name": "Get All Product Skus",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -220,
        -80
      ],
      "parameters": {
        "url": "=https://magekwik.com/rest/V1/products?searchCriteria[pageSize]=0",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "ad8c0611-3465-4b0e-bc99-6c8eb4cdb304",
      "name": "Filter products NOT sold in last year",
      "type": "n8n-nodes-base.code",
      "position": [
        0,
        -80
      ],
      "parameters": {
        "jsCode": "const allProducts =  $input.first().json.items || [];\nconst soldSkus = new Set($('Extract Sold SKUs from orders').first().json.soldSkus || []);\n\nconst unsoldProducts = allProducts.filter(product => {\n  return !soldSkus.has(product.sku);\n});\n\nreturn [{\n  json: {\n    unsold: unsoldProducts\n  }\n}];\n//return unsoldProducts.map(product => ({ json: product }));"
      },
      "typeVersion": 2
    },
    {
      "id": "7b2f1534-4a11-4d8e-a69f-b13cbcf82660",
      "name": "Gmail User for Approval",
      "type": "n8n-nodes-base.gmail",
      "position": [
        -1300,
        160
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "=The following products have recorded zero sales over the past 12 months. To optimise inventory, we propose disabling these items in our system.\n\nNext Steps:\n\nApprove: If you agree to remove these items from active inventory.\nDecline: If you wish to retain them for sale.\n\nPlease review the list and advise on your decision within 30 minutes. Thank you for your prompt attention.\n\nBest regards,\n\n{{ $json.htmlBody }}\n",
        "options": {
          "appendAttribution": false
        },
        "subject": "=Approve disabling {{ $json.count }} unsold products ",
        "operation": "sendAndWait",
        "approvalOptions": {
          "values": {
            "approvalType": "double"
          }
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "f0a9aac6-cc5f-4905-9016-e6e46463f2f7",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -440,
        160
      ],
      "parameters": {
        "options": {
          "reset": false
        }
      },
      "typeVersion": 3,
      "alwaysOutputData": false
    },
    {
      "id": "3949b0fc-2a0b-4f71-9301-221c121b0f93",
      "name": "If1",
      "type": "n8n-nodes-base.if",
      "position": [
        -1140,
        160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "a5d805ae-81cd-42e9-a4ef-5e41f7c1960b",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.data.approved }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "bd82188f-6ad7-4c47-a1ba-8bf7ca468c95",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        -920,
        160
      ],
      "parameters": {
        "mode": "chooseBranch",
        "useDataOfInput": 2
      },
      "typeVersion": 3.2
    },
    {
      "id": "081eb734-de23-4988-9faa-c65e4f09db13",
      "name": "Split Out",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -740,
        160
      ],
      "parameters": {
        "options": {},
        "fieldToSplitOut": "unsold"
      },
      "typeVersion": 1
    },
    {
      "id": "c0bf16d9-6aa9-40e8-9053-98e5c5fb912e",
      "name": "Disable Products",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -180,
        400
      ],
      "parameters": {
        "url": "=https://magekwik.com/rest/default/V1/products/{{ $json.sku }}",
        "method": "PUT",
        "options": {},
        "jsonBody": "{\n  \"product\": {\n    \"status\": 1\n  }\n}\n",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "typeVersion": 4.2
    },
    {
      "id": "088874ad-4ed2-4005-a5e9-3ce76ab7c8cf",
      "name": "Send a message",
      "type": "n8n-nodes-base.gmail",
      "position": [
        220,
        140
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "=The following  {{ $json.count }} products have been disabled.\n\n{{ $json.htmlBody }}",
        "options": {
          "appendAttribution": false
        },
        "subject": "={{ $json.count }} products have been deactivated"
      },
      "typeVersion": 2.1
    },
    {
      "id": "b4abc4dc-ca5b-41a7-bcad-ec842c348574",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        -160,
        160
      ],
      "parameters": {
        "include": "specifiedFields",
        "options": {},
        "aggregate": "aggregateAllItemData",
        "fieldsToInclude": "sku,name,price,status"
      },
      "typeVersion": 1
    },
    {
      "id": "9523619b-b2ca-43f0-b045-f68379eada33",
      "name": "Built Reporting Email",
      "type": "n8n-nodes-base.code",
      "position": [
        40,
        140
      ],
      "parameters": {
        "jsCode": "const headers = ['sku', 'name', 'price', 'status'];\n\nconst unsold = $input.first().json.data || [];\n\n// Start the HTML table\nlet html = `<table border=\"1\" cellpadding=\"6\" cellspacing=\"0\" style=\"border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px;\">`;\n\n// Add table header\nhtml += '<tr style=\"background-color: #f2f2f2;\">' + headers.map(h => `<th>${h}</th>`).join('') + '</tr>';\n\n// Add rows\nfor (const product of unsold) {\n  html += '<tr>' + headers.map(field => {\n    const value = product[field] ?? '';\n    return `<td>${String(value).replace(/</g, '&lt;').replace(/>/g, '&gt;')}</td>`;\n  }).join('') + '</tr>';\n}\n\n// Close table\nhtml += '</table>';\n\nreturn [{\n  json: {\n    htmlBody: html,\n    count: unsold.length,\n    subject: `Unsold Products Report (${unsold.length})`\n  }\n}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "affccc45-e966-4952-9136-2f19b82ac61d",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1380,
        -220
      ],
      "parameters": {
        "color": 7,
        "width": 840,
        "height": 300,
        "content": "                              Fetches All Ordered SKUS last 1 Year\n"
      },
      "typeVersion": 1
    },
    {
      "id": "bce6fc94-f30f-479e-8d4a-dcd946ed5e0b",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -500,
        -220
      ],
      "parameters": {
        "color": 6,
        "width": 840,
        "height": 300,
        "content": "                              Filters All UnOrders SKUS last 1 Year\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e24162fe-a07b-422c-9417-09ac72fbb534",
      "name": "Build Decision Email",
      "type": "n8n-nodes-base.code",
      "position": [
        220,
        -80
      ],
      "parameters": {
        "jsCode": "const headers = ['sku', 'name', 'price', 'status'];\n\nconst unsold = $json.unsold || [];\n\n// Start the HTML table\nlet html = `<table border=\"1\" cellpadding=\"6\" cellspacing=\"0\" style=\"border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px;\">`;\n\n// Add table header\nhtml += '<tr style=\"background-color: #f2f2f2;\">' + headers.map(h => `<th>${h}</th>`).join('') + '</tr>';\n\n// Add rows\nfor (const product of unsold) {\n  html += '<tr>' + headers.map(field => {\n    const value = product[field] ?? '';\n    return `<td>${String(value).replace(/</g, '&lt;').replace(/>/g, '&gt;')}</td>`;\n  }).join('') + '</tr>';\n}\n\n// Close table\nhtml += '</table>';\n\nreturn [{\n  json: {\n    htmlBody: html,\n    count: unsold.length,\n    subject: `Unsold Products Report (${unsold.length})`\n  }\n}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "cccc4f30-ad84-472a-8c05-8f52c5692f31",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1380,
        100
      ],
      "parameters": {
        "color": 5,
        "width": 840,
        "height": 280,
        "content": "                              \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                              If Approved, Processes the Data\n"
      },
      "typeVersion": 1
    },
    {
      "id": "689407c1-c09c-44d0-a162-e42cb48aac93",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -500,
        100
      ],
      "parameters": {
        "color": 4,
        "width": 840,
        "height": 500,
        "content": "                              \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n                               Disable Products and Reports via email\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b6051a73-aa8e-405e-aaaa-bbf444856a2f",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1380,
        -460
      ],
      "parameters": {
        "width": 1720,
        "height": 220,
        "content": "# Magento 2 Inventory Cleanup: Disable Unsold Stale Products After 1 Year with Approval\n\n## This workflow is designed for merchants who want to automatically identify and deactivate products that haven't been sold in the past 12 months, helping to maintain a clean and optimized catalog. The automation includes order analysis, product comparison, management approval, and automated product deactivation, with full reporting and transparency."
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Extract Sold SKUs from orders",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If1": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "Built Reporting Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Disable Products",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Disable Products": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Calculate date an year ago (ISO)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Decision Email": {
      "main": [
        [
          {
            "node": "Gmail User for Approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get All Product Skus": {
      "main": [
        [
          {
            "node": "Filter products NOT sold in last year",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Built Reporting Email": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail User for Approval": {
      "main": [
        [
          {
            "node": "If1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Sold SKUs from orders": {
      "main": [
        [
          {
            "node": "Get All Product Skus",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Orders since 1 year ago": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate date an year ago (ISO)": {
      "main": [
        [
          {
            "node": "Fetch Orders since 1 year ago",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter products NOT sold in last year": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          },
          {
            "node": "Build Decision Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}