Money Library

The Money library implements multi currency in the Oracle Health Insurance applications. With multi currency, Oracle Health Insurance keeps track of the currency of the Amount field.

This document details how to access, create, and change money related objects in the Oracle Health Insurance applications.

Object Model

Money components are stored in any entity as a single object of type OhiMoney.

Groovy: Dynamic Logic

Create and manipulate a Money value through dynamic logic.

Some examples:

  • Create Money and add 30 to the amount. Set the result to a money field on claim.

claim.benefitInputAmount = Money.create(10, "EUR") + 30
  • Create Money and subtract 30 from the amount. Set the result to a money field on claim.

claim.benefitInputAmount = Money.create(40, "EUR") - 30
  • Create Money and divide it by 5. Set the result to a money field on claim.

claim.benefitInputAmount = Money.create(10, "EUR") / 5
  • Create Money and get 9% of the amount. Set the result to a money field on claim.

claim.benefitInputAmount = Money.create(10, "EUR") * .09
  • Get the money attribute from one field and change the amount on it and set the result to another money field on claim.

This does not affect the allowedAmount money object, as that is not changing unless explicitly assigned. All OhiMoney objects are immutable.

claim.benefitInputAmount = claim.allowedAmount.changeAmount(100)
  • Fetch exchange rate giving the required parameters along with context information. In this example fetch the exchange rate from USD to EUR on 12 Dec 2012 in context "LIBERTY".

return getExchangeRate("USD", "EUR", java.sql.Date.valueOf("2015-12-12"), "LIBERTY")
  • Fetch exchange rate giving the required parameters along without context information. In this example fetch the exchange rate from USD to EUR on 12 Dec 2012 in default(no) context.

return getExchangeRate("USD", "EUR", java.sql.Date.valueOf("2021-12-12"))
  • Create money with Wrong currencyCode, throws UnknownCurrencyException.

def money = Money.create(10, "BLA");
// throws GEN-CURR-001 (Unknown currency code exception)
  • Fetching the amount value on the money object and setting it on a variable(like in ctrClaim)

ctrClaim.totalCoveredAmount = claim.totalCoveredAmount.amount
  • Fetching the currencyCode value on the money object and setting it on a variable(like in ctrClaim)

ctrClaim.totalCoveredAmountCurrency = claim.totalCoveredAmount.currencyCode

Features of OhiMoney

OhiMoney extends the JSR MonetaryAmount. There are a lot of features that are provided on MonetaryAmount. MonetaryAmount (and hence OhiMoney) is by design a final implementation. It is similar to string data type. So any changes to a money object gives back a new object, leaving the original one unchanged.

OhiMoney exposes the following APIs:

Table 1. Features of OhiMoney
Method Description

abs()

Gives the absolute value of the money amount value.

add(BigDecimal)

Adds the amount parameter to the money object and returns the changed OhiMoney object.

add(MonetaryAmount)

Returns the sum of the two money objects, only if the currencies are same. If currencies are not same, it throws MonetaryException.

changeAmount(BigDecimal)

Changes the amount value on the money object and returns the changed object.

changeCurrency(String)

Fetches the currency for the passed in currency code. If the currency is not found, exception is thrown. If currency is found, changes the currency on the money object and returns the changed object.

changeCurrency(CurrencyUnit)

Changes the currency on the money object and returns the changed object

convert(String,Date)

Fetches the exchange rate for the currencyCode on the money object, targetCurrencyCode(passed in as a parameter) and reference date(passed in as a parameter). If the exchange rate is found, the API converts the money object using the exchange rate and changes the currency. It then returns the converted money object.

convert(String,String,Date)

