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.

Where these fit

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).

Planned: no console create action

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

ColumnShows
Entry numberThe entry's reference (entry_number), badge. Searchable, sortable.
Entry dateThe accounting date of the entry. Sortable.
Entry typeWhat generated the entry — a badge showing one of: Cross Customer Allocation, Reallocation, Pad Posting, Refund Posting, Bounced Reversal, or Other.
DescriptionA free-text note, truncated to 40 characters in the list.
Total amountThe entry's total, in ₹. Sortable.
StateDraft Draft, Posted Posted, Reversed Reversed.

Filters

Screenshot placeholderThe Journal Entries list — entry number, entry date, entry type badge, description, total amount and state badge columns, with both filters open.

Actions

ActionPermissionFrom stateDetails
Postjournal.manageDraftPostedConfirmation only, no form. Re-checks that every line's debits equal its credits before posting — an unbalanced entry cannot be posted.
Reversejournal.managePostedReversedConfirmation 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.
Debit/credit lines aren't shown in the 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:

Everything here is read-only — an entry is driven through its lifecycle by the Post / Reverse row actions above, never edited on this page.

Screenshot placeholderThe Journal Entry detail page: an "Entry" info panel (entry number, state badge, entry type, entry date, total amount, description), a "Source & audit" panel (source document, reversing entry, posted by, created by), and a "Lines" table below.

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.

Planned: drafts are created by another service

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

ColumnShows
E-invoice numberThe e-invoice's reference (einvoice_number), badge. Searchable, sortable.
CustomerThe customer's full name.
GSTINThe customer's GST registration number (customer_gstin).
Total amountThe invoice total, in ₹. Sortable.
StateDraft Draft, Submitted Submitted, Done Done, Cancelled Cancelled.
IRNThe 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.

Screenshot placeholderThe GST E-Invoices list — e-invoice number, customer, GSTIN, total amount, state badge and IRN columns.

Actions

ActionPermissionFrom stateDetails
Submitgst_einvoice.manageDraftDoneConfirmation 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.
Cancelgst_einvoice.manageDoneCancelledConfirmation 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.
The 24-hour window is strict

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.

ParamRequiredNotes
place_of_supply_state_codeYesInteger 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_amountYesNumeric, min:0. The pre-tax amount to split GST against.
gst_rateOne of these twoNumeric, 028. An explicit GST rate %, used as-is.
tax_category_idOne of these twoInteger, 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
}
Same split rule as everywhere else

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.