Home Delivery
Home Delivery is a single board for every delivery order coming into the shop — whether it arrived through Swiggy, Zomato, a phone call, WhatsApp, your website, or was created directly at the counter — tracked from "New" through to "Delivered".
Overview
Every delivery order, regardless of which channel it came from, is shown as a card with a platform badge (🧡 Swiggy, ❤️ Zomato, 📞 Phone, 💬 WhatsApp, 🌐 Website, 🏪 Direct) and a status badge that moves through a fixed pipeline: New → Accepted → Preparing → Ready → Out for Delivery → Delivered (or Cancelled at any point before Delivered).
The page auto-refreshes every 30 seconds in the background so orders placed on a food-delivery platform (or injected by a webhook) appear without anyone touching the Refresh button, and a manual Refresh icon is always available for an instant pull.
An elapsed-time badge sits on every active order card and turns amber once 70% of the estimated preparation/delivery time (ETA) has passed, then red with the word "LATE" once the ETA is fully used up — so a busy kitchen or counter can see at a glance which orders are falling behind.
Clicking an order card opens a detail drawer where you can assign a delivery agent by name, adjust the ETA, review the full item list and total, and push the order through the remaining statuses one at a time, or cancel it.
Before You Start
- Your role must have access to the Billing section of the sidebar; the page itself carries no extra plan-tier gate, so it is available on the Free/base tier as well as Advanced and above.
- To auto-fill a customer's name, phone and address when creating an order, the customer must already exist in Customers (or you can type the details manually).
Step-by-Step Guide
1 Create a new delivery order
Use this for phone, WhatsApp or walk-in delivery requests — orders coming from Swiggy/Zomato webhooks appear automatically without this step.
- Click New Order in the top-right of the page.
- Pick the source Platform tile (Swiggy, Zomato, Phone, WhatsApp, Website or Direct) — this only affects the badge shown on the order, not how it is fulfilled.
- Type into Customer Name * to search existing customers; picking one auto-fills phone, delivery address (built from the customer's address, city and pincode) and delivery route, and silently fetches that customer's most recent delivery order so its item lines can be reused as a starting point (you'll see "Items from last order on …" while this loads).
- Fill in Delivery Address * if it was not auto-filled, and adjust Phone if needed.
- Add one or more Order Items (name, quantity, price) with the + Add Item button; remove a line with its ✕ button. The running total is shown once any line has a price.
- Optionally set a Delivery Route label (e.g. "North Route") to group orders for a delivery agent, an ETA (minutes), and any Notes / Special Instructions (e.g. "No onion").
- Click Create Order. Both Customer Name and Delivery Address are required — the page blocks saving and shows a toast if either is blank.
2 Move an order through its delivery stages
- On the order card, click the colored status button in the bottom-right (e.g. Accepted, Preparing, Ready, Out for Delivery, Delivered) to advance it to the next stage in the pipeline — each click moves it exactly one step forward.
- The card's left accent color and status pill always reflect the current stage, and the elapsed-time badge keeps counting from the moment the order was created.
- To cancel an order instead of progressing it, open its detail drawer and use ✕ Cancel Order — available on any order that is not already Delivered or Cancelled.
3 Assign a delivery agent and adjust the ETA
- Click anywhere on an order card (not the status button) to open its detail drawer.
- Enter the rider/agent's name in the Delivery agent name field and adjust the min ETA number (5–180 minutes), then click Save — this updates the order without changing its status.
- The drawer also lists customer name, phone, address and any notes, plus the full item list with quantities and line totals, and lets you jump straight to any later status with a single click.
4 Filter, search and monitor the day's deliveries
- Use the date picker to review a different day's orders.
- Type in the search box to filter by order number, customer name or phone.
- Use the All statuses and All platforms dropdowns to narrow the list to, say, only Zomato orders that are Out for Delivery.
- Watch the four KPI tiles above the list — Active, Out for Delivery, Delivered Today and Delivered Revenue — for a running summary of the day.
Every Field & Button, Explained
| Field / Button | What it does |
|---|---|
Active / Out for Delivery / Delivered Today / Delivered Revenue | KPI tiles counting orders currently in any non-final status, orders specifically Out for Delivery, orders Delivered so far today, and the ₹ total of Delivered orders today. |
Platform tiles | Swiggy, Zomato, Phone, WhatsApp, Website, Direct — sets the source badge shown on the order card and in filters; purely informational, does not change fulfilment. |
Customer Name * | Type-ahead customer search; selecting a match auto-fills phone, delivery address and route, and pulls that customer's last delivery order's items as a starting point. Required to save. |
Delivery Address * | Free-text multi-line address; required to save an order. |
Order Items | Repeatable name / quantity / price rows; use + Add Item to add a row and the ✕ button to remove one. Total is computed live from quantity × price across all rows. |
Delivery Route | Free-text label (e.g. "North Route", "Route A") to help group orders by area for a delivery agent's round. |
ETA (minutes) | Expected time to prepare and deliver the order; drives the elapsed-time badge's amber/red thresholds on the order card. |
Elapsed badge | Live "Xm" counter on active orders; turns amber past 70% of ETA and red with "LATE" once elapsed time exceeds the ETA. |
Next-status button | The colored pill button on each card (e.g. "→ Preparing") advances the order exactly one step along New → Accepted → Preparing → Ready → Out for Delivery → Delivered. |
Detail drawer — Delivery agent name / min ETA / Save | Updates the assigned rider and the ETA on an existing order without changing its status. |
Detail drawer — Update Status list | Jump directly to any later status in one click, or use ✕ Cancel Order to cancel (hidden once Delivered or Cancelled). |
Refresh button | Manually re-fetches the order list for the selected date immediately; the page also silently re-fetches every 30 seconds on its own. |
Date / Search / status & platform filters | Narrow the list to a specific day, a text match on order number/customer/phone, a specific pipeline stage, or a specific source platform. |
Tips & Best Practices
- Set a realistic ETA when creating the order — the amber/red "late" indicator is only useful if the ETA reflects how long delivery genuinely takes on that route.
- Use the Delivery Route field consistently (e.g. always "North", "South", "Route A/B") so you can visually group a rider's orders even though there is no dedicated route-grouping view yet.
- When a repeat customer calls in, search their name first — it saves re-typing the address and can pre-fill the same items they ordered last time.
Troubleshooting & FAQ
An order from Swiggy/Zomato has not shown up yet.
I can't click Create Order.
The elapsed badge on an order suddenly turned red.
Can I un-cancel an order?
🧑💻 Developer Notes
Source component(s):
frontend-app/packages/pos-react-lib/src/pages/shared/FnbDeliveryOrdersPage.jsx
Backend endpoints used:
GET /delivery-orders?date=&status=&platform= (list for the selected day, optionally filtered)GET /delivery-orders?customerPhone=&limit=1 (fetch a customer's most recent order to pre-fill items)POST /delivery-orders (create)PUT /delivery-orders/:id (update status, agent name, ETA)
Related tables (db-core repositories):
FnbDeliveryOrder
Feature flag key: billing
Mounted generically as <FnbDeliveryOrdersPage apiPrefix="" /> at pos-app's /deliveries route (App.js), reusing the same component that powers the bakery/restaurant delivery channel behind their own apiPrefix (e.g. /bakery, /restaurant) — the generic mount hits the routes in backend/src/routes/delivery.routes.js, which is registered at the API root (not variant-gated) and dispatches to the same bakery.controller handlers as the variant-specific mounts. Polling for new orders uses a 30-second setInterval with a silent (non-blocking) reload so the spinner never flickers.