Fix CSV import rounding errors with exchange rates (#5069)#5130
Closed
funnym0nk3y wants to merge 1 commit intoportfolio-performance:masterfrom
Closed
Conversation
…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.
Member
|
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. |
buchen
reviewed
Dec 21, 2025
Comment on lines
-208
to
+209
| Money converted = Money.of(amount.getCurrencyCode(), Math.round(grossAmountConverted.doubleValue())); | ||
| Money converted = Money.of(amount.getCurrencyCode(), | ||
| grossAmountConverted.setScale(0, RoundingMode.HALF_UP).longValue()); |
Member
There was a problem hiding this comment.
I am not sure what difference this make w.r.t. rounding. The double value is already rounded. If it is done first on the BigDecimal, that should not make a difference mathematically.
Member
|
Thanks for the proposal. In the end, I did use a different approach than proposed by Cloude - see 39042f0 - unfortunately, I miss on character in the issue number in the commit message so it does not show up here. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This commit addresses issue #5069 where CSV imports fail validation due to rounding errors when dealing with foreign exchange rates.
Changes made:
BaseCSVExtractor.java:
CheckForexGrossValueAction.java:
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:
The fix improves calculation precision and adds reasonable tolerance.