Sale Orders
A sale order is a customer's order for one or more law-book Full Sets or individual monthly parts. This page explains the order’s 9-state lifecycle, the rules every order line must follow (price, quantity, delivery mode, GST), and what Head Office does with an order: approve it for despatch, or cancel it.
Most sale orders are captured in the Sales-Executive field app or through the public API and arrive here already drafted. The console can also create a draft (New sale order, needs sale_order.create), edit a draft's lines (sale_order.edit) and move it on with Confirm Lines, Ready for HO and Submit to HO from the order's view page. Whichever route an order takes, it goes through the same checks. See Order lines.
Where to find it
Open Sales → Sale Orders in the left navigation. The link only appears if your role holds sale_order.view (or you are a super administrator).
The state machine
Every sale order sits in exactly one of 9 states. Most of the journey — from the moment a Sales Executive starts an order to the moment it is queued for Head Office — happens in the field app / API, with no console involvement. The console becomes relevant the instant an order reaches SubmittedToHo, and again at any point if the order needs to be stopped with Cancel.
Money is settled at Head Office, not in the field. A Sales Executive can submit an order that is not yet paid for, is being sold on credit, or carries a discount above their authority. What that order cannot do is get approved: HO Approve refuses it until the payment (or an approved credit request) covers the order and any over-authority discount has been approved. Nothing reaches despatch unsettled — the check simply sits with you rather than with the SE.
State legend
| State | What it means | Who moves it here |
|---|---|---|
| Draft | The order has just been started; lines can still be freely changed. | Field app / API |
| LinesConfirmed | The customer's line items — which Full Sets or parts, and quantities — are locked in. | Field app / API |
| ReadyForHo | The Sales Executive has flagged the order as finished and queued to go up to Head Office. No financial clearance is implied — an unpaid order reaches this state normally. | Field app / API |
| SubmittedToHo | The order has reached Head Office and is waiting for a decision. This is where payment, credit and discount are settled, and the only state from which HO Approve is offered. | Field app / API (arrives here) |
| ApprovedForDespatch | Head Office has approved the order; it is now eligible for stock reservation and picking. | Console — HO Approve |
| InDespatch | Stock for the order has been picked and packed, and the package is on its way to the customer. | Outside console (despatch process) |
| Completed | The order has finished its despatch cycle. The terminal, successful state. The order reaches it by itself — see below. | Automatic, when the last delivery lands |
| Suspended | A held/paused state defined on the model. No action in this console currently sets or clears it. | Not exposed anywhere found |
| Cancelled | The order was cancelled. Terminal — nothing can move an order out of this state. | Console — Cancel (or field app/API) |
An order in InDespatch moves to Completed on its own. The moment someone records a delivery on the order's last outstanding package (see Packages), the portal checks whether every delivery for that order is now finished — each one either delivered or cancelled — and if so completes the order and writes the change to its state log, crediting whoever recorded that final delivery. This used to need a person to close the order explicitly; it no longer does.
If an order is stuck in InDespatch, something on it is still open. A part that is still reserved, still in transit, or suspended all count as outstanding and hold the order open — a single held part is enough. Find the unfinished parts on Stock Moves and either get them despatched and delivered or cancel them; the order will close itself as soon as the last one clears.
Drafting an order, confirming its lines and submitting it to HO usually happen in the field app or through the public API. The console can do the same from a draft order's view page (Confirm Lines and Edit need sale_order.edit; Ready for HO and Submit to HO need sale_order.submit). Payment, credit and discount are not settled at these steps. That happens while the order sits in SubmittedToHo, and HO Approve enforces it. The final leg from ApprovedForDespatch through InDespatch to Completed isn't driven by any Sale Order button; it moves forward as despatch work happens (see Picking Waves and Packages).
Order lines Built
A line is one product on the order, with a quantity, unit price, optional delivery mode (carrier) and party / BA / special discounts. Lines can only be added or changed while the order is a Draft. The same rules apply whether the line comes from the field app, the API, offline sync or this console. In the console you add lines on the New sale order form or in the Lines table of a draft order. A rejected line shows its message under the field it concerns. The limits come from each product's settings: see Products.
| Rule | What happens |
|---|---|
| No price, no line | A product with no price in effect on the order date can't be ordered: "CODE has no current price and can't be ordered." (It is never priced at ₹0.) |
| Quantity cap | If the product has a Maximum quantity per order line, a larger quantity is rejected: "Quantity for CODE can't exceed N per order line." The console shows the maximum under the Quantity field. |
| Price lock | The unit price defaults to the product's MRP on the order date. Unless the product has Allow rate change on, a different price is rejected ("The price for CODE is fixed at ₹…") unless you hold sale_order.approve (or are a super administrator). In the console the Unit price field is greyed out when you can't change it. Re-sending a line's existing price is never rejected. |
| Delivery modes | If the product has active delivery modes, the line's carrier must be one that is active and valid on the order date, not today's date. An offline order is therefore checked against the day it was taken. Leave the carrier empty and the first permitted mode is filled in; the console pre-selects it and lists only permitted modes. Otherwise the line is rejected: "DTDC Cargo isn't a permitted delivery mode for CODE on 17 Sep 2026." A product with no active modes accepts any carrier. |
| Ordering from the SE app | If the product's Permit orders from SE app is off, a line added from the field app (online or through offline sync) is rejected: "CODE can't be ordered from the app." Lines added in this console are allowed. Confirm Lines doesn't re-check it. |
| Default party discount | The product's Default party discount % is filled in as the party discount unless the line gives one. |
GST on order lines
When a line is added, it keeps a copy of the product's tax category and GST rate. If someone later edits the tax category, lines already on orders keep their original rate. Every time the order's totals are recalculated, each line's tax is worked out as:
- Taxable amount = quantity × unit price − the line's discounts;
- Place of supply = the state of the order's shipping address (its GST state code, picked from the State list on the customer's address). Within the home state this is CGST + SGST; for any other state, IGST. The combined tax goes into the line's tax amount and the order's tax total;
- a line at 0 % GST (AIR's books and journals fall in exempt tax categories) carries ₹0 tax and needs no state on the address.
Changing an order's shipping address recalculates its tax.
Checks at Confirm Lines
On top of the existing checks (verified customer, at least one line, orderable products, a real pincode and region on the shipping address), Confirm Lines now also refuses an order with any of these messages:
- "Product CODE has no tax category."
- "Delivery mode CARRIER is no longer permitted for CODE." (the product's delivery modes changed after the line was added)
- "The shipping address needs a valid state before tax can be calculated." (only when a line has a GST rate above 0 %)
Discounts above the lower of the salesperson's limit and the product's limit don't block any of this (for a product with Allow override by SE on, only the product's limit counts). They send the order to HO discount approval, which HO Approve requires. See Discounts, Refunds & Charges.
What the console exposes
Besides View and Edit (drafts only), the Sale Orders list has two row actions that change an order's state. Both depend on your permissions and the order's current state, and the server checks both again, so a stale screen can't get around them.
HO Approve
Moves an order from SubmittedToHo to ApprovedForDespatch — the moment Head Office signs off on an order so it can be reserved and picked. This is the order's money gate. Approval is refused unless the order is fully paid or has an approved credit request covering the balance, and every line's discount is within the salesperson's authority or has an approved discount request. Both are re-checked on the server; a stale screen cannot get an unsettled order through.
- Visible when: the order's state is SubmittedToHo and you hold sale_order.approve (or are a super administrator).
- Confirmation: yes — a confirmation dialog, no form fields.
- Icon / colour: a check-badge icon, success (green).
- Find the order
On the Sale Orders list, use the Filters panel's State filter and select SubmittedToHo to see everything waiting on your decision.
- Select HO Approve on the order's row
The button only appears on rows currently in SubmittedToHo — you won't see it on any other order.
- Confirm
A dialog asks you to confirm. There is nothing else to fill in.
- Check the result
On success the row's State column updates to ApprovedForDespatch and the order becomes eligible to be picked into a wave. If the order is not settled, the approval is refused instead, with a message naming what is outstanding — the payment/credit shortfall, the unapproved discount, or both. Resolve it (record and allocate the payment, or approve the credit / discount request) and approve again.
Cancel
Stops an order dead, moving it to Cancelled from whatever state it is currently in.
- Visible when: the order's state is anything other than Completed or Cancelled and you hold sale_order.cancel (or are a super administrator).
- Confirmation: yes, plus a required form field.
- Icon / colour: an x-circle icon, danger (red).
| Field | Type | Required | Notes |
|---|---|---|---|
reason | Textarea | Yes | Max 500 characters. The action will not proceed with this left blank. |
- Select Cancel on the order's row
Available on any order not already Completed or Cancelled — including orders still in early field-app-driven states.
- Type a reason
Be specific — this text is the permanent record of why the order was stopped, and is what a colleague (or an auditor) will read later. Up to 500 characters.
- Confirm
Select the confirming button in the dialog.
- Check the result
The row's State updates to Cancelled. This is terminal — there is no console action to bring a cancelled order back.
Because Cancel is offered from almost every state — including ones the field app manages, like Draft or LinesConfirmed — it is Head Office's universal "stop this order" switch, independent of how far along it is. Use it when an order should not proceed at all, not as a substitute for the earlier, field-app-driven stages this console doesn't expose.
The list
Sale Orders opens on its list. Each row opens a detail view (below), and drafts can also be edited. Rows sort by created_at descending by default.
| Column | Shows |
|---|---|
reference | The order's reference number, as a badge. Searchable and sortable. |
| Customer | The ordering customer's full name (via their profile). |
| Salesperson | The full name of the staff member credited with the order. |
state | The order's current lifecycle state, as a coloured badge (see the state legend above). |
total_net_amount | The order's net value, formatted as Indian Rupees. Sortable. |
order_date | The date the order was placed. Sortable. |
Filter
The Filters panel offers a State drop-down listing all 9 states and a Product filter (search by code or name) that keeps orders with a line for that product — the product screen's Inventory tab links here with it already set. With State you can, for example, isolate everything sitting in SubmittedToHo waiting on your approval, or everything already Cancelled for an audit trail.
Viewing an order Built
Use the View row action (or click through) to open an order's detail page. It needs the same sale_order.view permission as the list. It contains:
- Order — an information panel with the reference, the current state (same coloured badge as the list), the customer and salesperson, the order type, the order date and any state reason.
- Amounts — the order's gross, discount, tax and (in bold) net totals, in Rupees.
- Line items — a table of every line on the order: product code and name, quantity, unit price, the discount and tax breakdown, and each line's gross and net amount.
- Payments applied — a read-only table of the payment allocations posted against this order: the voucher, the line it was applied to, and the amount (plus gateway charges and any allocation discount).
- Credit requests / Discount requests — the credit and discount approval requests raised on this order: the amount, the request state, the reason, who raised it, and who approved it (with the decision date and remarks).
- State history — the full audit trail of the order's state changes: from-state, to-state, the reason, who performed the transition and when.
Apart from the Lines table on a draft order (see Order lines), this page is for reading: an order moves through its lifecycle through the header actions (Confirm Lines, Ready for HO, Submit to HO, HO Approve, Cancel) and the field app. The lines you see are also what the sales reports aggregate; the payments, credit/discount requests and state history tables let you trace an order's full financial and approval history without leaving the page.
Visibility scoping — you may not see every order
Unlike a flat permission check, the Sale Orders list also filters which rows you can see, on top of whether the module is visible to you at all:
- Full visibility — you see every sale order in the system — applies if you are a super administrator or hold sale_order.view_all.
- Scoped visibility — everyone else only sees an order if either:
- the order's customer falls within your geography scope or your customer scope (the same scoping used across the console — see Customers), or
- you are recorded as the order's salesperson.
If a colleague mentions an order you cannot find, it is almost always this scoping at work rather than a fault: the order's customer sits outside the region or customer scope assigned to you, and you are not its salesperson. An administrator with sale_order.view_all, or a super administrator, can always see it and can review or widen your geography/customer scope if that access is genuinely needed.
See also
- Customers — the customer record each sale order belongs to, and how geography/customer scoping is set up.
- Payment Vouchers — how a customer's payment is recorded and allocated against an order, which is what clears the payment half of the HO Approve gate.
- Discounts, Refunds & Charges — the discount-approval flow that clears the other half of that gate, and what happens after an order is billed.
- Picking Waves — how an ApprovedForDespatch order's stock is actually picked, packed and despatched.
- Schedulers — the background jobs that quietly drive some of the "outside console" transitions shown in the diagram above.