cascading-taxes.concept.md
File: /docs/concepts/cascading-taxes.concept.md
Cascading Taxes and Calculation Order
Overview
Cascading taxes, also known as "tax on tax," are a complex regulatory requirement where certain taxes are calculated on a base amount that includes other, previously calculated taxes. Our ERP system handles this through an explicit, flexible, and powerful mechanism: the CalculationPriority field on the TaxCode aggregate. This document details our design and its advantages.
The Problem: Multi-Layered Taxes
Many ERP systems handle simple, two-layer "tax on tax" scenarios. However, they fail when faced with more complex, multi-layered regulations.
Example "Killer" Use Case: A luxury electronic item in a specific jurisdiction is subject to three cascading taxes:
- VAT: 20% on the net amount.
- Environmental Levy: 5% on the amount including VAT.
- Luxury Surcharge: 2% on the amount including VAT and the Environmental Levy.
Implicit systems that only have a "tax on tax" flag cannot correctly model this three-layer dependency.
Our Solution: Explicit CalculationPriority
Instead of implicit layers, our system uses an integer CalculationPriority field on every TaxCode.
- Rule: Lower numbers are calculated first.
- Flexibility: Allows for an unlimited number of cascading layers.
- Clarity: The intended calculation order is explicit in the data, not hidden in engine logic.
Key Domain Concepts
The entire process is driven by properties on the TaxCode:
| Property | Type | Role in Cascading Calculation |
|---|---|---|
CalculationPriority | int | Defines the sequence of calculation. This is paramount. |
CalculationOrigin | Enum | Determines the base amount for each step in the sequence. |
The TaxCalculationService uses these properties in a single, ordered loop to derive the correct total tax.
Detailed Calculation Flow
The TaxCalculationService maintains three running totals during its single-pass calculation:
netAmount: The initial, unchanging base amount of the transaction line.totalTaxSoFar: The sum of all taxes calculated in previous steps.currentGrossAmount: The sum ofnetAmount+totalTaxSoFar.
Sequence Diagram
Configuration Example
To achieve the three-layer "killer use case," a user would configure the tax codes as follows:
| Code | Name | Rate | CalculationPriority | CalculationOrigin |
|---|---|---|---|---|
| VAT-STD | VAT Standard 20% | 20% | 10 | PercentageOfNetAmount |
| ENV-LEVY | Environmental Levy 5% | 5% | 20 | PercentageOfGrossAmount |
| LUX-SUR | Luxury Surcharge 2% | 2% | 30 | PercentageOfGrossAmount |
This configuration explicitly tells the system the exact order and base for each calculation, enabling it to correctly handle this complex scenario without any code changes.