[Mifos-developer] Mifos Money calculations and MultiCurrency support

2 views
Skip to first unread message

Udai Gupta

unread,
Jan 5, 2010, 5:00:30 AM1/5/10
to Developer
Hi Folks,

Here are some observations after doing some investigation in code.

Q. How can rounding be configured in Mifos?

A. The rounding method of Money class in Mifos implements rounding
using a roundingAmount parameter, default value for this parameter is
stored in database as CURRENCY.ROUNDING_AMOUNT (per currency), you can
override it in applicationConfiguration.custom.xml as
"AccountingRules.AmountToBeRoundedTo" for your default currency.

"AmountToBeRoundedTo" or "roundingAmount" is used to represent the
amount to which you want calculation to be rounded to.

Eg. suppose you want to deal with amount in 50 cents precision. i.e.
AccountingRules.AmountToBeRoundedTo=0.5

A) for amount 14.24 (with celling/rounding up), it will round to 14.50 $
B) for amount 14.24 (with floor/rounding down), it will round to 14.00 $

Eg. suppose you want to deal with amount in 100 $. i.e.
AccountingRules.AmountToBeRoundedTo=100

A) for amount 111 (with celling/rounding up), it will round to 200 $
B) for amount 111 (with floor/rounding down), it will round to100 $

Best place to observe this behavior is
MoneyTest(testRoundUp,testRoundDown) where you can modify RUPEE (to
have roundingAmount what you want).

Q What are the uses of AccountingRules.DigitAfterDecimal and
AccountingRules.DigitBeforeDecimal ?
These two properties are used for validation of input data in string
format, and for view/info display amount fields in UI. In the above
example digitAfterDecimal is set equal to 2, you can set
digitAfterDecimal equal to 3 and the result will be A) 14.500 B)
14.000 for UI, but it doesn't affect rounding.

However digitBeforeDecimal is not configurable at the moment because
it is blocked by the issue
http://mifosforge.jira.com/browse/MIFOS-1537 (hard coded 7 value is used)

Also in some places digitAfterDecimal is used for rounding, eg
MoneyUtils#getMoneyAmount (it should be removed as its probably a bug
in the code).


Q. How calculations on money objects are being performed ?
internalPrecision = 13 and internalRoundingMode =
RoundingMode.HALF_UP(hardcoded) in Money class is being used for
bounding the precision after decimal for BigDecimal#add,
BigDecimal#subtract, BigDecimal#multiply and BigDecimal#divide
calculation. 13 is large value for digits after decimal precision so
this means, its doing calculations with high precision.

I think internalRoundingMode = RoundingMode.HALF_UP can be removed as
the default RoundingMode for BigDecimal calculation is HALF_UP. This
can be done during cleanup on Money class to have more meaningful
documentation and code.

Q What should be settings for Multi-Currency?

IMO, In multi-currency scenario we will need something like,
- AccountingRules.AmountToBeRoundedTo per currency (in database or
config file) to support different rounding modes for each currency
(i.e. nearest 1 USD vs. nearest 1000 LBP). Its up to discussion that
- Should we remove the values from database.
- There should be a validation for properties at application startup
(as Jeff also mentioned this in some thread).
- Should we allow plain config file to have modification scope of
roundingAmount or should we take it as TRAP DOOR setting, it's a very
powerful setting and it could even lead to loss of data if configure
wrong by mistake.


Any argument/comment/suggestion ?

Thanks to Van and Adam Monsen for pairing up with me on this.

Udai

------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev

Adam Monsen

unread,
Jan 6, 2010, 3:36:12 PM1/6/10
to Mifos Developer Discussions
> AccountingRules.AmountToBeRoundedTo

Van, Udai and I have made further progress on this. Looks like the
"AmountToBeRoundedTo" configuration setting (or
currency.ROUNDING_AMOUNT) is only used for rounding when creating
accounting entries. I also spoke with Keith Pierce a bit about rounding
monetary amounts before recording them as accounting entries; it seemed
the only reason that would make sense is if you were doing this to avoid
denominations less than the smallest possible for a given currency.

We are able to see a loan schedule where all payments are rounded to
multiples of 10 by setting the following:
AccountingRules.InitialRoundOffMultiple=10
AccountingRules.FinalRoundOffMultiple=10

These configuration settings are not present in the database.

signature.asc
Reply all
Reply to author
Forward
0 new messages