https://github.com/readysteady/monies
Ruby gem for representing monetary values
https://github.com/readysteady/monies
money ruby
Last synced: 2 months ago
JSON representation
Ruby gem for representing monetary values
- Host: GitHub
- URL: https://github.com/readysteady/monies
- Owner: readysteady
- License: other
- Created: 2024-09-05T09:00:34.000Z (9 months ago)
- Default Branch: main
- Last Pushed: 2025-01-02T13:08:12.000Z (5 months ago)
- Last Synced: 2025-03-10T13:49:17.050Z (3 months ago)
- Topics: money, ruby
- Language: Ruby
- Homepage: https://rubygems.org/gems/monies
- Size: 21.5 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGES.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# monies

Ruby gem for representing monetary values.
Pure Ruby—compatible with MRI/CRuby, JRuby, TruffleRuby, and Natalie.
## Installation
Using Bundler:
$ bundle add monies
Using RubyGems:
$ gem install monies
## Usage
Getting started:
```ruby
require 'monies'a = Monies(11, 'USD')
b = Monies('22.22', 'USD') * 2
c = Monies.parse('$33.44')puts Monies.format(a + b + c, symbol: true)
```## Currencies
Currencies are represented as strings. Using [ISO 4217 currency codes](https://en.wikipedia.org/wiki/ISO_4217)
is recommended for maximum interoperability, however there are no restrictions
on what strings you can use. For example:```ruby
Monies(10, 'USD')
Monies(10, 'BTC')
Monies(10, 'GBX')
Monies(10, 'X')
Monies(10, 'LOL')
Monies(10, 'Cubit')
Monies(10, 'Latinum')
Monies(10, 'sats')
```If your application primarily uses a single currency you can set a default currency:
```ruby
Monies.currency = 'USD'Monies(10)
```## Arithmetic
Arithmetic is currency checked to prevent errors:
```ruby
Monies(1, 'USD') + Monies(1, 'RUB') # raises Monies::CurrencyError
```If you need to sum amounts in different currencies you should first convert
them all to the same currency.Division is limited to 16 decimal places by default, which ought to be enough
for everyone. If you need more accuracy you can use the #div method to specify
the maximum number of decimal places you want:```ruby
Monies(1, 'USD').div(9, 100)
```Use the #allocate method to split an amount into a number of smaller amounts:
```ruby
installments = Monies(1, 'USD').allocate(3, 2)
```## Currency conversion
Use the #convert method to convert instances to another currency:
```ruby
value = Monies('1.23', 'BTC')price = Monies(100_000, 'USD')
puts value.convert(price).round(2)
```Fetching price data, caching that data, and rounding the result are all
responsibilities of the caller.## Parsing strings
Use the `Monies` method to convert strings that are expected to be valid and
don't contain special formatting, such as those in source code and databases:```ruby
Monies('12345.6')
```Use the `Monies.parse` method to parse strings that could be invalid or could
contain special formatting like thousand separators, currency codes, or symbols:```ruby
Monies.parse('£1,999.99')
Monies.parse('1.999,00 EUR')
```An `ArgumentError` exception is raised for invalid input:
```ruby
Monies.parse('notmoney') # raises ArgumentError
```Currency symbols and currency codes are defined in `Monies.symbols` which can
be updated to support additional currencies using #[]= or #update. For example:```ruby
Monies.symbols["\u20BF"] = 'BTC'Monies.symbols.update({"\u20BF" => 'BTC'})
Monies.parse('1,000 BTC')
```## Formatting strings
Use the `Monies.format` method to produce formatted strings:
```ruby
Monies.format(Monies('1234.56', 'USD')) # "1,234.56"
```Specify the `code` or `symbol` options to include the currency code or symbol:
```ruby
Monies.format(Monies('1234.56', 'USD'), code: true) # "1,234.56 USD"Monies.format(Monies('1234.56', 'USD'), symbol: true) # "$1,234.56"
```Specify the name of the format to use different formatting rules:
```ruby
Monies.format(Monies('1234.56', 'USD'), :eu) # "1.234,56"
```The default format is `:en` and can be changed by updating `Monies.formats`,
for example to change the default format to the built-in `:eu` format:```ruby
Monies.formats[:default] = Monies.formats[:eu]
```To create a custom format first create a `Monies::Format` subclass,
and then add the format to `Monies.formats`. For example:```ruby
class CustomFormat < Monies::Format::EN
# ...
endMonies.formats[:custom] = CustomFormat.new
```## BigDecimal integration
Monies integrates with the [bigdecimal gem](https://rubygems.org/gems/bigdecimal)
for multiplication and currency conversion. For example:```ruby
require 'bigdecimal/util'Monies('1.23', 'USD') * BigDecimal('0.1')
```Use the `Monies` method to convert from a `BigDecimal` value:
```ruby
Monies(BigDecimal(10), 'USD')
```Use the #to_d method to convert to a `BigDecimal` value:
```ruby
monies.to_d
```Specify a currency argument to use `BigDecimal` values for currency conversion:
```ruby
monies = Monies('1.11', 'BTC')
monies.convert(BigDecimal(100_000), 'USD').round(2)
```## Percentage integration
Monies integrates with the [percentage gem](https://rubygems.org/gems/percentage)
for percentage calculations. For example:```ruby
require 'percentage'capital_gains = Monies(10_000, 'GBP')
tax_rate = Percentage.new(20)
tax_liability = capital_gains * tax_rate
puts tax_liability
```## Sequel integration
Monies integrates with the [sequel gem](https://rubygems.org/gems/sequel)
to support database serialization. For example:```ruby
class Product < Sequel::Model
plugin Monies::Serialization::Sequelserialize_monies :price
end
```This will serialize the value and the currency as a single string.
You can also specify the currency at the model/application level using the
currency keyword argument:```ruby
serialize_monies :price, currency: Monies.currency
```This will serialize just the value as a single string.
You can also use two columns, one for the value and an additional string column
to store the currency:```ruby
serialize_monies :price, currency: :currency
```## ActiveRecord integration
Monies integrates with the [activerecord gem](https://rubygems.org/gems/activerecord)
to support database serialization. For example:```ruby
class Product < ApplicationRecord
include Monies::Serialization::ActiveRecordserialize_monies :price
end
```Usage of `serialize_monies` is identical to the [sequel integration](#sequel-integration).
## License
Monies is released under the LGPL-3.0 license.