Skip to content

GST & BAS

SAE Books handles Australian GST natively — every transaction line carries a tax_code, GST is computed at the line level, and the running BAS report is regenerated incrementally as new transactions post.

Tax codes

The shipped AU tax codes:

Code Rate reporting_type Meaning
GST 10% taxable Standard taxable supply
CAP 10% capital Capital acquisition (BAS G10, reported separately)
FRE 0% gst_free GST-free (basic food, exports, healthcare, etc.)
INP 0% input_taxed Input-taxed sale (residential rent, financial supplies)
EXP 0% export Export of goods/services (with documentation)
N-T 0% out_of_scope Not reportable (wages, drawings, owner transfers)
MGN 0% margin_scheme Margin scheme — Div 75 GSTA 1999 s66-50

Custom tax codes can be added per tenant. Each code carries a reporting_type that the BAS engine uses to bucket lines into G1/G2/G3/G10/G11. The tax_code_default on an account drives automatic tagging when a line is posted against that account.

Reverse-charge and import codes are not in the standard starter set

RCP (Reverse Charge — Imported Services, 10%) and IMP (GST on Imports, 10%) are AU-jurisdiction codes available via ensure_international_seed() but are not part of the seven-code standard AU starter set. Use INP for residential-rent / financial-supply input-taxed supplies.

How GST is computed

GST is stored on the journal line, not derived at report time:

class JournalLine:
    debit: Decimal            # debit amount (ex-GST for taxable lines)
    credit: Decimal           # credit amount (ex-GST for taxable lines)
    tax_code_id: UUID | None  # FK to tax_codes
    gst_amount: Decimal | None  # GST amount (computed at post)
    tax_treatment: dict | None  # per-line tax snapshot (JSONB)

gst_amount is locked when the journal is posted. The tax_treatment JSONB snapshot captures the tax-code state at post time so audit history stays self-consistent even if a tax code is later edited. Subsequent changes to the tax-code rate only affect new journals, never historical postings.

GST auto-posting is handled by saebooks.services.tax_engine.au (previously saebooks.services.gst, now a deprecated shim). When a taxable line posts, the engine creates a corresponding credit/debit on the GST Collected or GST Paid control account configured in company settings (gst_collected_account_code / gst_paid_account_code).

BAS preparation

GET /api/v1/reports/bas_summary accepts a date range and returns the BAS labels as a summary object:

GET /api/v1/reports/bas_summary?from_date=2026-01-01&to_date=2026-03-31

Response includes fields for G1, G2, G3, G10, G11, 1A, and 1B as computed from posted journal lines for the period.

BAS logic:

  • G1 — net sales on INCOME/OTHER_INCOME accounts with reporting_type = "taxable"
  • G2 — export sales (reporting_type = "export")
  • G3 — GST-free sales (reporting_type = "gst_free")
  • G10 — capital purchases (reporting_type = "capital")
  • G11 — non-capital taxable purchases (reporting_type = "taxable" on expense/COGS accounts)
  • 1A/1B — sourced directly from the GST Collected and GST Paid control account balances for the period

When registration_effective_date falls within the period the report splits pre- and post-registration sales — pre-registration sales are disclosed but excluded from 1A/1B (ATO compliance for mid-quarter GST registration).

The BAS settlement journal (clearing GST Collected and GST Paid to the BAS Payments/Receivable account) is generated by POST /reports/bas/settle on the web router.

E-lodgement (SBR)

The community edition exports a CSV / XML pack for manual lodgement via the ATO Business Portal or your tax agent's software.

The enterprise edition ships an SBR (Standard Business Reporting) adapter that lodges the BAS directly using a Machine Credential issued through the ATO's Relationship Authorisation Manager (RAM). This is the same mechanism Xero / MYOB use; SAE Books just runs it on hardware you control rather than someone else's SaaS.

Setting up the credential is a one-time operator task — see ATO SBR onboarding for the credential setup, and the lodge-server contract documented under Operations.

Common gotchas

  • Wine equalisation tax (WET) and luxury car tax (LCT) are separate from GST and require the relevant feature flag. They show up as additional BAS labels (1C, 1D, 1E, 1F).
  • Cash vs. accruals GST is a tenant setting — it determines whether GST is reported in the period of the invoice (accruals) or the payment (cash). Switching mid-year requires a one-off journal to bring opening balances onto the new basis.
  • Round-half-to-even is used for tax-amount rounding to match the ATO's published behaviour. Don't change this unless you have a written ruling that says otherwise.