JavaMoney / jsr354-ri

JSR 354 - Moneta: Reference Implementation
Other
334 stars 100 forks source link

Money.of with scaled BigDecimal leads to unexpected getNumber value #375

Closed l-ray closed 1 year ago

l-ray commented 2 years ago

When a MonetaryAmount is instantiated with a scaled BigDecimal, then extracting the big decimal using Money#getNumber leads to a BigDecimal with unexpected scale (e.g. "-1").

Example

    @Test
    void whenMonetaReceivesBigDecimal_thenItHandlesItAccordingly(){
        BigDecimal amount = BigDecimal.valueOf(1000,2);

        Money money = Money.of(amount, "EUR");
        assertEquals("EUR 10.00", money.toString());
        assertEquals(amount, money.getNumber().numberValueExact(BigDecimal.class));
    }

... leads to the following test-failure ...

java.lang.AssertionError: 
Expected :1E+1
Actual   :10.00

Background

Using Hibernate with the Jadira multi column user type (or any other Hibernate user type I guess) leads to creation of BigDecimal with a given scale. When on the other end the service returns e.g. BigDecimal - this leads to false service responses.

Workaround

Creating a new BigDecimal with the currencies scale solves the issue.

assertEquals(
  amount,
  money.getNumber().numberValueExact(BigDecimal.class)
    .setScale(money.getCurrency().getDefaultFractionDigits())
);
keilw commented 1 year ago

Not sure, which version of Moneta you used for this, but after #357 has been addressed, the assertion would fail:

     BigDecimal amount = BigDecimal.valueOf(1000,2);
     Money money = Money.of(amount , "EUR");
     assertEquals(money.toString(), "EUR 10.00");

java.lang.AssertionError:
Expected :EUR 10.00
Actual   :EUR 10

And you may tweak your Money

     BigDecimal amount = BigDecimal.valueOf(1000,2);
     Money money = Money.of(amount , "EUR", MonetaryContextBuilder.of().setMaxScale(2).setFixedScale(true).build());
     assertEquals(money.toString(), "EUR 10.00");

To set the desired scale, otherwise it takes the scale of the BigDecimalwhich was 0 in the initial example.