The line-level BasisAmount in SpecifiedTradeAllowanceCharge must equal
the value the percentage is applied to (BT-137/BT-142 semantic
definition, EN 16931-1:2017+A1:2019). For an item with basisQuantity != 1
that value is (price / basisQuantity) * quantity = the line subtotal, not
the per-unit price/basisQuantity value.
Also matches the line-net formula confirmed for EN 16931-1:2026 (BR-67,
ConnectingEurope/eInvoicing-EN16931 issue #445).
- ZUGFeRD2PullProvider.getItemTotalAllowanceChargeStr: emit
currencyFormat(item.getValue().multiply(item.getQuantity())).
- getAllowanceChargeStr (product-level, BG-29 GrossPrice path) is
intentionally NOT changed: there BasisAmount is the gross unit price
per BT-148, which is per-unit by definition.
- CalculationTest: two new XML-level regression tests asserting
BasisAmount and ActualAmount in emitted CII XML for allowance and
charge cases with basisQuantity != 1 (Extended profile).
Fixes#925 (Extended profile), related to #948.
Made-with: Cursor
Two arithmetic bugs caused wrong line totals when percentage-based allowances
or charges were used:
Bug A — Product-level (product.allowances): The percent discount was computed
as (price * pct/100) * quantity (line total), then subtracted from the unit
price and multiplied by quantity again — discount applied twice.
Bug B — Item-level (itemAllowances) with basisQuantity != 1: The percent was
applied to price * quantity instead of price * quantity / basisQuantity.
Fix: LineCalculator and XML pull providers now pass context-appropriate
IAbsoluteValueProvider wrappers (perUnitProvider for product-level,
itemBasisProvider for item-level). Allowance.java uses RoundingMode.HALF_UP
in getPercent().divide(100). BasisAmount in XML is formatted via
currencyFormat().
Files changed:
- LineCalculator.java: perUnitProvider, itemBasisProvider in allowance/charge loops
- Allowance.java: RoundingMode.HALF_UP, scale 18
- ZUGFeRD2PullProvider.java: correct providers, format BasisAmount
- OXPullProvider.java, DAPullProvider.java: perUnitProvider for product-level
- CalculationTest.java: @Test on 5 methods, 4 new regression tests
Verification: mvn test -pl library -Dtest=CalculationTest
Full PR description with before/after XML proof: see .project/PR-allowance-charge-fix.md
(Test evidence files in C:\temp\mustang-test\ are for PR attachment only, not in repo.)
Co-authored-by: Cursor <cursoragent@cursor.com>