money icon indicating copy to clipboard operation
money copied to clipboard

10th or 100th of cents support

Open JensDebergh opened this issue 4 years ago • 2 comments

Hi!

I have a question regarding the money gem. I have a client who needs calculations to be done with a precision bigger than 2. I know this gem handles everything up to a precision of 2 perfectly fine since values are stored as the amount of cents as an integer on the table

But what if I would need a smaller "unit" of the money gem to something smaller than cents. Like 10th of a cent or a 100th of a cent.

A value of 1,14 would result in a value of 1140 stored on the table.

To support a bigger precision:

A value of 1,1445 should be stored as 11445 but the unit needs to change to reflect that this is stored as a unit smaller than cents.

Currently 11445 would convert to 11,45 which isn't what I am looking for.

Since the money gem stores data by default as cents I guess this scenario can't be handled by default by this gem is this correct?

I was wondering if it is possible to configure the money to change the unit to 10th or 100th of a cent to enable these kind of scenarios.

Kind regards Jens

JensDebergh avatar Sep 11 '21 19:09 JensDebergh

Just a quick thought: I guess you could define your own currency like USD4 ("USD with exponent 4") and have conversions etc. between USD and your USD4. Not sure how it'd work out, but maybe worth investigating 🤷‍♂️ 🙂

ct-clearhaus avatar Sep 14 '21 08:09 ct-clearhaus

Hey! In the meantime I found the solution to my problem.

Set infinite precision on the money gem:

Money.infinite_precision = true

The column you defined in cents needs to be defined as a bigdecimal with the precision you want.

JensDebergh avatar Sep 14 '21 08:09 JensDebergh

We came across something similar in our apps. We wanted amounts formatted with 4 decimal place precision. We solved it this way:

Money::Currency.register(
  iso_code: "FEE",
  subunit_to_unit: 10000,
  decimal_mark: ".",
  _thousands_separator: ",",
  symbol: "$",
  symbol_first: true,
  name: "Fee",
  symbol_last: false
)

puts Money.from_amount(492.651, 'FEE').format
=> "$492.6510"

radar avatar Jun 14 '23 05:06 radar

The thing is this is a fix mainly for a single currency (which is perfectly fine if you only have to deal with one). If you have to deal with multiple currencies on the other hand this is just a bandaid to the problem.

Ideally we should be able to define the precision on a global configuration level.

JensDebergh avatar Jun 14 '23 07:06 JensDebergh