[
https://issues.apache.org/jira/browse/FINERACT-2988?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18132435#comment-18132435
]
LeeYoonMyeong commented on FINERACT-2988:
-----------------------------------------
Fixed by https://github.com/apache/fineract/pull/6731 (merged). Could a
committer please resolve this issue with Fix Version 1.17.0? I don't have
permission to transition it.
> Tax split uses double arithmetic and can be off by one minor unit at rounding
> boundaries
> ----------------------------------------------------------------------------------------
>
> Key: FINERACT-2988
> URL: https://issues.apache.org/jira/browse/FINERACT-2988
> Project: Apache Fineract
> Issue Type: Bug
> Components: Savings
> Reporter: LeeYoonMyeong
> Priority: Major
>
> {\{TaxUtils.splitTax}} and \{{TaxUtils.splitTaxData}} compute each tax
> component as
> {code:java}
> double tax = amount.doubleValue() * percentage.doubleValue() / 100.0;
> BigDecimal.valueOf(tax).setScale(scale, MoneyHelper.getRoundingMode());
> {code}
> When the exact product lies on a rounding boundary, the binary double is
> slightly below it, so the configured rounding mode is applied to the wrong
> side. These methods are used for withholding tax on savings interest posting
> (\{{SavingsAccount}}, \{{SavingsAccountInterestPostingServiceImpl}}) and for
> charge tax (\{{ChargeTaxApplicationServiceImpl}}).
> Examples (exact value -> expected -> current):
> * 4.10 at 15 %, scale 2, HALF_EVEN: 0.615 -> 0.62 -> *0.61*
> * 5250 at 1.4 %, scale 0, HALF_EVEN: 73.5 -> 74 -> *73*
> * 5500 at 1.4 %, scale 0, DOWN: 77 -> 77 -> *76*
> I scanned whole amounts 1..1,000,000 at 1.4 % (scale 0) and found 187
> differing amounts under HALF_EVEN and 374 under HALF_UP. Amounts
> 0.01..10,000.00 at 15 % (scale 2) gave 658 differing amounts under HALF_EVEN.
> Rates such as 10 %, 14 % and 16 % gave no differences in these ranges. That
> is why the existing tests (e.g. 1000 at 16 %) pass.
> *Proposed fix:* compute the product exactly with BigDecimal and round once:
> \{{amount.multiply(percentage).movePointLeft(2).setScale(scale,
> MoneyHelper.getRoundingMode())}}. Results change only where the exact value
> is on a rounding boundary. I have a patch with unit tests ready and would
> like to work on this issue.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)