Accounting — Journal & GST
Two record-keeping resources in the Billing navigation group: the internal double-entry ledger behind every posted discount, refund and reversal, and the GST e-invoices AIR files for taxable sales. Both are review-and-action screens — the records themselves are created by other flows, not by a button here.
Approving a Post-Approval Discount whose reason is configured to post can automatically create and post a journal entry here. Resolving a Charge as a levy does the same when its charge type is configured for accounting, issuing a Refund does the same when the refund.* accounting config is switched on, and dishonouring a Payment Voucher posts a reversal when the bounced.* config is switched on. Bank reconciliation and payment flows (Payment Vouchers, Bank Reconciliation) are the other main sources of ledger activity, though this console does not expose every posting path explicitly.
Journal Entries Partial
A Journal Entry is AIR's internal double-entry ledger — every entry balances a set of debit and credit lines. It appears under Journal Entries in the Billing group. Viewing the list needs journal.view. Each row can also be opened to a read-only detail view (below).
There is no New journal entry button. Entries are created by other flows — for instance, approving a Post-Approval Discount whose reason is configured to post automatically creates and posts one via PadService::approve(), resolving a Charge as a levy does the same via ChargeService::resolve() when its charge type is configured for accounting, issuing a Refund does the same via RefundRequestService::issue() when the refund.* accounting config is set, and dishonouring a Payment Voucher posts a reversal via PaymentVoucherService::dishonour() when the bounced.* config is set. This screen is where you review and post/reverse entries once they exist, not where you author them.
Columns
| Column | Shows |
|---|---|
| Entry number | The entry's reference (entry_number), badge. Searchable, sortable. |
| Entry date | The accounting date of the entry. Sortable. |
| Entry type | What generated the entry — a badge showing one of: Cross Customer Allocation, Reallocation, Pad Posting, Refund Posting, Bounced Reversal, or Other. |
| Description | A free-text note, truncated to 40 characters in the list. |
| Total amount | The entry's total, in ₹. Sortable. |
| State | Draft Draft, Posted Posted, Reversed Reversed. |
Filters
- State — all three states above.
- Entry type — all six entry types above.
Actions
| Action | Permission | From state | Details |
|---|---|---|---|
| Post | journal.manage | Draft → Posted | Confirmation only, no form. Re-checks that every line's debits equal its credits before posting — an unbalanced entry cannot be posted. |
| Reverse | journal.manage | Posted → Reversed | Confirmation only, no form. Creates a new entry that starts life already Posted, with every debit/credit line swapped, and links the two via reversed_by_id. The original moves to Reversed; the new reversal entry then appears in this same list. |
This list shows entries at the header level only — entry_number, totals, state. The individual debit and credit lines that make up an entry aren't shown here — open the entry's detail page (below) to see them.
Viewing an entry Built
Use the View row action to open an entry's detail page — read-only, gated by the same journal.view permission as the list. It has two info panels and a table:
- Entry — the entry number, the current state (same coloured badge as the list), the entry type, the entry date, the total amount and the description.
- Source & audit — the source document the entry was posted from, the reversing entry (if this one has since been reversed), who posted it, and who created it.
- Lines — a table of every debit/credit line on the entry: account code, debit, credit and narration.
Everything here is read-only — an entry is driven through its lifecycle by the Post / Reverse row actions above, never edited on this page.
GST E-Invoices Partial
A GST E-Invoice is the government-mandated electronic invoice AIR must file for taxable sales, carrying an IRN (Invoice Reference Number) once accepted by the GST portal. It appears under GST E-Invoices in the Billing group. Viewing the list needs gst_einvoice.view.
There is no New e-invoice button. Draft e-invoices are created elsewhere; this screen is where you submit a draft to the GST portal, or cancel one that's already Done.
Columns
| Column | Shows |
|---|---|
| E-invoice number | The e-invoice's reference (einvoice_number), badge. Searchable, sortable. |
| Customer | The customer's full name. |
| GSTIN | The customer's GST registration number (customer_gstin). |
| Total amount | The invoice total, in ₹. Sortable. |
| State | Draft Draft, Submitted Submitted, Done Done, Cancelled Cancelled. |
| IRN | The Invoice Reference Number returned by the GST portal once filed, truncated to 16 characters. Blank until Submit succeeds. |
Filter
A State filter narrows the list to any one of the four states above.
Actions
| Action | Permission | From state | Details |
|---|---|---|---|
| Submit | gst_einvoice.manage | Draft → Done | Confirmation only, no form. Sends the invoice to the GST portal to generate an IRN; on success the IRN and acknowledgement details are recorded and the invoice advances directly to Done. |
| Cancel | gst_einvoice.manage | Done → Cancelled | Confirmation with a form: reason (Textarea, required, max 500). Refused (422) if more than 24 hours have passed since the acknowledgement date — issue a credit note instead of cancelling a filed e-invoice past that window. |
GST rules only allow cancelling a filed e-invoice within 24 hours of the portal acknowledging it. Once that window closes, Cancel is refused outright — the only compliant way to correct a filed invoice past 24 hours is to issue a credit note, which is not a function of this screen.
GST Estimate Built
POST /api/v1/gst/estimate is a stateless utility endpoint, not a console screen — it lets a caller (chiefly the SE field app, while building a sale order line) preview the CGST/SGST/IGST split for a taxable amount before anything is saved. It performs no writes and returns the same breakdown shape GstCalculationService produces internally for real order lines.
| Param | Required | Notes |
|---|---|---|
place_of_supply_state_code | Yes | Integer state code the goods are supplied to — compared against AIR's home state (gst.home_state_code, see System Configuration) to decide intra- vs inter-state. |
taxable_amount | Yes | Numeric, min:0. The pre-tax amount to split GST against. |
gst_rate | One of these two | Numeric, 0–28. An explicit GST rate %, used as-is. |
tax_category_id | One of these two | Integer, must reference an existing Tax Category. When given, the rate is looked up from that category's gst_rate instead of being passed directly. |
Exactly one rate input is required — supplying neither gst_rate nor tax_category_id, or an unknown tax_category_id, is refused with a 422. Both may be sent, but only tax_category_id is used if present.
POST /api/v1/gst/estimate
{ "place_of_supply_state_code": 29, "taxable_amount": 100, "gst_rate": 18 }
200 OK
{
"is_inter_state": true,
"cgst_rate": 0, "cgst_amount": 0,
"sgst_rate": 0, "sgst_amount": 0,
"igst_rate": 18, "igst_amount": 18,
"total_tax": 18,
"place_of_supply_state_code": 29,
"taxable_amount": 100,
"gst_rate": 18,
"home_state_code": 27
}
When place_of_supply_state_code matches AIR's home state, the rate is halved into equal cgst_rate + sgst_rate and igst_rate is zero; otherwise the full rate goes to igst_rate and both cgst/sgst are zero. The response always echoes back place_of_supply_state_code, taxable_amount (rounded to 2dp), the gst_rate actually used (resolved from tax_category_id when that was given), and the current home_state_code it compared against.
Sits in the standard auth:sanctum + password.changed route group, the same as GET /me — no permission: gate, since this is a read-only calculator with no resource to scope access to.
Related pages: Discounts, Refunds & Charges · Payment Vouchers · Bank Reconciliation · Sale Orders · Offline Sync.