انتقل إلى المحتوى الرئيسي

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:

  1. VAT: 20% on the net amount.
  2. Environmental Levy: 5% on the amount including VAT.
  3. 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:

PropertyTypeRole in Cascading Calculation
CalculationPriorityintDefines the sequence of calculation. This is paramount.
CalculationOriginEnumDetermines 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:

  1. netAmount: The initial, unchanging base amount of the transaction line.
  2. totalTaxSoFar: The sum of all taxes calculated in previous steps.
  3. currentGrossAmount: The sum of netAmount + totalTaxSoFar.

Sequence Diagram

Configuration Example

To achieve the three-layer "killer use case," a user would configure the tax codes as follows:

CodeNameRateCalculationPriorityCalculationOrigin
VAT-STDVAT Standard 20%20%10PercentageOfNetAmount
ENV-LEVYEnvironmental Levy 5%5%20PercentageOfGrossAmount
LUX-SURLuxury Surcharge 2%2%30PercentageOfGrossAmount

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.