Parent

Namespace

Included Modules

Money

Money is any object or record that is generally accepted as payment for goods and services and repayment of debts in a given socio-economic context or country.” -Wikipedia

An instance of Money represents an amount of a specific currency.

Money is a value object and should be treated as immutable.

@see en.wikipedia.org/wiki/Money

Constants

VERSION

Attributes

conversion_precision[RW]

@attr_accessor [Money::Bank::*] default_bank Each Money object is associated to a bank object, which is responsible for currency exchange. This property allows you to specify the default bank object. The default value for this property is an instance of +Bank::VariableExchange.+ It allows one to specify custom exchange rates. @attr_accessor [Money::Currency] default_currency The default currency, which is used when Money.new is called without an explicit currency argument. The default value is Currency.new(“USD”). The value must be a valid +Money::Currency+ instance. @attr_accessor [true, false] use_i18n Use this to disable i18n even if it’s used by other objects in your app. @attr_accessor [true, false] infinite_precision Use this to enable infinite precision cents @attr_accessor [Integer] conversion_precision Use this to specify precision for converting Rational to BigDecimal

default_bank[RW]

@attr_accessor [Money::Bank::*] default_bank Each Money object is associated to a bank object, which is responsible for currency exchange. This property allows you to specify the default bank object. The default value for this property is an instance of +Bank::VariableExchange.+ It allows one to specify custom exchange rates. @attr_accessor [Money::Currency] default_currency The default currency, which is used when Money.new is called without an explicit currency argument. The default value is Currency.new(“USD”). The value must be a valid +Money::Currency+ instance. @attr_accessor [true, false] use_i18n Use this to disable i18n even if it’s used by other objects in your app. @attr_accessor [true, false] infinite_precision Use this to enable infinite precision cents @attr_accessor [Integer] conversion_precision Use this to specify precision for converting Rational to BigDecimal

default_currency[RW]

@attr_accessor [Money::Bank::*] default_bank Each Money object is associated to a bank object, which is responsible for currency exchange. This property allows you to specify the default bank object. The default value for this property is an instance of +Bank::VariableExchange.+ It allows one to specify custom exchange rates. @attr_accessor [Money::Currency] default_currency The default currency, which is used when Money.new is called without an explicit currency argument. The default value is Currency.new(“USD”). The value must be a valid +Money::Currency+ instance. @attr_accessor [true, false] use_i18n Use this to disable i18n even if it’s used by other objects in your app. @attr_accessor [true, false] infinite_precision Use this to enable infinite precision cents @attr_accessor [Integer] conversion_precision Use this to specify precision for converting Rational to BigDecimal

infinite_precision[RW]

@attr_accessor [Money::Bank::*] default_bank Each Money object is associated to a bank object, which is responsible for currency exchange. This property allows you to specify the default bank object. The default value for this property is an instance of +Bank::VariableExchange.+ It allows one to specify custom exchange rates. @attr_accessor [Money::Currency] default_currency The default currency, which is used when Money.new is called without an explicit currency argument. The default value is Currency.new(“USD”). The value must be a valid +Money::Currency+ instance. @attr_accessor [true, false] use_i18n Use this to disable i18n even if it’s used by other objects in your app. @attr_accessor [true, false] infinite_precision Use this to enable infinite precision cents @attr_accessor [Integer] conversion_precision Use this to specify precision for converting Rational to BigDecimal

rounding_mode[W]

@attr_writer rounding_mode Use this to specify the rounding mode

use_i18n[RW]

@attr_accessor [Money::Bank::*] default_bank Each Money object is associated to a bank object, which is responsible for currency exchange. This property allows you to specify the default bank object. The default value for this property is an instance of +Bank::VariableExchange.+ It allows one to specify custom exchange rates. @attr_accessor [Money::Currency] default_currency The default currency, which is used when Money.new is called without an explicit currency argument. The default value is Currency.new(“USD”). The value must be a valid +Money::Currency+ instance. @attr_accessor [true, false] use_i18n Use this to disable i18n even if it’s used by other objects in your app. @attr_accessor [true, false] infinite_precision Use this to enable infinite precision cents @attr_accessor [Integer] conversion_precision Use this to specify precision for converting Rational to BigDecimal

