How Tax Calculates on a Document
This is where everything in this category comes together. You’ve set up jurisdictions, tax types, profiles, rules, GL mappings, and registrations. Now watch the engine put them to work the moment an invoice is posted — turning a line amount into the right taxes, the right audit rows, and the right ledger entries.
The engine runs a fixed six-step pipeline. It’s the same six steps for a one-line UK sale and a fifty-line Brazilian one — only the data differs. We’ll walk each step, then run a UK invoice through it penny by penny.
Access you'll need. Any REDA Financials permission set can view the tax on a posted document. Creating and posting the invoices that trigger the calculation requires Accounts Receivable v2 (sales) or Accounts Payable v2 (purchases), or Accounting Admin v2; changing the underlying tax setup requires Accounting Admin v2 or Accounting Controller v2.
When it runs — and the three entry points
Tax is calculated at post time — the moment a document’s status becomes Posted, because that’s when it joins the books. But the same engine is used in three modes:
| Mode | When | Writes anything? |
|---|---|---|
| Live preview | As you edit an invoice | No — just shows the tax on screen |
| Post | When you post the document | Yes — writes the audit rows and posts to the ledger |
| Bulk post | Posting many documents at once | Yes — same result, optimised for volume |
The six-step pipeline
Worked example: a UK sale, penny by penny
Your UK entity sells £1,000 of standard-rated goods to a UK VAT-registered customer. Watch the pipeline:
| Step | What happens |
|---|---|
| 1 Resolve | Origin GB, destination GB (domestic). Line’s Tax Profile = GB-STD-20 (or default-taxed). |
| 2 Nexus | Entity is registered at GB → tax proceeds. |
| 3 Match | One rule fits: GB-VAT-STD-20 (20%). The reduced/zero/exempt rules don’t match the profile. |
| 4 Compute | Base £1,000 (no freight/discount). Tax = 1,000 × 20% = £200.00. |
| 5 Persist | One Source Line Tax row: Tax Type GB-VAT-STD, Rate 20%, Base £1,000, Amount £200. |
| 6 Post | Via the Sales mapping, £200 credits 2311-VAT-GB (VAT Payable). |
The resulting journal:
| Account | Debit | Credit |
|---|---|---|
| Accounts Receivable | £1,200.00 | |
| Revenue | £1,000.00 | |
| VAT Payable | £200.00 |
How the base is built (step 4 in detail)
The default base is just the line amount. The rule’s modifiers adjust it, applied in this order, before the rate is applied:
+ freight (if Include Freight)
− discount (if Subtract Discount)
× (1 − Base Reduction%) (partial exemption)
× (1 + MVA%) (Brazil ST markup)
− prior rule’s amount (Depends On Prior — DIFAL)
tax = base × rate ÷ 100 (rounded to 2dp, half-up)
Most lines use none of the modifiers — base is simply the amount. They exist for the regimes that need them, and they’re documented on Tax Rules.
Inclusive vs exclusive pricing
Each invoice line carries a Tax Base choice — Exclusive of Tax (the default: tax is added on top) or Inclusive of Tax (the price already includes tax). For inclusive lines, the engine back-calculates the net before applying rates:
Inclusive: £1,200 entered as tax-inclusive → net = 1,200 ÷ 1.20 = £1,000, tax £200. Same answer, reached from the other direction.
Brazil: the same pipeline, six rules deep
A São Paulo → Rio interstate consumer sale runs the identical six steps — but step 3 matches six rules and step 4 runs them in sequence order:
| Seq | Tax | Rate | Base note |
|---|---|---|---|
| 10 | ICMS | 12% | Por dentro — embedded in the price |
| 20 | IPI | 10% | On the goods value, added on top |
| 30 | PIS | 1.65% | Lucro Real rate (by seller regime) — por dentro |
| 40 | COFINS | 7.6% | Lucro Real rate — por dentro |
| 50 | DIFAL | 8% | Rio’s internal 20% − interstate 12%, seeded as a flat 8% rule |
| 60 | FCP | 2% | Rio surcharge (consumer sales) |
Step 5 writes six Source Line Tax rows; step 6 posts each to its own account. The exact por-dentro grossing-up and DIFAL base are worked penny by penny in the Brazil walkthrough — the point here is that it’s the same pipeline, just with more rules matching.
Re-posting and idempotency
Because posted documents can be corrected (move back to Draft, edit, re-post), the engine is idempotent: every time it calculates tax for a document, it first deletes the existing Source Line Tax rows for those lines, then writes fresh ones. So re-posting never doubles the tax or leaves stale rows — the result is always a clean reflection of the current document.
Built for volume
The engine is bulk-safe by design. Whether you post one invoice or two hundred, it resolves the shared data once and writes all the tax rows together, so a batch of documents costs roughly the same in database work as a handful. You won’t hit platform limits posting normal volumes — even Brazil’s heavy multi-tax invoices.
Where to go next
- Tax Rules — the rules the calculation evaluates.
- Source Line Tax (Audit Records) — the receipts the calculation writes.
- Tax Calculation Components — how a rule’s base is computed.
- Tax GL Mapping — where the calculated tax posts.
- Sales Invoice Tax — the calculation on a real invoice.
Frequently asked questions
On post. While you edit, a live preview shows the tax, but nothing is committed until you post the document — that’s when the audit rows and ledger entries are written. Withholding tax works the same way: previewed on the draft form, stored when the bill posts.
No. The engine clears the old tax rows for those lines before writing new ones, every time. Re-posting always produces a clean, current set — never duplicates.
Most often the nexus gate: if your entity isn’t registered in the buyer’s jurisdiction for the invoice date, step 2 returns zero tax. Check Entity Tax Registration. (The live preview applies the same rules, so a mismatch usually points to registration or an effective-date issue.)
On the invoice (line tax and total), and in the Source Line Tax rows behind it — one per rule that fired, showing the rule, rate, base, and amount. Those rows are the audit trail and link straight to the ledger entries.
Was this article helpful?