GST review
Distribution gst-review, import package gstreview. Library only: this component
ships no command.
Package lifecycle: published. Install gst-review from PyPI with
pip install gst-review; see release notes and
DISCLAIMER.md.
Review aids for Australian GST over bank and ledger lines, for bookkeepers and accountants checking a coded bank feed before a BAS and reconciling a lodged BAS after it. The engines read the figures you supply, contact no service, write to no ledger and lodge nothing. They are experimental review aids, not advice or return preparation.
Ryan Duguid is not a registered tax agent or BAS agent. Project support is limited to software issues reproduced with fabricated data. Do not send taxpayer information.
Coding review
review_coding gives every bank line one review state and the reason for it:
| State | Meaning |
|---|---|
unknown_gst_code |
The GST code is not in the code table, so its treatment is unknown. |
gst_differs_from_registration |
The code charges or claims GST, but the entity is not registered on that date, or the purchase is from a supplier recorded as not registered (GST Act ss 9-5 and 11-5). |
between_entities |
An opposite amount sits in another supplied entity's lines within the match window: likely a transfer, not income or expense. |
coded |
Coding confirmed. |
suggested |
Coding proposed but not confirmed. |
nothing_suggested |
No account or GST code proposed. |
States are checked in that order, so a registration conflict shows even on a
confirmed line. Lines pair one to one across entities, nearest date first, within
match_window_days (default 3, at most 31).
A negative amount is money out. The GST code on the line, or else the suggested code,
is read through a code table. The default covers common Xero and MYOB AU codes; pass
gst_codes to use your own, mapping each code to taxable, gst_free,
input_taxed or outside_gst.
from datetime import date
from decimal import Decimal
from gstreview import BankLine, Registration, review_coding
result = review_coding(
[
BankLine("1", "Alder Pty Ltd", date(2026, 8, 3), Decimal("-110.00"),
account="Repairs", gst_code="GST", confirmed=True,
supplier_registered=False),
BankLine("2", "Alder Pty Ltd", date(2026, 8, 4), Decimal("-5000.00")),
BankLine("3", "Birch Trust", date(2026, 8, 5), Decimal("5000.00")),
BankLine("4", "Birch Trust", date(2026, 8, 6), Decimal("330.00"),
suggested_account="Rent", suggested_gst_code="GST"),
],
{"Alder Pty Ltd": Registration(date(2024, 7, 1)), "Birch Trust": Registration(None)},
)
for row in result["lines"]:
print(row["id"], row["state"])
1 gst_differs_from_registration
2 between_entities
3 between_entities
4 gst_differs_from_registration
The result also carries counts by state, facts_used (registration dates, match
window and code table), not_decided, sources and source_checked.
The review does not decide whether an entity was required to be registered (s 23-5), whether a supply is taxable, GST-free or input taxed on its merits, what a transfer between entities is, or whether a suggestion is right. Refunds, reversals and creditable importations are not distinguished from other lines.
BAS reconciliation
reconcile_bas works out G1, G2, G3, G10, G11, 1A and 1B from ledger lines for each
tax period and compares them with the lodged figures. Each label gets a status:
matches, differs (with the difference and the lines behind the ledger figure),
not_reported (no lodged figure for that label) or negative_ledger (credit notes
exceed sales or purchases; a BAS takes no negative figures).
- Attribution. On the cash basis a line falls in the period of its payment date.
On accruals it falls in the period of the earlier of its invoice and payment dates
(GST Act ss 29-5 and 29-10). A period's
timinglist names lines invoiced in it but attributed elsewhere, or still unpaid on the cash basis. - Rounding. Ledger totals are rounded down to whole dollars before comparison, as the ATO's BAS instructions require. Lodged figures must be whole non-negative dollars.
- GST-inclusive or not. G labels include GST unless
g1_includes_gst=False; the ATO requires every other label to follow the choice made at G1. - Codes. Each line has a side (
saleorpurchase) and a GST code, read through a code table into a category:taxable,capital,gst_free,capital_gst_free,export,input_taxedorexcluded. The default covers common Xero and MYOB AU codes; passbas_codesto use your own. Excluded lines are listed in each period'skept_out. A line in a period that cannot be placed (an unknown code, a capital code on a sale, GST on a GST-free code) refuses the whole reconciliation, naming every such line and the reason, because a label compared without it could showmatcheswrongly.
The result also lists periods with ledger lines but no lodged figures (not_lodged),
lodged periods with no ledger lines (no_ledger_lines), lines outside every period
and unpaid lines.
from datetime import date
from decimal import Decimal as D
from gstreview import LedgerLine, Period, reconcile_bas
lines = [
LedgerLine("inv-101", "sale", D("1100.00"), D("100.00"), "GST", date(2026, 7, 14),
date(2026, 7, 30)),
LedgerLine("inv-102", "sale", D("550.00"), D("50.00"), "GST", date(2026, 9, 25),
date(2026, 10, 6)),
LedgerLine("bill-7", "purchase", D("330.00"), D("30.00"), "GST", date(2026, 8, 2),
date(2026, 8, 2)),
]
result = reconcile_bas(
lines,
[Period("2026-Q1", date(2026, 7, 1), date(2026, 9, 30))],
{"2026-Q1": {"G1": D(1650), "1A": D(150), "1B": D(30)}},
basis="cash",
)
for label, row in result["periods"][0]["labels"].items():
if row["status"] != "not_reported":
print(label, row["status"], row["difference"], row["lines"])
print("timing", result["periods"][0]["timing"])
G1 differs -550 ['inv-101']
1A differs -50 ['inv-101']
1B matches None []
timing ['inv-102']
The lodged figures here include invoice inv-102, which was paid in the next quarter.
On the cash basis it belongs to that quarter, so G1 and 1A differ and the period's
timing list names it.
It does not decide whether a difference needs a revised BAS, whether any code is right, or which basis applies (s 29-40). Part payments on the cash basis need one line per payment. Labels other than those above, adjustments and GST on imports are out of scope.
Aus Accounting MCP
Aus Accounting MCP exposes both reviews as the review_gst_coding and reconcile_bas
tools, taking decimal strings and YYYY-MM-DD dates, from the published distribution
it pins.
Metadata
Release files for gst-review 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| gst_review-0.1.0.tar.gz | 38.3 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gst_review-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 56.9 kB
Release files / gst_review-0.1.0.tar.gz
| Download URL | gst_review-0.1.0.tar.gz |
|---|---|
| Size | 38.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6524ca3a084300294187a542b6eb42bda59a1c9694d40dcc9a896eeddfb47ab6
|
|
BLAKE2b-256 checksum How to use checksums |
4b5b3d75d9b92e023ac0355cf804a8528349f15310a9cd45f7f04b96f84615c5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logRelease files / gst_review-0.1.0-py3-none-any.whl
| Download URL | gst_review-0.1.0-py3-none-any.whl |
|---|---|
| Size | 18.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
aae5020766ab8c576e912d50ec78f232a1fcf5f2dce4033f0862b0ed5e95edd8
|
|
BLAKE2b-256 checksum How to use checksums |
ecc0648ff3d04461fb0883aadfc084de0ba827e16146fe80d887f44bc16a5516
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logSecurity for gst-review 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for gst_review-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.