Fetches the exchange rate for the currencyCode on the money object, targetCurrencyCode(passed in as a parameter), contextCode((passed in as a parameter) and reference date(passed in as a parameter). If the exchange rate is found, the API converts the money object using the exchange rate and changes the currency. It then returns the converted money object.

convert(ExchangeRate)

Converts the money object using the exchange rate and changes the currency stored in the exchange rate. It then returns the converted money object.

convert(BigDecimal,String)

Converts the money object using the exchange rate(passed in as a parameter) and changes the currency to the targetCurrencyCode(passed in as a parameter). If there is no currency found for the passed in parameter, an exception is thrown, else, it then returns the converted money object.

copy()

Creates a copy of the money objects and returns it.

divide(long/Double/Number)

Divides the money object by the passed in parameter. Returns the changed money object.

divideAndRemainder(long/double/Number)

Divides the money object by the passed in parameter. Returns the result and remainder in an array of money object respectively.

divideToIntegralValue(long/double/Number)

Divides the money object by the passed in parameter. Returns the changed money object with the rounded down amount value

getAmount()

Returns the amount part of the money object

getCurrenyCode()

Returns the currency code of the money object.

getDisplayCode()

Returns the displayCode of the currency of the money object.

multiply(long/double/Number)

Multiplies the money object by the passed in parameter. Returns the changed money object.

negate()

Negates the amount part of the money object and returns the changed object.

percentage(BigDecimal)

Calculates the percentage of the money object using the passed in parameters and returns the changed object.

plus()

This is opposite of negate. It converts the negative amount to positive and returns the changed money object. If the amount in the money object is already positive, then there is no change.

remainder(long/double/Number)

Divides the money object by the passed in parameter. Returns the remainder.

reverseConvert(ExchangeRate)

This API comes handy when an exchange rate is already applied to a money object, and the same exchange rate is to be used to convert the money object back to its original currency. In this API, the money object divides with the rate rather than multiplying. The currency on the changed money object is set to the base currency on exchange rate.

round()

Rounds the money object to the nearest n decimal points using the HALF_UP rounding mode and returns the changed money object.

n is the value of the system property ohi.amount.scale. If this property is not set, n=2

round(int)

Rounds the money object based on the provided scale using the HALF_UP rounding mode and returns the changed money object.

For example:
scale 2 means round to the nearest 2 decimal points,
scale 1 means round to the nearest 1 decimal,
scale 0 means round to the nearest integer,
scale -1 means round to the nearest multiple of 10,
scale -2 means round to the nearest multiple of 100, and so on.

round(RoundingMode)

Rounds the money object according to the RoundingMode passed in as a parameter and returns the changed money object.

round(int, RoundingMode)

Rounds the money object according to the scale and RoundingMode passed in as parameters and returns the changed money object.

scaleByPowerOfTen(int)

Scales the amount by power of 10 and returns the changed money object.

stripTrailingZeros()

Strips the trailing zeros in the amount part of the money object and returns the changed money object.

subtract(BigDecimal)

Subtracts the amount parameter to the money object and returns the changed Money object.

subtract(MonetaryAmount)

Returns the difference of the two money objects, only if the currencies are same. If currencies are not same, it throws MonetaryException.

toPlainString()

Returns the string representation of the money object is the format of <amount with 2 decimal points><space><currency displayCode>

Money

To provide factory API to create money objects, there is an Money factory provided. The available methods on this factory can be seen below:

Money

Details of the API for the Money creation:

  • create(long/double/Number, CurrencyUnit): Helper methods to create money objects.

  • <strong>create(long/double/Number, String)</strong>: Helper methods to create money objects. This method fetches the currency with the passed in currencyCode. If currency is not found, an exception is thrown back.

  • <strong>create(</strong>long/double/Number): Helper methods to create money objects with defaultCurrency.

Static APIs

To provide some basic operations regarding money objects, like fetching default currency or fetching exchange rates between two currencyCodes etc, some static methods are also available. Details of the same are as under:

  • amount(OhiMoney): Returns the amount value of the money object if the money object is not null, else null.

  • defaultCurrency(): Returns the default currency setup in the Oracle Health Insurance application.

  • getCurrencies(): Returns all the currencies set up in the Oracle Health Insurance application.

  • getCurrenciesSorted(): Returns all the currencies set up in the Oracle Health Insurance application sorted on displayCode of the currency.

  • getCurrency(String): Fetches the currency for the passed in currency code. If not found, throws an exception.

  • getExchangeRate(String,String,Date,String): Fetches the exchange rate based on the passed in parameters, baseCurrencyCode, targetCurrencyCode, referenceDate and context.

  • getExchangeRate(String,String,Date): Fetches the exchange rate based on the passed in parameters, baseCurrencyCode, targetCurrencyCode and referenceDate.

Rounding and Formatting

Money amounts are rounded by default using a scale factor. Different rounding strategies exist:

In general, the number of decimal places (scale) available in money objects, matches the precision of the field as defined in the database. This precision can also be inspected using Swagger metadata:

Swagger metadata snippet of a field that can store 4 decimals:

"value": {
  "type": "number",
  "xml": {
    "attribute": true
  },
  "minimum": -9999999999.9999,
  "maximum": 9999999999.9999
}

In a limited number of special cases, the scale is less than the precision of the field. For example, in the Policies application, financial results can have up to 12 decimal places. Some customer may not want that precision, but only needs 4. In that case, one can set the ohi.amount.scale to 4.

When the ohi.amount.scale property is not set, the scale of 2 is used

In Oracle Health Insurance applications, the amount fields in UI are always formatted using the locale information.

For IPs, the amount field follows a pattern of total 12 digits with 2 decimal places with an exception for amount fields with greater specificity of total 22 digits with 12 decimal places.

Money related attributes can be searched using the following query keys:

  • Amount: For the amount part, use <attributeName>_amount as the attribute name to search on

  • Currency: For the currency part, use <attributeName>_currency[.code] as the attribute name to search on.

The amount and currency fields have no database index. This has performance implications when searching on those fields, especially in large tables. It is advisable to included other search criteria that are indexed.