Skip to content

Conversation

@funnym0nk3y
Copy link

This commit addresses issue #5069 where CSV imports fail validation due to rounding errors when dealing with foreign exchange rates.

Changes made:

  1. BaseCSVExtractor.java:

    • Replaced Math.round(BigDecimal.doubleValue()) with BigDecimal.setScale(0, RoundingMode.HALF_UP).longValue()
    • This avoids precision loss from converting BigDecimal to double
    • Applies to both extractGrossAmount() and createGrossValueIfNecessary()
  2. CheckForexGrossValueAction.java:

    • Added tolerance of ±2 (±0.02 in currency) to validation
    • This accounts for unavoidable rounding when Money values are limited to 2 decimal places
    • Prevents false positives while still catching actual errors

Root cause: Money stores amounts as longs with 2 decimal precision (factor of 100). When gross amounts are calculated with exchange rates, rounding to 2 decimals can cause small discrepancies that fail strict equality checks.

Example from issue:

  • Value: 95.26 CAD, FX Rate: 1.3795
  • Calculated: 95.26 / 1.3795 = 69.0540... → rounded to 69.05
  • Recalculated: 69.05 × 1.3795 = 95.254... → 95.25 ≠ 95.26

The fix improves calculation precision and adds reasonable tolerance.

…ance#5069)

This commit addresses issue portfolio-performance#5069 where CSV imports fail validation
due to rounding errors when dealing with foreign exchange rates.

Changes made:

1. BaseCSVExtractor.java:
   - Replaced Math.round(BigDecimal.doubleValue()) with
     BigDecimal.setScale(0, RoundingMode.HALF_UP).longValue()
   - This avoids precision loss from converting BigDecimal to double
   - Applies to both extractGrossAmount() and createGrossValueIfNecessary()

2. CheckForexGrossValueAction.java:
   - Added tolerance of ±2 (±0.02 in currency) to validation
   - This accounts for unavoidable rounding when Money values are
     limited to 2 decimal places
   - Prevents false positives while still catching actual errors

Root cause: Money stores amounts as longs with 2 decimal precision
(factor of 100). When gross amounts are calculated with exchange rates,
rounding to 2 decimals can cause small discrepancies that fail strict
equality checks.

Example from issue:
- Value: 95.26 CAD, FX Rate: 1.3795
- Calculated: 95.26 / 1.3795 = 69.0540... → rounded to 69.05
- Recalculated: 69.05 × 1.3795 = 95.254... → 95.25 ≠ 95.26

The fix improves calculation precision and adds reasonable tolerance.
@buchen buchen added the csv label Nov 9, 2025
@buchen
Copy link
Member

buchen commented Nov 9, 2025

I'll have a look - I also need to rebase because I just happen to touch that close (deriving the exchange rate if it is not present).

And a test case helps to avoid breaking this feature in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants