{
  "id": "yaudVbewTA3Zxsb4",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Automated Invoice Creator & Payment Reminder Bot for Clients",
  "tags": [],
  "nodes": [
    {
      "id": "d75d7591-4afa-427c-b436-ada9d8eb90dc",
      "name": "Monthly Invoice Trigger",
      "type": "n8n-nodes-base.cron",
      "position": [
        -180,
        -180
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "442fcd9c-dcff-4b5f-8d3e-17823048e40a",
      "name": "Daily Payment Reminder Check",
      "type": "n8n-nodes-base.cron",
      "position": [
        -180,
        380
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "e291b555-c948-48c4-b5a8-0e39b4c16e0b",
      "name": "Get Clients for Invoicing",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        40,
        -180
      ],
      "parameters": {
        "options": {},
        "sheetName": "Clients",
        "documentId": "YOUR_GOOGLE_SHEET_ID",
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "d17d13ca-cf7b-42a2-8c0a-c41858b936ec",
      "name": "Get Overdue Invoices",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        40,
        380
      ],
      "parameters": {
        "options": {},
        "sheetName": "Invoices",
        "documentId": "YOUR_GOOGLE_SHEET_ID",
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "b7838069-c5ef-4a6b-8003-f976f5952c55",
      "name": "Filter Active Clients",
      "type": "n8n-nodes-base.code",
      "position": [
        260,
        -180
      ],
      "parameters": {
        "jsCode": "// Filter active clients ready for invoicing\nconst allClients = $input.all();\nconst today = new Date();\ntoday.setHours(0, 0, 0, 0);\n\nconst clientsToInvoice = allClients.filter(item => {\n  const client = item.json;\n  // Skip header row\n  if (client.A === 'client_id' || !client.A) return false;\n  \n  const status = client.F; // Column F = status\n  const billingDate = new Date(client.E); // Column E = billing_date\n  billingDate.setHours(0, 0, 0, 0);\n  \n  return status === 'active' && billingDate <= today;\n});\n\n// Transform to readable format\nconst transformedClients = clientsToInvoice.map(item => {\n  const client = item.json;\n  return {\n    json: {\n      client_id: client.A,\n      client_name: client.B,\n      email: client.C,\n      service_description: client.D,\n      billing_date: client.E,\n      status: client.F,\n      amount: parseFloat(client.G) || 0\n    }\n  };\n});\n\nreturn transformedClients;"
      },
      "typeVersion": 2
    },
    {
      "id": "66d888dd-020c-4d3b-845b-f93cd867e6a8",
      "name": "Filter Overdue Invoices",
      "type": "n8n-nodes-base.code",
      "position": [
        260,
        380
      ],
      "parameters": {
        "jsCode": "// Filter overdue invoices\nconst allInvoices = $input.all();\nconst today = new Date();\ntoday.setHours(0, 0, 0, 0);\n\nconst overdueInvoices = allInvoices.filter(item => {\n  const invoice = item.json;\n  // Skip header row\n  if (invoice.A === 'invoice_id' || !invoice.A) return false;\n  \n  const status = invoice.G; // Column G = status\n  const dueDate = new Date(invoice.F); // Column F = due_date\n  dueDate.setHours(0, 0, 0, 0);\n  \n  // Get yesterday's date\n  const yesterday = new Date(today);\n  yesterday.setDate(yesterday.getDate() - 1);\n  \n  return status === 'pending' && dueDate <= yesterday;\n});\n\n// Transform to readable format\nconst transformedInvoices = overdueInvoices.map(item => {\n  const invoice = item.json;\n  return {\n    json: {\n      invoice_id: invoice.A,\n      invoice_number: invoice.B,\n      client_name: invoice.C,\n      email: invoice.D,\n      amount: parseFloat(invoice.E) || 0,\n      due_date: invoice.F,\n      status: invoice.G,\n      last_reminder_sent: invoice.H,\n      reminder_count: parseInt(invoice.I) || 0\n    }\n  };\n});\n\nreturn transformedInvoices;"
      },
      "typeVersion": 2
    },
    {
      "id": "0253a4de-ca69-4dd0-9c75-7bb686d296be",
      "name": "Generate Invoice Data",
      "type": "n8n-nodes-base.code",
      "position": [
        480,
        -180
      ],
      "parameters": {
        "jsCode": "// Generate invoice number\nconst now = new Date();\nconst invoiceNumber = `INV-${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}-${String(Math.floor(Math.random() * 1000)).padStart(3, '0')}`;\n\n// Calculate due date (30 days from now)\nconst dueDate = new Date();\ndueDate.setDate(dueDate.getDate() + 30);\n\n// Get client data\nconst clientData = $input.first().json;\n\n// Create invoice data\nconst invoiceData = {\n  invoice_number: invoiceNumber,\n  client_id: clientData.client_id,\n  client_name: clientData.client_name,\n  email: clientData.email,\n  service_description: clientData.service_description,\n  amount: clientData.amount,\n  issue_date: now.toISOString().split('T')[0],\n  due_date: dueDate.toISOString().split('T')[0],\n  status: 'pending'\n};\n\nreturn { json: invoiceData };"
      },
      "typeVersion": 2
    },
    {
      "id": "b2bebed5-0a36-4d7f-9ae1-ce5aeb17803d",
      "name": "Save Invoice to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        700,
        -180
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": "Invoices",
        "documentId": "YOUR_GOOGLE_SHEET_ID",
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "d22a9ad6-41a6-4601-9fe4-6bb194854fbd",
      "name": "Send Invoice Email",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        920,
        -180
      ],
      "parameters": {
        "text": "={{ $json.result }}",
        "options": {
          "allowUnauthorizedCerts": true
        },
        "subject": "New Invoice - {{ $json.invoice_number }}",
        "toEmail": "={{ $json.email }}",
        "fromEmail": "user@example.com"
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "bb3d4b79-3a7e-4d7a-914a-4dbd85a8bca3",
      "name": "Calculate Reminder Type",
      "type": "n8n-nodes-base.code",
      "position": [
        480,
        380
      ],
      "parameters": {
        "jsCode": "// Calculate days overdue\nconst dueDate = new Date($json.due_date);\nconst today = new Date();\nconst daysOverdue = Math.floor((today - dueDate) / (1000 * 60 * 60 * 24));\n\n// Determine reminder type based on days overdue\nlet reminderType = 'gentle';-\nlet subject = 'Payment Reminder';\n\nif (daysOverdue >= 30) {\n  reminderType = 'final';\n  subject = 'FINAL NOTICE - Payment Required';\n} else if (daysOverdue >= 14) {\n  reminderType = 'urgent';\n  subject = 'URGENT - Payment Overdue';\n} else if (daysOverdue >= 7) {\n  reminderType = 'follow-up';\n  subject = 'Payment Follow-up Required';\n}\n\nreturn {\n  json: {\n    ...($json),\n    days_overdue: daysOverdue,\n    reminder_type: reminderType,\n    email_subject: subject\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "8eacfac6-b3f0-41f8-9d45-6587f3f59333",
      "name": "Switch Reminder Type",
      "type": "n8n-nodes-base.switch",
      "position": [
        700,
        359
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "613ef87a-e0f6-45ee-9347-9db597b7dbf9",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json.reminder_type}}",
                    "rightValue": "gentle"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "7c82cc7e-9659-48e8-9143-bc3bca67c8f4",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json.reminder_type}}",
                    "rightValue": "follow-up"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "66f7c6ba-5f18-4290-84c3-1ab9de84ef21",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json.reminder_type}}",
                    "rightValue": "urgent"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "6e481655-1f66-4b4c-9717-3564e811ace6",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json.reminder_type}}",
                    "rightValue": "final"
                  }
                ]
              }
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "aa11ccd1-090e-4544-8c89-1957368268ff",
      "name": "Send Gentle Reminder",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        920,
        80
      ],
      "parameters": {
        "options": {},
        "subject": "={{ $json.email_subject }} - Invoice {{ $json.invoice_id }}",
        "toEmail": "={{ $json.email }}",
        "fromEmail": "user@example.com"
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "aa04fbde-36fc-4c9d-bc0e-ef3725de3879",
      "name": "Send Follow-up Reminder",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        920,
        280
      ],
      "parameters": {
        "options": {},
        "subject": "={{ $json.email_subject }} - Invoice {{ $json.invoice_id }}",
        "toEmail": "={{ $json.email }}",
        "fromEmail": "user@example.com"
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "da991ec5-fa55-4cbb-8fe2-d9ee1f231ca1",
      "name": "Send Urgent Reminder",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        920,
        480
      ],
      "parameters": {
        "options": {},
        "subject": "={{ $json.email_subject }} - Invoice {{ $json.invoice_id }}",
        "toEmail": "={{ $json.email }}",
        "fromEmail": "user@example.com"
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "03806211-8278-4e6e-9aa3-9511ae7b2d6a",
      "name": "Send Final Notice",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        920,
        680
      ],
      "parameters": {
        "options": {},
        "subject": "={{ $json.email_subject }} - Invoice {{ $json.invoice_id }}",
        "toEmail": "={{ $json.email }}",
        "fromEmail": "user@example.com"
      },
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "b8d9735c-cf50-4b4e-b913-f21093e68dc2",
      "name": "Update Reminder Log",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1140,
        380
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": "Invoices",
        "documentId": "YOUR_GOOGLE_SHEET_ID",
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "11ef4edf-e5d2-4f0a-874c-af270b75b338",
      "name": "Log Invoice Creation",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1140,
        -180
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": "Activity_Log",
        "documentId": "YOUR_GOOGLE_SHEET_ID",
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4
    },
    {
      "id": "b41db4f5-4b6a-481a-b7ef-60028e651eff",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        100,
        -620
      ],
      "parameters": {
        "width": 760,
        "height": 340,
        "content": "## Invoice Creation Flow\n\n\n**Monthly Invoice Trigger** \u2013 Triggers workflow on a set monthly schedule.\n\n**Get Clients for Invoicing** \u2013 Reads client data from Google Sheet.\n\n**Filter Active Clients** \u2013 Filters out inactive clients.\n\n**Generate Invoice Data** \u2013 Creates invoice details in required format.\n\n**Save Invoice to Google Sheets** \u2013 Appends or updates invoice record in the sheet.\n\n**Send Invoice Email** \u2013 Sends the invoice to the client via email.\n\n**Log Invoice Creation** \u2013 Logs invoice creation for records/auditing."
      },
      "typeVersion": 1
    },
    {
      "id": "e50bfca0-4cc7-4837-a480-a29ef3d675e6",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -280,
        80
      ],
      "parameters": {
        "color": 4,
        "width": 980,
        "height": 220,
        "content": "## **Reminder Flow**\n\n**Daily Payment Reminder Check** \u2013 Triggers workflow daily to check overdue invoices.\n**Get Overdue Invoices** \u2013 Reads overdue invoices from Google Sheet.\n**Filter Overdue Invoices** \u2013 Filters invoices still unpaid.\n**Calculate Reminder Type** \u2013 Calculates how many days overdue.\n**Switch Reminder Type** \u2013 Decides which type of reminder to send.\n**Send Gentle / Follow-up / Urgent / Final Notice** \u2013 Sends respective reminder email.\n**Update Reminder Log** \u2013 Updates reminder status in the sheet."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "af210e95-bedc-44a9-ab43-8129618f3429",
  "connections": {
    "Send Final Notice": {
      "main": [
        [
          {
            "node": "Update Reminder Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Invoice Email": {
      "main": [
        [
          {
            "node": "Log Invoice Creation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Overdue Invoices": {
      "main": [
        [
          {
            "node": "Filter Overdue Invoices",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Gentle Reminder": {
      "main": [
        [
          {
            "node": "Update Reminder Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Urgent Reminder": {
      "main": [
        [
          {
            "node": "Update Reminder Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch Reminder Type": {
      "main": [
        [
          {
            "node": "Send Gentle Reminder",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Follow-up Reminder",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Urgent Reminder",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send Final Notice",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Active Clients": {
      "main": [
        [
          {
            "node": "Generate Invoice Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Invoice Data": {
      "main": [
        [
          {
            "node": "Save Invoice to Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Reminder Type": {
      "main": [
        [
          {
            "node": "Switch Reminder Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Overdue Invoices": {
      "main": [
        [
          {
            "node": "Calculate Reminder Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Monthly Invoice Trigger": {
      "main": [
        [
          {
            "node": "Get Clients for Invoicing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Follow-up Reminder": {
      "main": [
        [
          {
            "node": "Update Reminder Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Clients for Invoicing": {
      "main": [
        [
          {
            "node": "Filter Active Clients",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily Payment Reminder Check": {
      "main": [
        [
          {
            "node": "Get Overdue Invoices",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Save Invoice to Google Sheets": {
      "main": [
        [
          {
            "node": "Send Invoice Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}