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:
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_INCOMEaccounts withreporting_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.