VAT base composition

In most places VAT is charged on the room alone and the tourist tax sits beside it. But in some countries the tourist tax is legally part of what the operator supplies — so VAT is charged on room + tourist tax. TaxLens models both with one primitive: base_includes plus calculation_order.

The operator-vs-guest question

When a guest pays a tourist or occupancy tax, who is the legal debtor — the operator or the guest? That single question decides whether the tax sits inside the VAT base or beside it.

  • Guest-borne — the operator merely collects the tax and remits it on the guest's behalf (a disbursement, a suplido, a débours). It is not part of the consideration for the room, so VAT is charged on the room only. This is the common case and the engine's default.
  • Operator-levied — the tax is legally owed by the operator and forms part of the price of the supply. VAT is then charged on room + tourist tax.
Out of base (default) vs in base
OUT of base (default)Room100VAT (on room)+10Tourist tax (beside)+5VAT base = 100 → VAT 10IN baseRoom100Tourist tax (order: first)+5VAT (on room + tax)+10.5VAT base = 105 → VAT 10.5
Left: VAT on the room only, tourist tax beside it. Right: tourist tax computes first and folds into the VAT base.

base_includes + calculation_order

There is no per-country special case for this. The engine models the in-base case with two fields already on every rate:

  • base_includes — a list of tax-category codes whose computed amounts are added to this rate's taxable base before it computes. The default is the room only (base_amount).
  • calculation_order — an integer ordering (lower = first). Any category listed in base_includes must have a lower order than this rate, so it computes first and its amount is available to fold in.

To put the tourist tax inside the VAT base, the VAT rate lists the tourist-tax category in its base_includes and is given a higher calculation_order than the tourist tax. The tourist tax computes first; the VAT then computes on the larger base.

{
  "tax_category": "vat_reduced",
  "rate_type": "percentage",
  "rate_value": 0.10,
  "calculation_order": 20,
  "base_includes": ["base_amount", "tourism_flat_person_night"]
}
// the tourism rate has calculation_order 10 (lower → computes first),
// so its amount is folded into this VAT rate's base.
Detail
This is the same machinery behind the pre-existing tax-on-tax cascades — Canada's HST on the municipal accommodation tax (Toronto) and the GB cascade use exactly this base_includes + calculation_order pattern.

Which countries are in, which are out

Determined against primary law. These lists reflect the dominant operator-redevable case per country:

IN the VAT base

Germany (Übernachtungsteuer), Spain (IEET), Bulgaria, Latvia, Netherlands (toeristenbelasting), Belgium — plus the pre-existing Canada (HST-on-MAT) and GB cascades.

OUT — room-only VAT (default)

Italy (imposta di soggiorno, invoice code N1), Austria, Portugal, Greece, Croatia, Hungary, Poland, Slovenia, Lithuania, France (taxe de séjour au réel), Switzerland, Romania.

Honest caveats

This primitive is precise but not unlimited. Two boundaries to know:

  • No per-operator election. The lists model the dominant case. A few jurisdictions (NL, BE) allow an individual operator to elect a disbursement treatment that flips the tax OUT of the base — there is no field to express that per-operator choice, so the country-level default stands.
  • Matches by accumulated category, not by city. base_includes matches a category code accumulated across the whole booking. It does not cleanly generalize to a single shared country-level VAT rate that must include the tax for some cities but exclude it for others (e.g. Mexico's ISH) — see Limitations.

Where to go next

The folding only matters because each layer is its own row — see Layered & additive stacking. Which category each layer carries is in Tax categories. And because VAT is the recoverable, invoice-grade layer, this composition flows straight into VAT-only invoicing.