{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "ff5e8a30-7c98-4a57-912d-d237d93e9b77",
      "name": "Webhook Trigger",
      "type": "n8n-nodes-base.webhook",
      "notes": "Receives farm operations data from HTML form. Copy the production webhook URL and use it in your web form.",
      "position": [
        -848,
        -384
      ],
      "parameters": {
        "path": "farm-operations-logger",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "lastNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "d4beaa47-e36f-4181-afe9-614c69cc6afb",
      "name": "Capture Breakdowns",
      "type": "n8n-nodes-base.googleSheets",
      "notes": "Writes breakdown/downtime records to the 'breakdowns' sheet",
      "position": [
        80,
        -352
      ],
      "parameters": {
        "columns": {
          "value": {
            "id": "={{ $json.id }}",
            "type": "={{ $json.type }}",
            "notes": "={{ $json.breakdown.notes }}",
            "end time": "={{ $json.endTime }}",
            "start time": "={{ $json.startTime }}",
            "total downtime": "={{ $json.totalDowntime }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "type",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "type",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "start time",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "start time",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "end time",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "end time",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "total downtime",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "total downtime",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "notes",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "notes",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "breakdowns"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_SPREADSHEET_ID_HERE"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "8ff6382c-b471-4fbf-8339-e8c921f5f7a6",
      "name": "Main Log Capture Node",
      "type": "n8n-nodes-base.googleSheets",
      "notes": "Writes complete operation record to the 'main_logs' sheet",
      "position": [
        80,
        -128
      ],
      "parameters": {
        "columns": {
          "value": {
            "id": "={{ $json.body.id }}",
            "date": "={{ $json.body.date }}",
            "field": "={{ $json.body.field }}",
            "end time": "={{ $json.body.endTime }}",
            "operator": "={{ $json.body.operator }}",
            "machinery": "={{ $json.body.machinery }}",
            "operation": "={{ $json.body.operation }}",
            "timestamp": "={{ $json.body.timestamp }}",
            "breakdowns": "={{ $json.body.breakdowns }}",
            "start time": "={{ $json.body.startTime }}",
            "supervisor": "={{ $json.body.supervisor }}",
            "total hours": "={{ $json.body.totalHours }}",
            "value/units": "={{ $json.body.operationOutput.value }} {{ $json.body.operationOutput.unit }}",
            "fuel entries": "={{ $json.body.fuelEntries }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "timestamp",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "date",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "operator",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "operator",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "supervisor",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "supervisor",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "start time",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "start time",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "end time",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "end time",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "total hours",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "total hours",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "machinery",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "machinery",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "field",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "field",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "operation",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "operation",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "value/units",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "value/units",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "fuel entries",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "fuel entries",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "breakdowns",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "breakdowns",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "main_logs"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_SPREADSHEET_ID_HERE"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "429281d7-9104-4b5f-9e55-75edab9b0f69",
      "name": "Fuel Capture Log",
      "type": "n8n-nodes-base.googleSheets",
      "notes": "Writes fuel consumption data to the 'fuel' sheet",
      "position": [
        64,
        -576
      ],
      "parameters": {
        "columns": {
          "value": {
            "id": "={{ $json.id }}",
            "litre": "={{ $('Workflow Configuration').item.json.body.fuelEntries[0].litres }}",
            "mach-end": "={{ $('Workflow Configuration').item.json.body.fuelEntries[0].machineryHoursEnd }}",
            "supplier": "={{ $('Workflow Configuration').item.json.body.fuelEntries[0].supplier }}",
            "attendant": "={{ $('Workflow Configuration').item.json.body.fuelEntries[0].attendant }}",
            "mach-start": "={{ $('Workflow Configuration').item.json.body.fuelEntries[0].machineryHoursStart }}"
          },
          "schema": [
            {
              "id": "id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "id",
              "defaultMatch": true,
              "canBeUsedToMatch": true
            },
            {
              "id": "mach-start",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "mach-start",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "mach-end",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "mach-end",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "litre",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "litre",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "attendant",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "attendant",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "supplier",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "supplier",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "fuel"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_SPREADSHEET_ID_HERE"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "1593e048-49bb-43cd-a40d-22532aad6799",
      "name": "Expand Fuel Entries",
      "type": "n8n-nodes-base.code",
      "notes": "Transforms fuel entries array into individual items for separate sheet rows",
      "position": [
        -272,
        -576
      ],
      "parameters": {
        "jsCode": "// Loop through fuelEntries array and create one item per fuel entry with the log ID\nconst items = [];\n\nfor (const item of $input.all()) {\n  const logId = item.json.body.id;\n  const fuelEntries = item.json.body.fuelEntries || [];\n  \n  for (const fuelEntry of fuelEntries) {\n    items.push({\n      json: {\n        id: logId,\n        machineryHours: fuelEntry.machineryHours,\n        litres: fuelEntry.litres,\n        attendant: fuelEntry.attendant\n      }\n    });\n  }\n}\n\nreturn items;"
      },
      "typeVersion": 2
    },
    {
      "id": "2895c5b3-8746-44ae-a689-13de76e98428",
      "name": "Expand Breakdowns",
      "type": "n8n-nodes-base.code",
      "notes": "Transforms breakdowns array into individual items for separate sheet rows",
      "position": [
        -240,
        -352
      ],
      "parameters": {
        "jsCode": "// Loop through breakdowns array and create one item per breakdown with the log ID\nconst items = [];\n\nfor (const item of $input.all()) {\n  const logId = item.json.body.id;\n  const breakdowns = item.json.body.breakdowns || [];\n  \n  for (const breakdown of breakdowns) {\n    items.push({\n      json: {\n        id: logId,\n        breakdown: breakdown,\n        type: breakdown.type,\n        startTime: breakdown.startTime,\n        endTime: breakdown.endTime,\n        totalDowntime: breakdown.totalDowntime\n      }\n    });\n  }\n}\n\nreturn items;"
      },
      "typeVersion": 2
    },
    {
      "id": "8580fa54-9d40-49d7-9ef6-a40a211889ef",
      "name": "Workflow Configuration",
      "type": "n8n-nodes-base.set",
      "notes": "IMPORTANT: Replace YOUR_SPREADSHEET_ID_HERE with your actual Google Sheets ID",
      "position": [
        -592,
        -384
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "spreadsheetId",
              "type": "string",
              "value": "YOUR_SPREADSHEET_ID_HERE"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "1a5e1949-86e1-4a43-bbb3-7767e276694a",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1552,
        -848
      ],
      "parameters": {
        "width": 544,
        "height": 688,
        "content": "## OPERATOR-SPECIFIC FARM OPERATIONS LOGGER\n\nCaptures detailed farm machinery operations data via webhook and logs to three Google Sheets tabs: main operations, fuel consumption, and equipment breakdowns.\n\nSETUP CHECKLIST:\n\u25a1 Create Google Sheet with 3 tabs: main_logs, fuel, breakdowns\n\u25a1 Add column headers to each tab (see documentation)\n\u25a1 Import workflow into n8n\n\u25a1 Set up Google Sheets OAuth2 credentials\n\u25a1 Update spreadsheet ID in Workflow Configuration node\n\u25a1 Update Document field in all 3 Google Sheets nodes\n\u25a1 Test webhook with sample payload\n\u25a1 Activate workflow\n\u25a1 Update data collection app with Production URL\n\nWEBHOOK PATH: GET THIS FROM WEBHOOK TRIGGER\nMETHOD: POST\nCONTENT-TYPE: application/json"
      },
      "typeVersion": 1
    },
    {
      "id": "913f580c-0727-4030-8ef4-3a441167c2e5",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -928,
        -848
      ],
      "parameters": {
        "color": 7,
        "height": 624,
        "content": "## WEBHOOK TRIGGER\nReceives POST requests from data collection app\nPath: farm-operations-logger\nAccepts JSON payload with operation details\n\u2192 Passes to Workflow Configuration"
      },
      "typeVersion": 1
    },
    {
      "id": "563bf9f7-510b-4875-b2ae-e27a0c9eb869",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -656,
        -848
      ],
      "parameters": {
        "color": 7,
        "width": 224,
        "height": 624,
        "content": "## WORKFLOW CONFIGURATION\nCentral node that:\n- Stores spreadsheet ID for reference\n- Splits data flow to 3 branches:\n  1. Main log (direct)\n  2. Fuel entries (via expansion)\n  3. Breakdowns (via expansion)\n\u2192 Update spreadsheetId value here!"
      },
      "typeVersion": 1
    },
    {
      "id": "e4e692a0-dede-40e9-b847-25cc48f0828b",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -336,
        -848
      ],
      "parameters": {
        "color": 7,
        "height": 256,
        "content": "## EXPAND FUEL ENTRIES\nCode node that loops through fuelEntries array\nCreates one item per fuel entry with log ID\nHandles multiple fuel fills per operation\n\u2192 Each fuel entry becomes separate row"
      },
      "typeVersion": 1
    },
    {
      "id": "733d329c-30a1-4597-8a4a-4937bc05871c",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        272,
        -592
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "content": "## FUEL CAPTURE LOG\nWrites to \"fuel\" sheet tab\nColumns: id, mach-start, mach-end, litre, attendant, supplier\n\u26a0\ufe0f Update Document to your spreadsheet\n\u26a0\ufe0f Ensure \"fuel\" tab exists"
      },
      "typeVersion": 1
    },
    {
      "id": "fb48e538-cd6c-4dac-88d4-b37998e47b34",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        288,
        -144
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 224,
        "content": "## MAIN LOG CAPTURE NODE\nWrites to \"main_logs\" sheet tab\nCaptures primary operation data:\n- Operator, machinery, field, operation\n- Start/end times, total hours\n- Operation output (value/units)\n\u26a0\ufe0f Update Document to your spreadsheet\n\u26a0\ufe0f Ensure \"main_logs\" tab exists"
      },
      "typeVersion": 1
    },
    {
      "id": "9fbc3803-56fd-4025-9680-dea97dde81d1",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -448,
        -176
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 208,
        "content": "## EXPAND BREAKDOWNS\nCode node that loops through breakdowns array\nCreates one item per breakdown with log ID\nIncludes: type, start/end times, downtime, notes\n\u2192 Each breakdown becomes separate row"
      },
      "typeVersion": 1
    },
    {
      "id": "77e1ba97-4211-43e9-b8d5-5a30893b03cd",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        272,
        -368
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "content": "## CAPTURE BREAKDOWNS\nWrites to \"breakdowns\" sheet tab\nColumns: id, type, start time, end time, total downtime, notes\n\u26a0\ufe0f Update Document to your spreadsheet\n\u26a0\ufe0f Ensure \"breakdowns\" tab exists"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Webhook Trigger": {
      "main": [
        [
          {
            "node": "Workflow Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Expand Breakdowns": {
      "main": [
        [
          {
            "node": "Capture Breakdowns",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Expand Fuel Entries": {
      "main": [
        [
          {
            "node": "Fuel Capture Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Workflow Configuration": {
      "main": [
        [
          {
            "node": "Main Log Capture Node",
            "type": "main",
            "index": 0
          },
          {
            "node": "Expand Fuel Entries",
            "type": "main",
            "index": 0
          },
          {
            "node": "Expand Breakdowns",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}