bank[R]

@attr_reader [Currency] currency The currency the money is in. @attr_reader [Money::Bank::*] bank The +Money::Bank+ based object used to perform currency exchanges with.

currency[R]

@attr_reader [Currency] currency The currency the money is in. @attr_reader [Money::Bank::*] bank The +Money::Bank+ based object used to perform currency exchanges with.

Public Class Methods

add_rate(from_currency, to_currency, rate) click to toggle source

Adds a new exchange rate to the default bank and return the rate.

@param [Currency, String, Symbol] from_currency Currency to exchange from. @param [Currency, String, Symbol] to_currency Currency to exchange to. @param [Numeric] rate Rate to exchange with.

@return [Numeric]

@example

Money.add_rate("USD", "CAD", 1.25) #=> 1.25
# File lib/money/money.rb, line 212
def self.add_rate(from_currency, to_currency, rate)
  Money.default_bank.add_rate(from_currency, to_currency, rate)
end
ca_dollar(cents) click to toggle source

Creates a new Money object of the given value, using the Canadian dollar currency.

@param [Integer] cents The cents value.

@return [Money]

@example

n = Money.ca_dollar(100)
n.cents    #=> 100
n.currency #=> #<Money::Currency id: cad>
# File lib/money/money.rb, line 169
def self.ca_dollar(cents)
  Money.new(cents, "CAD")
end
disallow_currency_conversion!() click to toggle source

Sets the default bank to be a SingleCurrency bank that raises on currency exchange. Useful when apps operate in a single currency at a time.

# File lib/money/money.rb, line 218
def self.disallow_currency_conversion!
  self.default_bank = Bank::SingleCurrency.instance
end
empty(currency = default_currency) click to toggle source

Create a new money object with value 0.

@param [Currency, String, Symbol] currency The currency to use.

@return [Money]

@example

Money.empty #=> #<Money @fractional=0>
# File lib/money/money.rb, line 92
def empty(currency = default_currency)
  @empty ||= {}
  @empty[currency] ||= Money.new(0, currency)
end
Also aliased as: zero
euro(cents) click to toggle source

Creates a new Money object of the given value, using the Euro currency.

@param [Integer] cents The cents value.

@return [Money]

@example

n = Money.euro(100)
n.cents    #=> 100
n.currency #=> #<Money::Currency id: eur>
# File lib/money/money.rb, line 198
def self.euro(cents)
  Money.new(cents, "EUR")
end
inherited(base) click to toggle source
# File lib/money/money.rb, line 127
def self.inherited(base)
  base.setup_defaults
end
new(obj, currency = Money.default_currency, bank = Money.default_bank) click to toggle source

Creates a new Money object of value given in the +fractional unit+ of the given currency.

Alternatively you can use the convenience methods like {Money.ca_dollar} and {Money.us_dollar}.

@param [Numeric] fractional The value given in the fractional unit. @param [Currency, String, Symbol] currency The currency format. @param [Money::Bank::*] bank The exchange bank to use.

@return [Money]

@example

Money.new(100)        #=> #<Money @fractional=100 @currency="USD">
Money.new(100, "USD") #=> #<Money @fractional=100 @currency="USD">
Money.new(100, "EUR") #=> #<Money @fractional=100 @currency="EUR">
# File lib/money/money.rb, line 239
def initialize(obj, currency = Money.default_currency, bank = Money.default_bank)
  @fractional = obj.fractional
  @currency   = obj.currency
  @bank       = obj.bank
rescue NoMethodError
  @fractional = as_d(obj)
  @currency   = Currency.wrap(currency)
  @bank       = bank
end
rounding_mode(mode=nil) click to toggle source

Use this to return the rounding mode. You may also pass a rounding mode and a block to temporatly change it. It will then return the results of the block instead.

@param [BigDecimal::ROUND_MODE] optional

@return [BigDecimal::ROUND_MODE,Yield] rounding mode or block results

@example

