Most manufacturers tracking purchase orders in a spreadsheet discover an overdue delivery one of two ways: someone on the shop floor asks where the material is, or a supplier eventually gets in touch to say there was a delay.

Neither of those is early enough.

This workflow template reads your PO tracker in Google Sheets every morning, compares each expected delivery date against today, and sends a Gmail alert listing every overdue PO: supplier name, PO number, and how many days overdue. It also writes "OVERDUE" into a status column in the sheet so the problem is visible to anyone who opens it.

No ERP. No vendor portal logins. Just a spreadsheet you already maintain and an alert that actually goes out.

What You Are Building

A scheduled n8n workflow that:

  1. Runs every morning before your team's day starts
  2. Reads your PO tracker from Google Sheets
  3. Identifies rows where the expected delivery date has passed and the status is not already closed
  4. Sends a Gmail alert to your purchasing coordinator (or a distribution list) with all overdue POs listed
  5. Writes "OVERDUE" into the status column for each flagged row so the sheet reflects current state

Prerequisites

A Google Sheet set up as a PO tracker. Your sheet needs at minimum these columns:

  • PO Number
  • Supplier Name
  • Item or Description
  • Expected Delivery Date (formatted as YYYY-MM-DD for reliable date math)
  • Status (leave blank for open POs; the workflow writes "OVERDUE" here when applicable)

Columns for order quantity, unit cost, or buyer name are fine to have: the workflow only reads and writes the five above.

n8n instance. n8n Cloud or self-hosted, version 1.0 or later.

Google Sheets credentials in n8n. In Credentials, add a Google Sheets OAuth2 credential authorized against the Google account that owns the sheet.

Gmail credentials in n8n. Add a Gmail OAuth2 credential authorized against the account you want the alert to send from. This can be a shared purchasing inbox or an individual account.

Workflow Overview

The complete node sequence:

Schedule Trigger (daily, 6:30am)
    → Google Sheets (Read all rows from PO tracker)
    → Code node (filter rows where Expected Delivery Date < today AND Status is not closed)
    → IF node (check if any overdue POs exist)
      → True: Format Alert (Code node: build the email body)
               → Gmail Send (alert to purchasing coordinator)
               → Google Sheets Update (write "OVERDUE" to status column for each flagged row)
      → False: (end, no overdue POs today)

Running at 6:30am means the alert is in your purchasing coordinator's inbox before the shop floor day starts. If material is overdue, they have time to follow up with the supplier before anyone else asks.

Step-by-Step Build

Step 1: Use n8n's AI to Generate the Starting Workflow

Before building any nodes manually, use n8n's built-in AI to generate the workflow structure. This gives you a connected starting point in seconds; you then configure credentials and refine the logic in the steps that follow.

Open n8n and create a new workflow. Click the Generate workflow button in the top-right corner of the canvas (the sparkle/AI icon), or look for the AI description bar that appears on an empty canvas.

Use this prompt:

Build a workflow that runs every morning at 6:30am. Read all rows from a Google Sheet called PO Tracker. Find rows where the Expected Delivery Date is in the past and the Status column is not "received", "closed", or "cancelled". Calculate how many days overdue each row is. Build a summary of all overdue POs with supplier name, PO number, and days overdue. Send this as a Gmail alert to the purchasing team. Then write "OVERDUE" to the Status column for each flagged row.

The AI will generate a set of connected nodes. It will not be fully configured: credentials are missing, column names are placeholders, and the Code node logic will need to be replaced with the specific JavaScript in the steps below. That is expected.

What the AI typically gets right:

  • The correct node types: Schedule Trigger, Google Sheets, Code, IF, Gmail, Google Sheets Update
  • A reasonable connection order
  • Placeholder names that match your prompt

What you will configure in the steps below:

  • Your Google Sheets and Gmail OAuth2 credentials
  • Exact column header names from your PO tracker
  • The closed status values to exclude in the Code node
  • The alert email recipient and body format

Once the AI has generated the workflow, proceed to Step 2 to configure each node.

Step 2: Add the Schedule Trigger

Create a new workflow and add a Schedule Trigger node.

Set it to run daily at 6:30am, or whatever time gives your purchasing coordinator enough lead time before the shop floor starts asking questions.

Step 3: Add the Google Sheets Node

Add a Google Sheets node after the trigger. Configure it:

  • Operation: Get Many Rows
  • Credential: Your Google Sheets OAuth2 credential
  • Spreadsheet: Your PO tracker URL
  • Sheet: The tab containing your PO data
  • Return All Rows: Enable

Run manually to confirm it returns your PO rows. Open the output panel to confirm the exact column name keys n8n is using: these must match exactly in the Code node.

Step 4: Add a Code Node to Filter Overdue POs

Add a Code node after the Google Sheets node. This node calculates how many days overdue each PO is and filters out rows that are already closed or have no date.

const items = $input.all();
const today = new Date();
today.setHours(0, 0, 0, 0);

const closedStatuses = ['received', 'closed', 'cancelled', 'overdue'];

const overdue = items
  .filter(item => {
    const status = (item.json['Status'] || '').toLowerCase().trim();
    if (closedStatuses.includes(status)) return false;

    const expectedDate = new Date(item.json['Expected Delivery Date']);
    if (isNaN(expectedDate)) return false;

    return expectedDate < today;
  })
  .map(item => {
    const expectedDate = new Date(item.json['Expected Delivery Date']);
    const daysOverdue = Math.floor((today - expectedDate) / (1000 * 60 * 60 * 24));
    return {
      json: {
        ...item.json,
        daysOverdue,
        rowNumber: item.json._rowNumber // n8n includes this for Sheets update
      }
    };
  });

