Reconcile tax accruals

Make the accrual rows and the ledger agree — and know which disagreements are expected.

Owned by Admin · 9 steps · about 18 minutes

Why this exists

Tax lives in two places on purpose, and reconciliation is the act of checking that they still say the same thing. The accrual rows are the tax module's own record: one row per sale per jurisdiction line, with the rate snapshotted onto it, and negative rows for refund reversals. The ledger is the money: two liability accounts that the selling module credits as part of the same balanced transaction as the sale.

Two records of the same fact, written by different modules, is a design choice. The accrual rows carry the detail a filing needs — jurisdiction, rate, category, source — which does not belong in a general ledger. The ledger carries the money, which must balance against everything else. If they ever diverge, one of the two is wrong, and you want to find that out in your own dashboard rather than in an agency's letter.

One divergence in this build is expected and you must learn to recognise it. The payments module posts stub tax to the liability accounts when an order settles, but it does not yet call the tax module's accrual engine. So a seeded or demo database legitimately shows drift: money in the ledger, no accrual row behind it. The dashboard badge going red on a fresh install is not a bug you can fix, and it is documented rather than hidden. What matters is knowing which drift is that, and which drift is new.

Refund reversals are prorated and capped so cumulative reversals can never exceed the original accrual, and they are period-keyed to the refund date, not the sale date. That is why a quarter can carry a negative line for a sale that happened in the quarter before it — and why reconciling a closed quarter after a late refund is a normal thing to do.

Before you start

  • An admin session.
  • A period to reconcile — the current quarter is fine to practise on.
  • Access to the ledger's trial balance, since half the answer lives there.

Practise with

PersonaEmailPasswordNote
adminadmin@club.test admin123the only persona that can see either side of the reconciliation
admintaxadmin@demo.club tax-admin-123the seeded tax admin

Steps 1–9 — Admin

their manual →
  1. 1
    Open the tax office and read the reconciliation badge together with the liability tiles, not instead of them.
    Expected result Quarter-to-date liability by jurisdiction and category, and a badge saying whether the accruals and the ledger agree.
    Watch out for On a seeded database the badge is legitimately red, because the demo order posts stub tax with no accrual behind it. Learn what your baseline looks like before you treat red as an alarm.
  2. 2
    Pull the liability figures and read the two halves the badge is comparing: accrual sums by account, and the ledger movement on the same accounts in the same window.
    Expected result Totals by account, jurisdiction and category, plus the ledger balances and a reconciled flag.
    Watch out for The window is the quarter containing the date you asked about. Comparing an accrual total for one quarter against a ledger balance for another will always disagree.
  3. 3
    Reconcile a specific period and read the drift per account rather than the single flag.
    Expected result Accrued, ledger and drift figures per liability account.
    Watch out for Drift in one direction only usually means missing accruals; drift in both usually means a genuine posting error. The sign tells you which module to go and read.
  4. 4
    Go to the other side of the comparison and read the two tax liability accounts on the trial balance.
    /admin/ledger ledger
    Expected result The sales tax and municipal tax liability balances.
    Watch out for These accounts are collected, not earned. A large balance is money you are holding for somebody else — it is a liability, and it should fall when you file and pay.
  5. 5
    Filter the ledger to one of the tax liability accounts and look at what actually credited it.
    Expected result Sale postings crediting tax, and refund postings debiting it back.
    Watch out for Each of these belongs to a balanced transaction with a reference. Follow the reference to the order or refund rather than trying to match by amount and time.
  6. 6
    In a training database, seed accruals for a period so you have a clean, reconciling example to compare against the messy one.
    Expected result Accrual rows created, backed by REAL balanced ledger postings, so this seeded traffic reconciles exactly.
    Watch out for This posts real money movements through the ledger. Do not run it on anything you intend to file from.
  7. 7
    List the filing periods and their packages to see which quarters are open, generated, approved or mailed.
    Expected result Periods with their current package status.
    Watch out for A period with no row has never been generated. That is normal for a future quarter and alarming for a past one.
  8. 8
    When reconciliation changes the numbers before a filing goes out, regenerate the package rather than editing it.
    /api/tax/periods/{period_id}/regenerate POST tax
    Expected result A new revision, with the previous one superseded and its documents kept.
    Watch out for Regeneration is for a package that has not been approved. Once approved, documents are hash-sealed and mailed — the answer to a post-approval discovery is an amended filing, not a quiet regeneration.
  9. 9
    Run the tax accrual invariant as a second opinion.
    Expected result Confirmation that no cumulative reversal exceeds its original accrual and that every accrual points at a real rate row.
    Watch out for This invariant checks the accrual side's internal consistency, not its agreement with the ledger. Both checks matter and neither replaces the other.