fee = Money.rounding_mode(BigDecimal::ROUND_HALF_UP) do
  Money.new(1200) * BigDecimal.new('0.029')
end
# File lib/money/money.rb, line 145
def self.rounding_mode(mode=nil)
  if mode.nil?
    Thread.current[:money_rounding_mode] || @rounding_mode
  else
    begin
      Thread.current[:money_rounding_mode] = mode
      yield
    ensure
      Thread.current[:money_rounding_mode] = nil
    end
  end
end
setup_defaults() click to toggle source
# File lib/money/money.rb, line 107
def self.setup_defaults
  # Set the default bank for creating new +Money+ objects.
  self.default_bank = Bank::VariableExchange.instance

  # Set the default currency for creating new +Money+ object.
  self.default_currency = Currency.new("USD")

  # Default to using i18n
  self.use_i18n = true

  # Default to not using infinite precision cents
  self.infinite_precision = false

  # Default to bankers rounding
  self.rounding_mode = BigDecimal::ROUND_HALF_EVEN

  # Default the conversion of Rationals precision to 16
  self.conversion_precision = 16
end
us_dollar(cents) click to toggle source

Creates a new Money object of the given value, using the American dollar currency.

@param [Integer] cents The cents value.

@return [Money]

@example

n = Money.us_dollar(100)
n.cents    #=> 100
n.currency #=> #<Money::Currency id: usd>
# File lib/money/money.rb, line 184
def self.us_dollar(cents)
  Money.new(cents, "USD")
end
zero(currency = default_currency) click to toggle source
Alias for: empty

Public Instance Methods

allocate(splits) click to toggle source

Allocates money between different parties without loosing pennies. After the mathmatically split has been performed, left over pennies will be distributed round-robin amongst the parties. This means that parties listed first will likely recieve more pennies then ones that are listed later

@param [Array<Numeric>] splits [0.50, 0.25, 0.25] to give 50% of the cash to party1, 25% to party2, and 25% to party3.

@return [Array<Money>]

@example

Money.new(5,   "USD").allocate([0.3, 0.7])         #=> [Money.new(2), Money.new(3)]
Money.new(100, "USD").allocate([0.33, 0.33, 0.33]) #=> [Money.new(34), Money.new(33), Money.new(33)]
# File lib/money/money.rb, line 463
def allocate(splits)
  allocations = allocations_from_splits(splits)

  if (allocations - BigDecimal("1")) > Float::EPSILON
    raise ArgumentError, "splits add to more then 100%"
  end

  amounts, left_over = amounts_from_splits(allocations, splits)

  unless self.class.infinite_precision
    left_over.to_i.times { |i| amounts[i % amounts.length] += 1 }
  end

  amounts.collect { |fractional| Money.new(fractional, currency) }
end
amount() click to toggle source

Returns the numerical value of the money

@return [BigDecimal]

@example

Money.new(1_00, "USD").amount    # => BigDecimal.new("1.00")

@see to_d @see fractional

# File lib/money/money.rb, line 278
def amount
  to_d
end
as_ca_dollar() click to toggle source

Receive a money object with the same amount as the current Money object in canadian dollar.

@return [Money]

@example

n = Money.new(100, "USD").as_ca_dollar
n.currency #=> #<Money::Currency id: cad>
# File lib/money/money.rb, line 434
def as_ca_dollar
  exchange_to("CAD")
end
as_euro() click to toggle source

Receive a money object with the same amount as the current Money object in euro.

@return [Money]

@example

n = Money.new(100, "USD").as_euro
n.currency #=> #<Money::Currency id: eur>
# File lib/money/money.rb, line 446
def as_euro
  exchange_to("EUR")
end
as_us_dollar() click to toggle source

Receive a money object with the same amount as the current Money object in american dollars.

@return [Money]

@example

n = Money.new(100, "CAD").as_us_dollar
n.currency #=> #<Money::Currency id: usd>
# File lib/money/money.rb, line 422
def as_us_dollar
  exchange_to("USD")
end
cents() click to toggle source

Convenience method for fractional part of the amount. Synonym of fractional

