/** * Obtains an instance of {@code Money} for the specified currency and amount. * * @param currency the currency the amount is in * @param amount the amount of the currency to represent, as an instance of {@link BigDecimal} * @return the currency amount */ public static Money of(Currency currency, BigDecimal amount) { return new Money(currency, amount); }
@Test public void testConvertedToWithRateProvider() throws Exception { FxRateProvider provider = (ccy1, ccy2) -> 2.5d; assertEquals(Money.of(Currency.RON, 250.30), MONEY_100_AUD.convertedTo(CCY_RON, provider)); assertEquals(Money.of(Currency.RON, 200.23), MONEY_200_RON.convertedTo(CCY_RON, provider)); }
/** * Converts the current instance of {@link CurrencyAmount} to the equivalent {@link Money} instance. * This will result into loss of precision in the amount, since {@link Money} is storing the amount * rounded to the currency specification. * * @return The newly created instance of {@link Money}. */ public Money toMoney() { return Money.of(this.getCurrency(), this.getAmount()); }
@Test public void testOfCurrencyAmount() throws Exception { assertEquals(MONEY_200_RON.getCurrency(), CCY_RON); assertEquals(MONEY_200_RON.getAmount(), new BigDecimal(AMT_200_23).setScale(2, RoundingMode.HALF_EVEN)); }
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Unable to parse amount: 200.23 RON") public void testParseWrongFormat() throws Exception { Money.parse("200.23 RON"); }
@Test public void testToString() throws Exception { assertEquals("RON 200.23", MONEY_200_RON.toString()); }
@Test public void testConvertedToWithExplicitRate() throws Exception { assertEquals(Money.of(Currency.RON, 200.23), MONEY_200_RON.convertedTo(CCY_RON, BigDecimal.valueOf(1))); assertEquals(Money.of(Currency.RON, 260.31), MONEY_100_AUD.convertedTo(CCY_RON, BigDecimal.valueOf(2.6d))); }
/** * Converts this amount to an equivalent amount the specified currency. * <p> * The result will be expressed in terms of the given currency, converting * using the specified FX rate. * <p> * For example, if this represents 'GBP 100' and this method is called with * arguments {@code (USD, 1.6)} then the result will be 'USD 160'. * * @param resultCurrency the currency of the result * @param fxRate the FX rate from this currency to the result currency * @return the converted instance, which should be expressed in the specified currency * @throws IllegalArgumentException if the FX is not 1 when no conversion is required */ public Money convertedTo(Currency resultCurrency, BigDecimal fxRate) { if (currency.equals(resultCurrency)) { if (DoubleMath.fuzzyEquals(fxRate.doubleValue(), 1d, 1e-8)) { return this; } throw new IllegalArgumentException("FX rate must be 1 when no conversion required"); } return Money.of(resultCurrency, amount.multiply(fxRate)); }
@Test public void testOfCurrencyAndAmount() throws Exception { assertEquals(MONEY_100_AUD.getCurrency(), CCY_AUD); assertEquals(MONEY_100_AUD.getAmount(), new BigDecimal(AMT_100_12).setScale(2, RoundingMode.HALF_UP)); assertEquals(MONEY_100_13_AUD.getCurrency(), CCY_AUD); assertEquals(MONEY_100_13_AUD.getAmount(), BigDecimal.valueOf(AMT_100_12).setScale(2, RoundingMode.HALF_UP)); //Testing the rounding from 3 to 2 decimals assertEquals(MONEY_100_12_BHD.getCurrency(), CCY_BHD); assertEquals(MONEY_100_12_BHD.getAmount(), BigDecimal.valueOf(AMT_100_12).setScale(3, RoundingMode.HALF_UP)); assertEquals(MONEY_100_125_BHD.getCurrency(), CCY_BHD); assertEquals(MONEY_100_125_BHD.getAmount(), BigDecimal.valueOf(100.125)); //Testing the rounding from 4 to 3 decimals }
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Unable to parse amount, invalid format: [$]100") public void testParseWrongElementsNumber() throws Exception { Money.parse("$100"); }
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "FX rate must be 1 when no conversion required") public void testConvertedToWithExplicitRateForSameCurrency() throws Exception { assertEquals(Money.of(Currency.RON, 200.23), MONEY_200_RON.convertedTo(CCY_RON, BigDecimal.valueOf(1.1))); }
/** * Converts this amount to an equivalent amount in the specified currency. * <p> * The result will be expressed in terms of the given currency. * If conversion is needed, the provider will be used to supply the FX rate. * * @param resultCurrency the currency of the result * @param rateProvider the provider of FX rates * @return the converted instance, in the specified currency * @throws RuntimeException if no FX rate could be found */ @Override public Money convertedTo(Currency resultCurrency, FxRateProvider rateProvider) { if (currency.equals(resultCurrency)) { return this; } double converted = rateProvider.convert(amount.doubleValue(), currency, resultCurrency); return Money.of(resultCurrency, converted); }
/** * Obtains an instance of {@code Money} for the specified currency and amount. * * @param currency the currency the amount is in * @param amount the amount of the currency to represent * @return the currency amount */ public static Money of(Currency currency, double amount) { return new Money(currency, BigDecimal.valueOf(amount)); }
/** * Obtains an instance of {@code Money} for the specified {@link CurrencyAmount}. * * @param currencyAmount the instance of {@link CurrencyAmount} wrapping the currency and amount. * @return the currency amount */ public static Money of(CurrencyAmount currencyAmount) { return new Money(currencyAmount.getCurrency(), BigDecimal.valueOf(currencyAmount.getAmount())); }
/** * Parses the string to produce a {@link Money}. * <p> * This parses the {@code toString} format of '${currency} ${amount}'. * * @param amountStr the amount string * @return the currency amount * @throws IllegalArgumentException if the amount cannot be parsed */ @FromString public static Money parse(String amountStr) { ArgChecker.notNull(amountStr, "amountStr"); List<String> split = Splitter.on(' ').splitToList(amountStr); if (split.size() != 2) { throw new IllegalArgumentException("Unable to parse amount, invalid format: " + amountStr); } try { Currency cur = Currency.parse(split.get(0)); return new Money(cur, new BigDecimal(split.get(1))); } catch (RuntimeException ex) { throw new IllegalArgumentException("Unable to parse amount: " + amountStr, ex); } }