{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "9db0da1b-8007-4d83-9c20-b321e536ce40",
      "name": "searchPeriod",
      "type": "n8n-nodes-base.set",
      "position": [
        1680,
        420
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0b297449-7eb1-4a02-adff-7c1c82888532",
              "name": "startDay",
              "type": "string",
              "value": "={{$now.plus({ days: -30 }).toFormat('yyyy-MM-dd')}}"
            },
            {
              "id": "c85e7afa-0a73-473f-a7ae-93b88db7a717",
              "name": "endDay",
              "type": "string",
              "value": "={{$now.toFormat('yyyy-MM-dd')}}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "47a8c0a7-9eac-4406-90c0-3e27962df533",
      "name": "getOrderDoLoop",
      "type": "n8n-nodes-base.graphql",
      "position": [
        1940,
        420
      ],
      "parameters": {
        "query": "={\n  orders(\n    first: 250\n    {{ $json.data.orders.pageInfo.endCursor ? ', after: \"' + $json.data.orders.pageInfo.endCursor + '\"' : '' }}\n    query: \"created_at:>={{ $('searchPeriod').item.json.startDay }} AND created_at:<={{ $('searchPeriod').item.json.endDay }}\"\n  ) {\n    edges {\n      node {\n        id\n        createdAt\n        lineItems(first: 250) {\n          edges {\n            node {\n              product {\n                title\n                vendor\n              }\n              quantity\n              originalUnitPriceSet {\n                shopMoney {\n                  amount\n                  currencyCode\n                }\n              }\n              variant {\n                title\n              }\n              sku\n            }\n          }\n        }\n      }\n    }\n    pageInfo {\n      hasNextPage\n      endCursor\n    }\n  }\n}\n",
        "endpoint": "https://lokal-eg.myshopify.com/admin/api/2025-01/graphql.json",
        "authentication": "headerAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": false,
      "retryOnFail": true,
      "typeVersion": 1.1,
      "waitBetweenTries": 5000
    },
    {
      "id": "ee8fefc3-608e-4700-a46c-6d82dcac91c0",
      "name": "is hasNextPage = true",
      "type": "n8n-nodes-base.if",
      "position": [
        2160,
        420
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "94cefe62-8334-438a-83d9-9cbde31ae72c",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.data.orders.pageInfo.hasNextPage }}",
              "rightValue": "true"
            }
          ]
        }
      },
      "retryOnFail": true,
      "typeVersion": 2.2
    },
    {
      "id": "fbd86310-fbe4-4033-884b-6936d70f6fc2",
      "name": "groupItemListbyVendor",
      "type": "n8n-nodes-base.code",
      "position": [
        2420,
        440
      ],
      "parameters": {
        "jsCode": "// Gather all executions from getOrderDoLoop\nlet allOrders = [];\nlet counter = 0;\nwhile (true) {\n  try {\n    const items = $items(\"getOrderDoLoop\", 0, counter);\n    allOrders.push(...items);\n  } catch (e) {\n    break;\n  }\n  counter++;\n}\n\n// Flatten all line items into array\nconst allLineItems = [];\nfor (const item of allOrders) {\n  const edges = item.json.data.orders.edges || [];\n  for (const order of edges) {\n    const orderId = order.node.id.replace(\"gid://shopify/Order/\", \"\");\n    const orderDate = order.node.createdAt.split(\"T\")[0];\n    const lineItems = order.node.lineItems.edges;\n    for (const li of lineItems) {\n      allLineItems.push({\n        order_id: orderId,\n        order_date: orderDate,\n        product_title: li.node.product?.title || \"\",\n        vendor: li.node.product?.vendor || \"\",\n        sku: li.node.sku || \"\",\n        variant_name: li.node.variant?.title || \"\",\n        quantity: li.node.quantity || 0,\n        price: li.node.originalUnitPriceSet?.shopMoney?.amount || 0,\n        currency: li.node.originalUnitPriceSet?.shopMoney?.currencyCode || \"\"\n      });\n    }\n  }\n}\n\n// Group by SKU for summary (optional, comment out to send every line)\nconst summary = {};\nfor (const row of allLineItems) {\n  if (!row.sku) continue;\n  if (!summary[row.sku]) {\n    summary[row.sku] = {\n      SKU: row.sku,\n      Title: row.product_title,\n      Brand: row.vendor,\n      total_quantity_sold: 0,\n      total_sales: 0\n    };\n  }\n  summary[row.sku].total_quantity_sold += row.quantity;\n  summary[row.sku].total_sales += row.quantity * parseFloat(row.price);\n}\n\nreturn Object.values(summary).map(row => ({json: row}));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "9c26334c-36b7-4d6d-9c8b-78ec9b362382",
      "name": "Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2640,
        440
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "Brand",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Brand",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SKU",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "SKU",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Title",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "total_quantity_sold",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "total_quantity_sold",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "total_sales",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "total_sales",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1ZEm8zyl__E59M6kD9UkvHHZTMbEWktjoH3FrYhBg6LU/edit#gid=0",
          "cachedResultName": "Dump"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "1ZEm8zyl__E59M6kD9UkvHHZTMbEWktjoH3FrYhBg6LU"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "ae7b35ca-74bd-4e3b-bc06-f1758582a8c4",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        1380,
        400
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 8,
              "triggerAtMinute": 43
            }
          ]
        }
      },
      "typeVersion": 1.2
    }
  ],
  "connections": {
    "searchPeriod": {
      "main": [
        [
          {
            "node": "getOrderDoLoop",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "getOrderDoLoop": {
      "main": [
        [
          {
            "node": "is hasNextPage = true",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "searchPeriod",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "groupItemListbyVendor": {
      "main": [
        [
          {
            "node": "Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "is hasNextPage = true": {
      "main": [
        [
          {
            "node": "getOrderDoLoop",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "groupItemListbyVendor",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}