@return [Integer] when inifinte_precision is false @return [BigDecimal] when inifinte_precision is true

@see infinite_precision

# File lib/money/money.rb, line 24
def cents
  fractional
end
currency_as_string() click to toggle source

Return string representation of currency object

@return [String]

@example

Money.new(100, :USD).currency_as_string #=> "USD"
# File lib/money/money.rb, line 288
def currency_as_string
  currency.to_s
end
currency_as_string=(val) click to toggle source

Set currency object using a string

@param [String] val The currency string.

@return [Money::Currency]

@example

Money.new(100).currency_as_string("CAD") #=> #<Money::Currency id: cad>
# File lib/money/money.rb, line 300
def currency_as_string=(val)
  @currency = Currency.wrap(val)
end
dollars() click to toggle source

Assuming using a currency using dollars: Returns the value of the money in dollars, instead of in the fractional unit cents.

Synonym of amount

@return [BigDecimal]

@example

Money.new(1_00, "USD").dollars   # => BigDecimal.new("1.00")

@see amount @see to_d @see cents

# File lib/money/money.rb, line 264
def dollars
  amount
end
exchange_to(other_currency, &rounding_method) click to toggle source

Receive the amount of this money object in another Currency.

@param [Currency, String, Symbol] other_currency Currency to exchange to.

@yield [n] Optional block to use when rounding after exchanging one currency

for another.

@yieldparam [Float] n The resulting float after exchanging one currency for

another.

@yieldreturn [Integer]

@return [Money]

@example

Money.new(2000, "USD").exchange_to("EUR")
Money.new(2000, "USD").exchange_to("EUR") {|x| x.round}
Money.new(2000, "USD").exchange_to(Currency.new("EUR"))
# File lib/money/money.rb, line 405
def exchange_to(other_currency, &rounding_method)
  other_currency = Currency.wrap(other_currency)
  if self.currency == other_currency
    self
  else
    @bank.exchange_with(self, other_currency, &rounding_method)
  end
end
fractional() click to toggle source

The value of the monetary amount represented in the fractional or subunit of the currency.

For example, in the US Dollar currency the fractional unit is cents, and there are 100 cents in one US Dollar. So given the Money representation of one US dollar, the fractional interpretation is 100.

Another example is that of the Kuwaiti Dinar. In this case the fractional unit is the Fils and there 1000 Fils to one Kuwaiti Dinar. So given the Money representation of one Kuwaiti Dinar, the fractional interpretation is 1000.

@return [Integer] when inifinte_precision is false @return [BigDecimal] when inifinte_precision is true

@see infinite_precision

# File lib/money/money.rb, line 44
def fractional
  # Ensure we have a BigDecimal. If the Money object is created
  # from YAML, @fractional can end up being set to a Float.
  fractional = as_d(@fractional)

  if self.class.infinite_precision
    fractional
  else
    fractional.round(0, self.class.rounding_mode).to_i
  end
end
hash() click to toggle source

Returns a Fixnum hash value based on the fractional and currency attributes in order to use functions like & (intersection), group_by, etc.

@return [Fixnum]

@example

Money.new(100).hash #=> 908351
# File lib/money/money.rb, line 311
def hash
  [fractional.hash, currency.hash].hash
end
inspect() click to toggle source

Common inspect function

@return [String]

# File lib/money/money.rb, line 328
def inspect
  "#<Money fractional:#{fractional} currency:#{currency}>"
end
localize_formatting_rules(rules) click to toggle source
# File lib/money/money/formatting.rb, line 301
def localize_formatting_rules(rules)
  if currency.iso_code == "JPY" && I18n.locale == :ja
    rules[:symbol] = "円" unless rules[:symbol] == false
    rules[:symbol_position] = :after
    rules[:symbol_after_without_space] = true
  end
  rules
