Solavel Solavel Docs

Taxes and VAT

docs/solavel-finance/taxes-vat.md

Who can use this: Owner can do everything; Manager can view but is denied tax.edit_rate and tax.archive; Accountant can view tax rates and apply taxes to documents but cannot edit rates or archive. URL / Route:

  • Tax rates/finance/tax-rates (finance.tax-rates.index). Detail: finance.tax-rates.show, edit, update, create, store, destroy, quick-create, toggle.
  • Tax codes/finance/settings/tax-codes (finance.settings.tax-codes.index).
  • Tax overview/finance/settings/taxes (finance.settings.taxes.index).
  • VAT returns/finance/vat-returns (finance.vat-returns.index). Actions: finance.vat-returns.create, store, show, finalize, post-reporting, settle, carry-forward. Plan / feature gates: feature:vat_enabled is the master switch (default: enabled). Reverse charge needs feature:reverse_charge_enabled (default: off). VAT returns also need feature:tracker.vat_returns (default: enabled). Permissions: tax.view, tax.apply, tax.edit_rate, tax.archive, tax.codes.view, tax.codes.manage, tax.rates.view, tax.rates.manage. VAT-return permissions: vat_returns.view, vat_returns.create, vat_returns.finalize, vat_returns.post_reporting, vat_returns.settle, vat_returns.carry_forward. Reverse-charge use needs tax.reverse_charge. All of the above also require feature:vat_enabled (and reverse_charge_enabled for reverse charge).

Purpose

Solabooks has three layers in its tax model:

  • Tax codes — the policy entries (Standard rate, Zero-rated, Exempt, Reverse-charge). Codes group rates and decide how a tax line interacts with the VAT return.
  • Tax rates — the actual percentages associated with codes. A "Standard" tax code may carry a 5% rate today and a 10% rate from a future date.
  • VAT returns — the periodic reporting cycle where you sum the tax codes by period and produce the return amount due to / claimable from your authority.

Database note: in this build the underlying tables for Tax, TaxCode, and TaxRate are unified — all three model classes alias the same taxes table. You do not need to maintain separate tables; older guides that mention three distinct tables refer to a previous schema.

Step by step

Tax codes

Route: /finance/settings/tax-codes. Permissions: tax.codes.view, tax.codes.manage.

  1. Open the page to see all tax codes.
  2. Click New tax code to add one. Fields: name, type (Output / Input / Both), behaviour (Standard / Zero-rated / Exempt / Reverse-charge / Out-of-scope), recoverability percentage, default account.
  3. Edit or toggle visibility from each row.

The setup wizard installs the country's default tax codes. You only need this page for unusual configurations.

Tax rates

Route: /finance/tax-rates. Permissions: tax.rates.view, tax.rates.manage.

  1. Open /finance/tax-rates. Each row shows code, label, rate %, effective from, effective to, status.
  2. New rate: click New tax rate. Pick a code, enter the rate %, the effective-from date, and an optional end date.
  3. Quick create: finance.tax-rates.quick-create is used by inline pickers when you create an item or invoice and need a rate that does not yet exist.
  4. Edit: click a row. Permission tax.edit_rate is required (Manager is denied this).
  5. Toggle / archive: finance.tax-rates.toggle. Permission tax.archive (Manager denied).

Apply tax on a transaction

Permission: tax.apply. Available on every line of a quote, sales order, invoice, sales receipt, credit note, bill, expense, debit note, refund, and journal entry. Picking a tax code (and the active rate inside it) attaches a tax line to the document; totals recompute live.

Reverse charge

Permission: tax.reverse_charge. Feature flags: vat_enabled AND reverse_charge_enabled.

When reverse-charge is on, a "Reverse-charge" tax code can be picked on supplier bills. The bill posts both an output and an input VAT line in equal amounts so the net to the authority is zero, satisfying the standard reverse-charge mechanism.

VAT return lifecycle

