ITADN

Allow custom TransactionCalculator injection to properly support BR-FXEXT-CO-15 tolerance use cases

#1041Openmeparis 创建于 2026-02-16
M
mepariscommented
Context In Factur-X EXTENDED, rule BR-FXEXT-CO-15 introduces a tolerance of ±0.01 EUR per invoice line between: BT-112 (GrandTotalAmount) and BT-109 + BT-110 This tolerance exists to absorb rounding strategy differences (line-level vs document-level rounding). However, in Mustang, TransactionCalculator is directly instantiated inside ZUGFeRD2PullProvider: TransactionCalculator calc = new TransactionCalculator(trans); This makes it impossible to provide an alternative calculation strategy without modifying core code. Why this is a problem BR-FXEXT-CO-15 explicitly acknowledges that small discrepancies may exist due to rounding strategies. In real ERP systems: Line amounts may be rounded early VAT may be computed globally Totals may be derived from upstream certified engines Payment totals may legally differ by 0.01 or 0.02 Even when remaining within the tolerance defined by BR-FXEXT-CO-15. Currently, Mustang: Applies a fixed “round-early, aggregate-later” strategy Does not allow substituting the calculation model Prevents leveraging the tolerance provided by BR-FXEXT-CO-15 unless the core library is forked This limits advanced but legitimate use cases in Factur-X EXTENDED. Important Clarification This proposal does not aim to: Break EN 16931 compliance Bypass BR-CO-15 Modify default behavior It simply allows advanced users to: Implement alternative compliant calculation strategies Explicitly rely on BR-FXEXT-CO-15 tolerance where appropriate Preserve ERP-certified totals when legally acceptable without modifying Mustang core. Proposed Solution (Minimal & Backward Compatible) Introduce a protected factory method in ZUGFeRD2PullProvider: protected TransactionCalculator createCalculator(Invoice trans) { return new TransactionCalculator(trans); } Replace: TransactionCalculator calc = new TransactionCalculator(trans); with: TransactionCalculator calc = createCalculator(trans); Benefits 100% backward compatible No behavioral change for existing users Enables legitimate BR-FXEXT-CO-15 tolerance scenarios Avoids forcing users to fork Mustang Improves extensibility and enterprise adoption Keeps normative compliance fully under user responsibility Example Usage public class CustomPullProvider extends ZUGFeRD2PullProvider { @Override protected TransactionCalculator createCalculator(Invoice trans) { return new CustomTransactionCalculator(trans); } } Why This Matters BR-FXEXT-CO-15 exists specifically to tolerate controlled rounding discrepancies. Without an extension mechanism in Mustang, it is not possible to: Align calculation strategy with external ERP engines Fully leverage the tolerance defined in the Factur-X EXTENDED profile Implement controlled, documented rounding policies Adding this factory method would make Mustang more extensible, while keeping default behavior fully unchanged.
3 条评论