end
regexp_format(formatted, rules, decimal_mark, symbol_value) click to toggle source
# File lib/money/money/formatting.rb, line 287
def regexp_format(formatted, rules, decimal_mark, symbol_value)
  regexp_decimal = Regexp.escape(decimal_mark)
  if rules[:south_asian_number_formatting]
    /(\d+?)(?=(\d\d)+(\d)(?:\.))/
  else
    # Symbols may contain decimal marks (E.g "դր.")
    if formatted.sub(symbol_value.to_s, "") =~ /#{regexp_decimal}/
      /(\d)(?=(?:\d{3})+(?:#{regexp_decimal}))/
    else
      /(\d)(?=(?:\d{3})+(?:[^\d]{1}|$))/
    end
  end
end
round(rounding_mode = self.class.rounding_mode) click to toggle source

Round the monetary amount to smallest unit of coinage.

@note

This method is only useful when operating with infinite_precision turned
on. Without infinite_precision values are rounded to the smallest unit of
coinage automatically.

@return [Money]

@example

Money.new(10.1, 'USD').round #=> Money.new(10, 'USD')

@see

Money.infinite_precision
# File lib/money/money.rb, line 512
def round(rounding_mode = self.class.rounding_mode)
  if self.class.infinite_precision
    Money.new(fractional.round(0, rounding_mode), self.currency)
  else
    self
  end
end
split(num) click to toggle source

Split money amongst parties evenly without loosing pennies.

@param [Numeric] num number of parties.

@return [Array<Money>]

@example

Money.new(100, "USD").split(3) #=> [Money.new(34), Money.new(33), Money.new(33)]
# File lib/money/money.rb, line 487
def split(num)
  raise ArgumentError, "need at least one party" if num < 1

  if self.class.infinite_precision
    split_infinite(num)
  else
    split_flat(num)
  end
end
symbol() click to toggle source

Uses +Currency#symbol+. If nil is returned, defaults to “¤”.

@return [String]

@example

Money.new(100, "USD").symbol #=> "$"
# File lib/money/money.rb, line 321
def symbol
  currency.symbol || "¤"
end
symbol_position_from(rules) click to toggle source
# File lib/money/money/formatting.rb, line 326
def symbol_position_from(rules)
  if rules.has_key?(:symbol_position)
    rules[:symbol_position]
  elsif currency.symbol_first?
    :before
  else
    :after
  end
end
symbol_value_from(rules) click to toggle source
# File lib/money/money/formatting.rb, line 310
def symbol_value_from(rules)
  if rules.has_key?(:symbol)
    if rules[:symbol] === true
      symbol
    elsif rules[:symbol]
      rules[:symbol]
    else
      ""
    end
  elsif rules[:html]
    currency.html_entity == '' ? currency.symbol : currency.html_entity
  else
    symbol
  end
end
to_d() click to toggle source

Return the amount of money as a BigDecimal.

@return [BigDecimal]

@example

Money.us_dollar(1_00).to_d #=> BigDecimal.new("1.00")
# File lib/money/money.rb, line 360
def to_d
  as_d(fractional) / as_d(currency.subunit_to_unit)
end
to_f() click to toggle source

Return the amount of money as a float. Floating points cannot guarantee precision. Therefore, this function should only be used when you no longer need to represent currency or working with another system that requires floats.

@return [Float]

@example

Money.us_dollar(100).to_f #=> 1.0
# File lib/money/money.rb, line 373
def to_f
  to_d.to_f
end
to_money(given_currency = nil) click to toggle source

Conversation to self.

@return [self]

# File lib/money/money.rb, line 380
def to_money(given_currency = nil)
  given_currency = Currency.wrap(given_currency)
  if given_currency.nil? || self.currency == given_currency
    self
  else
    exchange_to(given_currency)
  end
end
to_s() click to toggle source

Returns the amount of money as a string.

@return [String]

@example

Money.ca_dollar(100).to_s #=> "1.00"
# File lib/money/money.rb, line 338
def to_s
  unit, subunit, fraction = strings_from_fractional

  str = if currency.decimal_places == 0
          if fraction == ""
            unit
          else
            "#{unit}#{decimal_mark}#{fraction}"
          end
        else
          "#{unit}#{decimal_mark}#{pad_subunit(subunit)}#{fraction}"
        end

  fractional < 0 ? "-#{str}" : str
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.