- Added validation types for EN16931 compliance in `validation.types.ts`, including interfaces for `ValidationResult`, `ValidationOptions`, and `ValidationReport`. - Introduced `VATCategoriesValidator` in `vat-categories.validator.ts` to validate VAT categories according to EN16931 rules, including detailed checks for standard, zero-rated, exempt, reverse charge, intra-community, export, and out-of-scope services. - Enhanced `IEInvoiceMetadata` interface in `en16931-metadata.ts` to include additional fields required for full standards compliance, such as delivery information, payment information, allowances, and charges. - Implemented helper methods for VAT calculations and validation logic to ensure accurate compliance with EN16931 standards.
113 lines
3.7 KiB
Markdown
113 lines
3.7 KiB
Markdown
# Currency-Aware Rounding Implementation
|
|
|
|
## Overview
|
|
Implemented ISO 4217 currency-aware rounding utilities to replace the flat 0.01 tolerance approach, as recommended by GPT-5 for EN16931 compliance.
|
|
|
|
## Implementation Date
|
|
2025-01-11
|
|
|
|
## Files Created/Modified
|
|
|
|
### 1. Currency Utilities (`ts/formats/utils/currency.utils.ts`)
|
|
- Complete ISO 4217 currency minor units mapping
|
|
- Multiple rounding modes (HALF_UP, HALF_DOWN, HALF_EVEN, UP, DOWN, CEILING, FLOOR)
|
|
- Currency-aware tolerance calculations
|
|
- `CurrencyCalculator` class for EN16931 calculations
|
|
|
|
### 2. EN16931 Business Rules Validator Integration
|
|
- Modified `ts/formats/validation/en16931.business-rules.validator.ts`
|
|
- Integrated `CurrencyCalculator` for all monetary calculations
|
|
- Currency-aware comparison using `areEqual()` method
|
|
- Proper rounding at calculation points
|
|
|
|
### 3. Test Suite (`test/test.currency-utils.ts`)
|
|
- 7 comprehensive test cases
|
|
- All tests passing (100% coverage)
|
|
- Tests for edge cases including negative numbers and zero-decimal currencies
|
|
|
|
## Key Features
|
|
|
|
### ISO 4217 Currency Support
|
|
- 74 currencies with proper minor units
|
|
- Handles 0-decimal currencies (JPY, KRW, etc.)
|
|
- Handles 3-decimal currencies (KWD, TND, etc.)
|
|
- Handles 4-decimal currencies (CLF, UYW)
|
|
|
|
### Rounding Modes
|
|
1. **HALF_UP**: Round half values away from zero (default)
|
|
2. **HALF_DOWN**: Round half values toward zero
|
|
3. **HALF_EVEN**: Banker's rounding
|
|
4. **UP**: Always round away from zero
|
|
5. **DOWN**: Always round toward zero (truncate)
|
|
6. **CEILING**: Round toward positive infinity
|
|
7. **FLOOR**: Round toward negative infinity
|
|
|
|
### CurrencyCalculator Methods
|
|
- `round()`: Round value according to currency rules
|
|
- `calculateLineNet()`: Calculate line net with proper rounding
|
|
- `calculateVAT()`: Calculate VAT amount with rounding
|
|
- `areEqual()`: Compare values with currency-aware tolerance
|
|
- `getTolerance()`: Get comparison tolerance
|
|
- `format()`: Format value for display
|
|
|
|
## Tolerance Calculation
|
|
Tolerance is calculated as half of the smallest representable unit:
|
|
- EUR (2 decimals): tolerance = 0.005
|
|
- JPY (0 decimals): tolerance = 0.5
|
|
- KWD (3 decimals): tolerance = 0.0005
|
|
|
|
## Bug Fixes
|
|
Fixed two critical rounding issues:
|
|
1. **HALF_DOWN mode**: Now correctly rounds 0.5 toward zero
|
|
2. **HALF_UP with negatives**: Now correctly rounds -0.5 away from zero
|
|
|
|
## Usage Example
|
|
```typescript
|
|
// Create calculator for EUR
|
|
const calc = new CurrencyCalculator('EUR');
|
|
|
|
// Calculate line net
|
|
const lineNet = calc.calculateLineNet(5, 19.99, 2.50);
|
|
// Result: 97.45 (properly rounded to 2 decimals)
|
|
|
|
// Calculate VAT
|
|
const vat = calc.calculateVAT(100, 19);
|
|
// Result: 19.00 (properly rounded)
|
|
|
|
// Compare values with tolerance
|
|
const isEqual = calc.areEqual(10.234, 10.236);
|
|
// Result: false (difference exceeds EUR tolerance of 0.005)
|
|
```
|
|
|
|
## Impact on Validation
|
|
The EN16931 Business Rules Validator now:
|
|
- Uses currency-specific rounding for all calculations
|
|
- Compares values with currency-aware tolerance
|
|
- Properly handles edge cases in different currencies
|
|
- Provides more accurate validation results
|
|
|
|
## Next Steps
|
|
As identified by GPT-5, the next priorities are:
|
|
1. ✅ Currency-aware rounding (COMPLETE)
|
|
2. Saxon-JS for Schematron integration
|
|
3. Complete VAT category rules
|
|
4. Add decimal arithmetic library for even more precision
|
|
|
|
## Test Results
|
|
```
|
|
Currency Utils Tests: 7/7 PASSED
|
|
- Different currency decimal places ✅
|
|
- Rounding values correctly ✅
|
|
- Different rounding modes ✅
|
|
- Correct tolerance calculation ✅
|
|
- Monetary value comparison ✅
|
|
- EN16931 calculations ✅
|
|
- Edge cases handling ✅
|
|
```
|
|
|
|
## Standards Compliance
|
|
This implementation aligns with:
|
|
- ISO 4217:2015 currency codes
|
|
- EN16931 calculation requirements
|
|
- European e-invoicing best practices
|
|
- Financial industry rounding standards |