return overdue;

Adjust 'Status' and 'Expected Delivery Date' to match your exact column headers. The closedStatuses array lists values that should be excluded: add any status labels your team uses to mark a PO as resolved.

The daysOverdue field is calculated here and used in the email alert body. The _rowNumber field is passed through for the Google Sheets Update node in Step 8: n8n adds this automatically when reading from Sheets, so it will be available in item.json.

Step 5: Add an IF Node to Handle No Results

Add an IF node after the Code node.

Configure the condition:

  • Value 1: {{ $items().length }}
  • Condition: Greater than
  • Value 2: 0

Connect the True branch to the Format Alert node. Leave the False branch unconnected: when there are no overdue POs, the workflow ends quietly.

Step 6: Add a Format Alert Code Node

Add a Code node on the True branch. Name it Format Alert. This node assembles the list of overdue POs into a single email body string.

const items = $input.all();
const today = new Date().toISOString().split('T')[0];

const lines = items.map(item => {
  const { 'PO Number': po, 'Supplier Name': supplier, 'Item or Description': desc, 'Expected Delivery Date': date, daysOverdue } = item.json;
  return `PO ${po}: ${supplier}: ${desc}\n  Expected: ${date} (${daysOverdue} day${daysOverdue === 1 ? '' : 's'} overdue)`;
});

const count = items.length;
const subject = `Overdue PO Alert: ${count} purchase order${count === 1 ? '' : 's'} past expected delivery: ${today}`;
const body = `The following purchase orders have passed their expected delivery date:\n\n${lines.join('\n\n')}\n\nPlease follow up with the relevant suppliers.`;

return [{ json: { subject, body, items: items.map(i => i.json) } }];

Adjust the field names inside the destructuring to match your exact column headers. Run the node to confirm the output panel shows a subject and body field with properly formatted content.

Step 7: Add the Gmail Send Node

Add a Gmail node after Format Alert. Set the operation to Send Email.

Configure it:

  • Credential: Your Gmail OAuth2 credential
  • To: Your purchasing coordinator's email address, or a distribution list (purchasing@yourcompany.com)
  • Subject: {{ $json.subject }}
  • Message: {{ $json.body }}

The subject will read something like: Overdue PO Alert: 3 purchase orders past expected delivery: 2026-05-28

For HTML formatting, wrap $json.body lines in <p> tags inside the Format Alert node and set the Gmail node's Message Type to HTML.

Step 8: Add a Google Sheets Update Node

After the Gmail Send node, add a Google Sheets node with the operation set to Update Row.

This node writes "OVERDUE" to the Status column for every row that was included in the alert. Because the Code node may have returned multiple rows, you need to run this inside a Loop Over Items node: add one between the Gmail Send and this Google Sheets node, feeding it {{ $json.items }} from the Format Alert output.

Inside the loop, configure the Google Sheets node:

  • Operation: Update Row
  • Spreadsheet: Same sheet
  • Sheet: Same tab
  • Row Number: {{ $json._rowNumber }}: this targets the exact row without needing to match on PO number
  • Fields to Update: Status → OVERDUE

After this runs, anyone who opens the PO tracker sheet will see "OVERDUE" in the status column for flagged rows, even before they check their email.

Step 9: Activate the Workflow

Toggle the workflow to Active. Test by temporarily changing an expected delivery date to yesterday in your sheet, triggering the workflow manually, and confirming the alert arrives and the Status column updates.

What to Watch Out For

POs that were received but never marked closed. If your team does not update the Status column when a PO is received, the workflow will flag it as overdue indefinitely. Build the habit of marking received POs as "Received" or "Closed" when the material arrives. The workflow's closedStatuses array in Step 3 handles this automatically once the status is updated.

Expected delivery dates stored as text instead of dates. If your team enters dates in formats like "May 15" or "15/05/2026," the JavaScript Date parser may misread them. YYYY-MM-DD is the safest format. If you cannot change the existing format, add a normalization line at the top of the Code node to convert common formats before the comparison runs.

Alert volume on the first run. If your PO tracker has accumulated many unresolved rows over time, the first run may produce a large alert. Run the workflow in test mode first to review the output, and clean up or close any already-resolved POs before activating.

How to Extend This Workflow

Add a supplier contact lookup. If you maintain a separate supplier contact sheet with email addresses, add a Google Sheets lookup inside the loop to pull the supplier's email and send them a direct follow-up automatically, separate from the internal team alert.

Escalate POs that are more than 5 days overdue. Add a second filter pass in the Code node for rows where daysOverdue > 5 and route those to a separate Gmail action that notifies a manager. First-day overdue items go to the purchasing coordinator; week-overdue items go up the chain.

Track overdue history. Instead of simply writing "OVERDUE" to the status column, write the alert date alongside it: OVERDUE - flagged 2026-05-28. This gives you a running record of when each PO was first flagged without needing a separate log sheet.

Why Start Here

Overdue PO alerts are one of the clearest automation wins for small manufacturers because the data is almost always already in a spreadsheet: teams just do not have anything checking it automatically. The consequence of not catching an overdue delivery early is real: production delays, emergency sourcing, and the kind of reactive scramble that burns hours and goodwill.

This workflow is also a clean introduction to date-based automation logic. Any process your team tracks with a date column and a status column: supplier certifications, contract renewals, payment due dates, can be automated with the same pattern. Build it once here and you have the template for a dozen other processes.

The Flow Kaizen guide covers how to sequence your first five automation builds, starting with quick wins like this one and building toward more connected workflows as your team's confidence grows.