Discounts, Refunds & Charges
Three related approval workflows for money that moves outside the normal order/payment cycle: a discount granted after HO already approved an order, money owed back to a customer, and money AIR levies on a customer. Each is a separate link in the Billing navigation group, but they share the same approve/reject/cancel shape, so this guide covers them together.
All three relate back to a customer's running account. A PAD reduces what a customer still owes on an order; a refund pays money back out; a charge adds to what they owe. See Payment Vouchers for how money comes in, and Sale Orders for the order an outstanding balance is measured against.
Post-Approval Discounts (PAD) Partial
A Post-Approval Discount is a discount granted on a sale order after Head Office has already approved it — for example a goodwill reduction agreed with a customer once the order is in flight. In the console it appears under Post Approval Discounts in the Billing navigation group. Viewing the list needs pad.view. Each row can also be opened to a read-only detail view (below).
PADs are drafted and submitted for approval elsewhere (the API or another service) — there is no New PAD button here. A PAD only appears in this list once it exists, most often already at Pending Approval. Once you can act on one, you can approve, reject or cancel it as described below.
Columns
| Column | Shows |
|---|---|
| PAD number | The PAD's reference (pad_number), shown as a badge. Searchable, sortable. |
| Customer | The customer's full name. |
| Reason | The configured discount reason (reason.name) — this is what decides, behind the scenes, whether approving the PAD also posts a journal entry. |
| Amount | The discount amount, in ₹. Sortable. |
| State | A state badge — colours below. Draft Draft, Pending Approval Pending Approval, Approved Approved, Posted Posted, Cancelled Cancelled. |
| Booking date | The date the discount was booked. Sortable. |
Filter
A State filter lets you narrow the list to any one of the five states above.
Viewing a PAD Built
Use the View row action to open a PAD's detail page — read-only, gated by the same pad.view permission as the list. It has three info panels and no child table:
- Discount — the PAD number, the current state (same coloured badge as the list), the customer, the reason, the amount and the booking date.
- Applied to — the sale order, the sale-order line, the package and the invoice customer the discount applies to.
- Approval & audit — who submitted it, who approved it, and the linked journal entry (if approving it posted one).
Everything here is read-only — a PAD is driven through its lifecycle by the Approve / Reject / Cancel actions below, not edited as a form.
Actions
| Action | Permission | From state | Details |
|---|---|---|---|
| Approve | pad.approve | Pending Approval → Approved | Confirmation only, no form. Refused (422) if the discount amount exceeds the sale order's remaining outstanding balance. If the PAD's reason is configured to post a journal entry, approving it automatically creates and posts that entry and the PAD advances straight through to Posted in the same step. |
| Reject | pad.approve | Pending Approval → Cancelled | Confirmation with a form: reason (Textarea, required, max 1000). There is no distinct "Rejected" state — a rejected PAD lands on Cancelled, same as a cancelled one. |
| Cancel | pad.cancel | Draft, Pending Approval or Approved → Cancelled | Confirmation only, no form. Refused (409) if the PAD has already reached Posted with a linked journal entry — "reverse the journal entry first" on the Accounting page. |
Cancel is offered on rows at Draft, Pending Approval or Approved. If, between opening the page and confirming, the PAD advanced to Posted in another tab or because your own Approve just auto-posted its journal entry, the cancellation is refused and you're told to reverse the journal entry first instead.
Refund Requests Partial
A Refund Request is money AIR owes back to a customer. It appears under Refund Requests in the Billing group. Viewing the list needs refund.view. Each row can also be opened to a read-only detail view (below).
Refunds are created and submitted elsewhere — there is no New refund button here. This page is where you approve, reject or issue a refund once it exists.
Columns
| Column | Shows |
|---|---|
| Refund number | The refund's reference (refund_number), badge. Searchable, sortable. |
| Customer | The customer's full name. |
| Total amount | The refund amount, in ₹. Sortable. |
| State | Draft Draft, Submitted Submitted, Approved Approved, Issued Issued, Rejected Rejected. |
| Refund method | How the money will go back — Cheque, NEFT or Adjustment. This decides which fields the Issue form asks for. |
Filter
A State filter narrows the list to any one of the five states.
Viewing a refund Built
Use the View row action to open a refund's detail page — read-only, gated by the same refund.view permission as the list. It has three info panels plus one child table:
- Refund — the refund number, the current state (same coloured badge as the list), the customer, the total amount and the refund method.
- Source & bank — the originating voucher and the refund bank account.
- Approval & audit — who submitted it, who approved it, and the linked journal entry (if issuing it posted one).
Below the panels, a read-only Items table: one row per sale-order line the refund covers, showing the refund amount, the allocated amount, the PAD amount and any remarks. Everything here is read-only — a refund is driven through its lifecycle by the Approve / Reject / Issue actions below, not edited as a form.
Actions
| Action | Permission | From state | Details |
|---|---|---|---|
| Approve | refund.approve | Submitted → Approved | Confirmation only, no form. |
| Reject | refund.approve | Submitted → Rejected | Confirmation with a form: rejection_reason (Textarea, required, max 1000). |
| Issue | refund.issue | Approved → Issued | Confirmation with a form whose required fields depend on the refund's method (see below). |
The Issue form
The form always offers the same three fields, but which ones you must fill depends on the record's refund_method:
| Field | Type | Required | Notes |
|---|---|---|---|
refund_cheque_number | Text | Only if method is Cheque | The cheque number issued to the customer. |
refund_cheque_date | Date | Only if method is Cheque | The date on the cheque. |
refund_bank_account_id | Number | Only if method is NEFT | The bank account the refund was transferred from. |
If the method is Cheque and you leave the cheque fields blank, or the method is NEFT and you leave the bank account blank, the action is refused with a validation error rather than issuing an incomplete refund.
If refund accounting is switched on in System Configuration — an opt-in flag plus a debit and a credit account under the accounting group — then issuing a refund also creates and posts a balanced double-entry to the ledger in the same step, linked back to the refund. If the flag is off, or either account is left blank, nothing is posted — so a journal entry only appears for refunds issued while accounting is configured. The entry, once posted, shows up on the Accounting — Journal & GST page. These refund.* account settings are shared across all refunds (refunds have no per-type accounting).
Charges Partial
A Charge is money AIR levies on a customer — for example a cheque-bounce fee. It appears under Charges in the Billing group. Viewing the list needs charge.view. Each row can also be opened to a read-only detail view (below).
There is no console action to create a charge, mark it Notified, or record a Dispute — a charge only appears here once it has already reached Notified or Disputed by some other flow. From this page you can only Resolve or Cancel it.
Columns
| Column | Shows |
|---|---|
| Charge number | The charge's reference (charge_number), badge. Searchable, sortable. |
| Customer | The customer's full name. |
| Type | The configured charge type (chargeType.name) — e.g. cheque-bounce. |
| Amount | The charge amount, in ₹. Sortable. |
| State | Draft Draft, Notified Notified, Disputed Disputed, Resolved Resolved, Cancelled Cancelled. |
| Resolution | Once resolved, whether the charge was Levied or Waived. Blank until resolved. |
Filter
A State filter narrows the list to any one of the five states.
Viewing a charge Built
Use the View row action to open a charge's detail page — read-only, gated by the same charge.view permission as the list. It has two info panels and no child table:
- Charge — the charge number, the current state (same coloured badge as the list), the resolution (same badge as the list), the customer, the type and the amount.
- Resolution & audit — who resolved it, who created it, the linked journal entry (if the resolution posted one), and any resolution remarks.
Everything here is read-only — a charge is driven through its lifecycle by the Resolve / Cancel actions below, not edited as a form.
Actions
| Action | Permission | From state | Details |
|---|---|---|---|
| Resolve | charge.resolve | Notified or Disputed → Resolved | Confirmation with a form: resolution (Select — Levy or Waive, required); resolution_notes (Textarea, optional, max 1000). |
| Cancel | charge.cancel | Draft, Notified or Disputed → Cancelled | Confirmation only, no form. |
Resolving a charge always asks you to record the outcome: Levy confirms the customer is charged, Waive writes it off with no payment. Either way the charge moves to Resolved — the choice is recorded, not enforced by a further state.
If the charge's charge type is configured for accounting (an opt-in flag plus a debit and a credit account), resolving it as Levy also creates and posts a balanced double-entry to the ledger in the same step, linked back to the charge. Waive posts nothing, and a charge type left unconfigured posts nothing either way — so a journal entry only appears for levied charges under a configured type. This accounting configuration lives on the charge type and is set through the API, not this console; the entry, once posted, shows up on the Accounting — Journal & GST page.
Related pages: Payment Vouchers · Sale Orders · Accounting — Journal & GST · Bank Reconciliation.