Money Library

The Money library is created to implement MultiCurrency requirement in the Oracle Health Insurance applications. With multicurrency, Oracle Health Insurance will now also keep track of the currency of the amount field wherever required.

This document will detail on how money related objects can be accessed, created, changed in the Oracle Health Insurance applications. It will also detail all the apis available to perform such operations on money objects in Oracle Health Insurance.

Object Model

Money components will be stored in any entity as ONE object. The object will be called as OhiMoney. OhiMoney is an implementation of JSR 354. This JSR will be part of JAVA 9. Oracle Health Insurance will make use of the JSR’s reference implementation JavaMoney.

Groovy: Dynamic Logic

Money manipulation/creation will be required in the dynamic logic. In order to make that possible, Oracle Health InsuranceMoney interface and Money will be included as imports in all the dynamic logic(s).

With the above, it will be possible to seamlessly create money objects and do money related manipulations in groovy.

Some examples are as under:

  • 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 90% 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. Please note that this will have no affect on the allowedAmount money object, as that is not changing unless explicitly assigned. All Oracle Health InsuranceMoney objects are final. Same as for String etc.

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", new java.sql.Date(Date.parse("yyyy-mm-dd", "2015-12-12").getTime()), "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", new java.sql.Date(Date.parse("yyyy-mm-dd", "2015-12-12").getTime()))
  • Create money with Wrong currencyCode, will throw UnknownCurrencyException.

def money = Money.create(10, "BLA"); // Will throw 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

External representation of OhiMoney: Rest/SOAP

All Oracle Health InsuranceMoney attributes will be represented as an element in Rest or SOAP interfaces.

The element structure for REST will be as follows, please note that currencyCode is an optional field. If currencyCode is not provided, it will be defaulted to a predefined logic on usecase basis or to the default currency configured in the Oracle Health Insurance application.

<moneyFieldName currencyCode="" amount="" />

Example:

<benefitInputAmount currencyCode="USD" amount="1000.50" />

Rest layer transformation is required to convert Oracle Health InsuranceMoney object to such a structure and back.

The element structure for SOAP will be based on the xsd. XSD for money related attributes will follow the following definition:

<xsd:complexType name="ohiMoneyType">
    <xsd:attribute name="amount" type="amountType" />
    <xsd:attribute name="currencyCode" type="string03Type" />
</xsd:complexType>

All money attributes will be declared of type ohiMoneyType in the SOAP request.

Features of Oracle Health InsuranceMoney

Oracle Health InsuranceMoney extends the JSR MonetaryAmount. There are a lot of features that are provided on MonetaryAmount. MonetaryAmount (and hence Oracle Health InsuranceMoney) is by design a final implementation. It is similar to datatypes String etc. So any changes to money object gives back a new object. Oracle Health InsuranceMoney implementation is a decorator above the Reference implementation Money object, so most of the methods are delegated to the underlying money object.

Oracle Health InsuranceMoney has following apis exposed:

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 aplied 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 will be divided 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, etc.

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 changedcOhiMoney 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>

All the apis that perform operation on money object do not change the existing money objects. They always return a new instance of the changed money object. As explained earlier, this is because Oracle Health InsuranceMoney is a final object.

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 api(s)

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. See below.

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. A customer may not need/want that precision, but only needs 4. In that case, one can set the ohi.amount.scale to 4.

Note

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.

    Note

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