# ERPNext sales order fulfillment board for your ops team

> See every open order grouped by how far it has shipped, with late orders on top and a one click way to raise deliveries, invoices and customer updates.

- Workflow type: app
- Services: ERPNext, Gmail, Slack Bot
- Categories: Operations, Sales
- Published: 2026-08-21

## What it does

- Groups every open sales order into three columns: submitted but not yet delivered, partly delivered, and delivered but not yet invoiced.
- Puts anything past its promised delivery date at the top of the board, flagged with a plain count of how many days late it is.
- Opens any order to show its line items, linked deliveries and invoices, then lets you raise a draft delivery note or draft invoice, leave a note on the order, or post a status update to your fulfillment channel in Slack.
- Gives every order card a Chase this order button that checks stock for each line, spots deliveries still sitting in draft, writes a customer update into your Gmail drafts, and posts its diagnosis back onto the order so the board shows why the order is stuck.

## What you'll need

- An ERPNext account with permission to view sales orders, delivery notes, invoices and stock
- A Gmail account for drafting customer update emails
- A Slack workspace with a channel your fulfillment team watches

## Prompt

Build me a sales order fulfillment control board that my operations team opens every morning to see which ERPNext orders are moving, which are stuck, and which are late.

The main view is a board of cards, one card per open sales order, grouped into three fulfillment states: submitted but not yet delivered, partially delivered, and delivered but not yet invoiced. Read the orders with List Documents on Sales Order, and read deliveries with List Documents on Delivery Note. Derive the three groups from the order's own progress fields: nothing delivered yet means per_delivered is 0, partially delivered means per_delivered is above 0 and below 100, and delivered but not billed means per_delivered has reached 100 while per_billed is still below 100. Request the fields you need explicitly on the list call, including name, customer, transaction_date, delivery_date, status, docstatus, per_delivered, per_billed, grand_total and currency, since ERPNext returns only the document name by default.

Any order whose promised delivery date (the delivery_date field) has already passed is flagged as late, sorted to the top of its group, and shows a plain days late number, so a card reads something like 6 days late. Keep that number simple and unmissable rather than a colored bar or a percentage. Each card should show the customer, the order id, the order value, the promised delivery date, and the delivered and billed progress, so someone can scan the board without opening anything.

Default the board to submitted orders only, meaning docstatus is 1, so drafts and cancelled orders stay out of the way. Give me a filter by customer and a filter by warehouse, and let me clear them to see everything. The warehouse filter should match against the warehouse set on the order's line items.

Clicking an order opens a detail panel. Load the full order with Get Document on Sales Order so the panel can list every line item with item code, description, quantity ordered, quantity delivered, warehouse and rate. In the same panel, show the linked delivery notes and sales invoices for that order: find them with List Documents on Delivery Note and Sales Invoice filtered by the originating sales order on their item rows, and pull details for any one of them with Get Document. Show each linked document's id, status and whether it is still a draft.

From the detail panel I want four actions. First, raise a draft delivery note for the order using Make Delivery Note from Sales Order. Second, raise a draft sales invoice using Make Sales Invoice from Sales Order. Important: both of these mapping methods return an unsaved document object, so the handler must post the returned object back with Insert a Document (frappe.client.insert) to actually persist it, then show me the new draft's id and link. Leave both new documents as drafts for a human to review and submit; never submit them automatically. Third, let me leave a note on the order with Add a Comment. Fourth, let me post a status update about the order to our fulfillment channel with Slack Bot Send a Message, prefilled with the order id, customer, fulfillment state and days late so I only have to tweak the wording.

Every order card also carries a Chase this order button that kicks off a background agent for that specific order. The agent should: read the order with Get Document to get its line items; check on hand quantity for every line item with Get Stock Balance, using the item code and the warehouse on that line; look at whether any linked delivery note for the order is still sitting in draft rather than submitted; draft a customer update email in Gmail with Create a Draft, addressed to the order's contact, explaining the current status and the expected next step; and finally write its diagnosis back onto the order with Add a Comment, in a couple of plain sentences that name the actual blocker, for example that two lines are short on stock in the main warehouse, or that a delivery note has been sitting in draft since last Tuesday. Because the diagnosis lands as a comment on the order, the board and the detail panel should surface the most recent chase comment next to the order so the reason it is stuck sits right beside it, along with when the chase last ran.

Two hard rules. Never auto send anything to a customer: every customer facing email must land as a Gmail draft that a human opens and sends, and the app should say so on the button. And remember that submitted ERPNext documents cannot be edited, so the app must never try to modify a confirmed sales order in place; it only creates new draft documents, adds comments to the timeline, and posts to Slack.

## How to customize

- Change which orders show by default, for example widening it beyond confirmed orders or hiding anything under a certain value
- Adjust the filters to match how your team splits work, such as by customer, warehouse, territory or sales person
- Reword the customer update email and the Slack status post so they sound like your team

## FAQ

### Will this email my customers automatically?

No. Every customer update is created as a draft in Gmail and left there. Nothing reaches a customer until a person opens the draft, reads it and clicks send.

### Does it change my confirmed orders in ERPNext?

It never edits a confirmed order. Delivery notes and invoices are raised as drafts for someone on your team to review and submit, and notes are added to the order's activity timeline.

### How does it decide an order is late?

It compares the promised delivery date on the order with today's date. Anything past that date is flagged and sorted to the top of the board with the number of days it has slipped.

### Can I use this with a self hosted ERPNext?

Yes. It works with hosted ERPNext or your own server, as long as you can sign in and create access for the user whose permissions the board should use.

### What does the Chase this order button actually do?

It kicks off a background helper that checks on hand quantity for every line on the order, looks at whether any linked delivery is still sitting in draft, drafts a customer update email, and writes a short plain English diagnosis onto the order so the board can show why it is stuck.

Use this prompt in General Input: https://www.generalinput.com/prompts/erpnext-sales-order-fulfillment-board-for-your-ops-team