Routes: /finance/vat-returns/*.

  1. Create a return: finance.vat-returns.create / store. Permission: vat_returns.create. Pick the period (from a list of un-returned closed periods).
  2. Show the return: finance.vat-returns.show. Each line shows turnover by tax code, output VAT, input VAT, and the net payable / claimable. Source documents are linked.
  3. Finalize: finance.vat-returns.finalize. Permission: vat_returns.finalize. Locks the figures so further postings into the period do not change them. The return becomes "Finalized".
  4. Post reporting: finance.vat-returns.post-reporting. Permission: vat_returns.post_reporting. Records that you have submitted the return externally (e.g. uploaded to your tax authority's portal). Optionally writes the receivable / payable journal.
  5. Settle: finance.vat-returns.settle. Permission: vat_returns.settle. Records the actual payment made or refund received against the VAT control account, closing out the return.
  6. Carry forward: finance.vat-returns.carry-forward. Permission: vat_returns.carry_forward. If the period closed in net credit, you can roll the credit into the next period instead of claiming a refund.

VAT detail report

Route: /finance/reports/vat-detail-by-rate (finance.reports.vat-detail-by-rate). Permission: gated on vat_enabled (per the permission map). PDF: finance.reports.pdf.vat-detail-by-rate. Use this to see every tax-bearing line by rate for a date range.

Worked examples

Standard 17% VAT on a JOD 100 sale:

Account Debit Credit
AR — Customer control 117.00
Revenue — Sales 100.00
VAT Output 17.00

The JOD 17 contributes to "Output VAT" on the VAT return.

Standard 17% VAT on a JOD 100 purchase, fully recoverable:

Account Debit Credit
Expense 100.00
VAT Input (Recoverable) 17.00
AP — Supplier control 117.00

The JOD 17 contributes to "Input VAT" on the VAT return and reduces the net payable.

Zero-rated sale of JOD 100 (e.g. export): no VAT lines at all — the sale still appears on the return as zero-rated turnover for reporting, but there is no Output VAT to remit.

Account Debit Credit
AR — Customer control 100.00
Revenue — Sales 100.00

Exempt sale of JOD 100 (e.g. some financial services): like zero-rated, no VAT collected, but the sale is reported in a different box and input VAT on related purchases is NOT recoverable.

Partially-recoverable VAT — JOD 100 expense + JOD 17 VAT, only 50% recoverable:

Account Debit Credit
Expense 100.00
VAT Input (Recoverable) 8.50
Expense (non-recoverable VAT gross-up) 8.50
AP — Supplier control 117.00

The non-recoverable half is added back to the expense account — the full JOD 117 hits P&L.

Reverse charge on a JOD 100 imported service (output and input cancel out, net payable to authority = zero):

Account Debit Credit
Expense 100.00
VAT Input (Recoverable, reverse charge) 17.00
VAT Output (reverse charge) 17.00
AP — Supplier control 100.00

Both VAT lines show on the VAT return — output in the reverse-charge box, input in the recoverable box — netting to zero cash impact.

A VAT-return period summary (illustration):

Box Amount (JOD)
Standard-rated sales (Output VAT) 1,700.00
Zero-rated sales 0.00
Exempt sales (reporting only) 0.00
Reverse-charge output 17.00
Total Output VAT 1,717.00
Standard purchases (Input VAT, recoverable) 850.00
Reverse-charge input 17.00
Total Input VAT 867.00
Net payable to authority 850.00

Common mistakes

  • "Tax line doesn't appear on a document." Check the line's tax code is set — every line carries its own. A blank tax code means "no tax". If new documents always miss tax, set a default on the customer / supplier record.
  • "Reverse-charge isn't an option." Reverse charge needs both feature:vat_enabled AND feature:reverse_charge_enabled on for the org. Check at Settings.
  • "VAT return is locked but I need to add a transaction in that period." Finalized returns block new postings in their period. Either edit the return back to Draft (with vat_returns.finalize permission), or post in a later period and accept it in the next return.
  • Rate change mid-period. Tax codes don't expire — rates do. When a rate changes (e.g. 16% → 17%), add a new rate with the new effective-from date; existing documents keep their original rate.
  • Non-recoverable VAT confusion. Non-recoverable VAT is added back into the expense account, not the recoverable VAT account. Check the tax code's Recoverability % if a bill's input-VAT figure doesn't match what you expected.
  • Negative VAT return ("you're owed money"). Don't claim a refund every period — use Carry forward to roll the credit into the next period instead, especially if you expect output VAT to outweigh input VAT soon.

Tips

  • The VAT Detail by Rate report under Reports breaks down every tax line by code for a date range — use it before finalizing a return to spot misclassifications.
  • For a reverse-charge bill, the output and input VAT cancel out to zero cash impact — the bill itself doesn't ask for a separate VAT payment.

Behaviour and rules

  • Tax codes don't expire. Rates do — a code carries multiple rates with effective-from/to dates.
  • VAT-return blocking. Once a return covers a period and is Finalized, postings into that period are blocked unless the period is unlocked first.
  • Reverse charge lines do not contribute to the tax payable but do show on the VAT return for the relevant boxes.
  • vat_enabled global gate. With vat_enabled off for the org, all tax.*, tax.codes.*, tax.rates.*, vat_returns.*, and reports.vat.* permissions are denied via the permission map. The org can still use the app, but no tax lines are produced.
  • Multiple tax authorities. Not currently supported in this build — there is one VAT regime per organization.
  • Tax archive vs delete. Use Archive (toggle) to hide a rate. Hard delete is allowed only when no transaction has used the rate.

Permissions / restrictions

  • View tax pages: tax.view, tax.codes.view, tax.rates.view.
  • Apply tax on a document: tax.apply.
  • Edit a rate: tax.edit_rate (Manager denied).
  • Manage codes: tax.codes.manage.
  • Manage rates: tax.rates.manage.
  • Archive a rate: tax.archive (Manager denied).
  • Reverse charge: tax.reverse_charge (requires both flags).
  • VAT-return actions: vat_returns.view / create / finalize / post_reporting / settle / carry_forward.

Related

Source: docs/solavel-finance/taxes-vat.md ← All documentation