Class: Money
- Inherits:
-
Object
- Object
- Money
- Includes:
- Comparable
- Defined in:
- lib/money/money.rb,
lib/money/errors.rb,
lib/money/exchange_bank.rb
Overview
bank.exchange(100_00, “USD”, “CAD”) # => 6450
Defined Under Namespace
Classes: ExchangeBank, UnknownRate
Constant Summary collapse
- CURRENCIES =
{ "USD" => { :delimiter => ",", :separator => ".", :symbol => "$" }, "CAD" => { :delimiter => ",", :separator => ".", :symbol => "$" }, "HKD" => { :delimiter => ",", :separator => ".", :symbol => "$" }, "SGD" => { :delimiter => ",", :separator => ".", :symbol => "$" }, "BRL" => { :delimiter => ".", :separator => ",", :symbol => "R$ " }, "ZWD" => { :delimiter => ",", :separator => ".", :symbol => "Z$"}, "EUR" => { :delimiter => ",", :separator => ".", :symbol => '€', :html => '€' }, "GBP" => { :delimiter => ",", :separator => ".", :symbol => '£', :html => '£' }, "JPY" => { :delimiter => ".", :separator => ".", :symbol => '¥', :html => '¥' }, }
Class Attribute Summary collapse
-
.default_bank ⇒ Object
Each Money object is associated to a bank object, which is responsible for currency exchange.
-
.default_currency ⇒ Object
the default currency, which is used when
Money.new
is called without an explicit currency argument.
Instance Attribute Summary collapse
-
#bank ⇒ Object
readonly
Returns the value of attribute bank.
-
#cents ⇒ Object
(also: #to_i)
readonly
Returns the value of attribute cents.
-
#currency ⇒ Object
readonly
Returns the value of attribute currency.
Class Method Summary collapse
- .add_rate(*params) ⇒ Object
-
.ca_dollar(cents) ⇒ Object
Creates a new Money object of the given value, using the Canadian dollar currency.
-
.empty(currency = default_currency) ⇒ Object
Create a new money object with value 0.
-
.euro(cents) ⇒ Object
Creates a new Money object of the given value, using the Euro currency.
-
.real(cents) ⇒ Object
Creates a new Money object of the given value, using the Brazilian Real currency.
-
.us_dollar(cents) ⇒ Object
Creates a new Money object of the given value, using the American dollar currency.
Instance Method Summary collapse
- #%(fixnum) ⇒ Object
-
#*(fixnum) ⇒ Object
multiply money by fixnum.
- #+(other_money) ⇒ Object
- #-(other_money) ⇒ Object
- #-@ ⇒ Object
-
#/(fixnum) ⇒ Object
divide money by fixnum check out split_in_installments method too.
- #<=>(other_money) ⇒ Object
-
#==(other_money) ⇒ Object
Do two money objects equal? Only works if both objects are of the same currency.
-
#add_tax(tax) ⇒ Object
Just a helper if you got tax inputs in percentage.
-
#compound_interest(rate, count = 1, period = 12) ⇒ Object
Calculates compound interest Returns a money object with the sum of self + it.
-
#exchange_to(other_currency) ⇒ Object
Recieve the amount of this money object in another currency.
-
#format(*rules) ⇒ Object
Format the price according to several rules Currently supported are :with_currency, :no_cents, :symbol and :html.
-
#in_installments_of(other_money, order = false) ⇒ Object
Split money in installments based on payment value.
-
#initialize(cents, currency = nil, bank = nil) ⇒ Money
constructor
Creates a new money object.
- #method_missing(m, *x) ⇒ Object
- #normalize_formatting_rules(rules) ⇒ Object
-
#round_to_coin(coin) ⇒ Object
Round to nearest coin value basically, we don’t have coins for cents in CZK, our smallest fraction is 0.50CZK.
-
#simple_interest(rate, count = 1, period = 12) ⇒ Object
Calculate self + simple interest.
-
#split_in_installments(fixnum, order = false) ⇒ Object
Split money in number of installments.
- #tax_breakdown(tax) ⇒ Object
- #tax_reverse_breakdown(tax) ⇒ Object
-
#to_f ⇒ Object
Money.ca_dollar(100).to_f => “1.0”.
-
#to_money ⇒ Object
Conversation to self.
-
#to_s ⇒ Object
Money.ca_dollar(100).to_s => “1.00”.
-
#zero? ⇒ Boolean
Test if the money amount is zero.
Constructor Details
#initialize(cents, currency = nil, bank = nil) ⇒ Money
Creates a new money object.
Money.new(100)
Alternativly you can use the convinience methods like Money.ca_dollar and Money.us_dollar
91 92 93 94 95 |
# File 'lib/money/money.rb', line 91 def initialize(cents, currency = nil, bank = nil) @cents = cents.to_i @currency = (currency || Money.default_currency).upcase @bank = bank || Money.default_bank end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(m, *x) ⇒ Object
323 324 325 326 327 328 329 |
# File 'lib/money/money.rb', line 323 def method_missing(m,*x) if m.to_s =~ /^as/ exchange_to(m.to_s.split("_").last.upcase) else super end end |
Class Attribute Details
.default_bank ⇒ Object
Each Money object is associated to a bank object, which is responsible for currency exchange. This property allows one to specify the default bank object.
bank1 = MyBank.new
bank2 = MyOtherBank.new
Money.default_bank = bank1
money1 = Money.new(10)
money1.bank # => bank1
Money.default_bank = bank2
money2 = Money.new(10)
money2.bank # => bank2
money1.bank # => bank1
The default value for this property is an instance if VariableExchangeBank. It allows one to specify custom exchange rates:
Money.default_bank.add_rate("USD", "CAD", 1.24515)
Money.default_bank.add_rate("CAD", "USD", 0.803115)
Money.us_dollar(100).exchange_to("CAD") # => Money.ca_dollar(124)
Money.ca_dollar(100).exchange_to("USD") # => Money.us_dollar(80)
34 35 36 |
# File 'lib/money/money.rb', line 34 def default_bank @default_bank end |
.default_currency ⇒ Object
the default currency, which is used when Money.new
is called without an explicit currency argument. The default value is “USD”.
38 39 40 |
# File 'lib/money/money.rb', line 38 def default_currency @default_currency end |
Instance Attribute Details
#bank ⇒ Object (readonly)
Returns the value of attribute bank.
7 8 9 |
# File 'lib/money/money.rb', line 7 def bank @bank end |
#cents ⇒ Object (readonly) Also known as: to_i
Returns the value of attribute cents.
7 8 9 |
# File 'lib/money/money.rb', line 7 def cents @cents end |
#currency ⇒ Object (readonly)
Returns the value of attribute currency.
7 8 9 |
# File 'lib/money/money.rb', line 7 def currency @currency end |
Class Method Details
.add_rate(*params) ⇒ Object
82 83 84 |
# File 'lib/money/money.rb', line 82 def self.add_rate(*params) Money.default_bank.add_rate(*params) end |
.ca_dollar(cents) ⇒ Object
Creates a new Money object of the given value, using the Canadian dollar currency.
63 64 65 |
# File 'lib/money/money.rb', line 63 def self.ca_dollar(cents) Money.new(cents, "CAD") end |
.empty(currency = default_currency) ⇒ Object
Create a new money object with value 0.
58 59 60 |
# File 'lib/money/money.rb', line 58 def self.empty(currency = default_currency) Money.new(0, currency) end |
.euro(cents) ⇒ Object
Creates a new Money object of the given value, using the Euro currency.
73 74 75 |
# File 'lib/money/money.rb', line 73 def self.euro(cents) Money.new(cents, "EUR") end |
Instance Method Details
#%(fixnum) ⇒ Object
145 146 147 |
# File 'lib/money/money.rb', line 145 def %(fixnum) Money.new(cents % fixnum, currency) end |
#*(fixnum) ⇒ Object
multiply money by fixnum
135 136 137 |
# File 'lib/money/money.rb', line 135 def *(fixnum) Money.new(cents * fixnum, currency) end |
#+(other_money) ⇒ Object
112 113 114 115 116 117 118 119 |
# File 'lib/money/money.rb', line 112 def +(other_money) other_money = Money.new(other_money) unless other_money.is_a? Money if currency == other_money.currency Money.new(cents + other_money.cents, other_money.currency) else Money.new(cents + other_money.exchange_to(currency).cents,currency) end end |
#-(other_money) ⇒ Object
121 122 123 124 125 126 127 128 |
# File 'lib/money/money.rb', line 121 def -(other_money) other_money = Money.new(other_money) unless other_money.is_a? Money if currency == other_money.currency Money.new(cents - other_money.cents, other_money.currency) else Money.new(cents - other_money.exchange_to(currency).cents, currency) end end |
#/(fixnum) ⇒ Object
divide money by fixnum check out split_in_installments method too
141 142 143 |
# File 'lib/money/money.rb', line 141 def /(fixnum) Money.new(cents / fixnum, currency) end |
#<=>(other_money) ⇒ Object
103 104 105 106 107 108 109 110 |
# File 'lib/money/money.rb', line 103 def <=>(other_money) other_money = Money.new(other_money) unless other_money.is_a? Money if bank.same_currency?(currency, other_money.currency) cents <=> other_money.cents else cents <=> other_money.exchange_to(currency).cents end end |
#==(other_money) ⇒ Object
Do two money objects equal? Only works if both objects are of the same currency
98 99 100 101 |
# File 'lib/money/money.rb', line 98 def ==(other_money) other_money.respond_to?(:cents) && cents == other_money.cents && other_money.respond_to?(:currency) && bank.same_currency?(currency, other_money.currency) end |
#add_tax(tax) ⇒ Object
Just a helper if you got tax inputs in percentage. Ie. add_tax(20) => cents * 1.20
196 197 198 |
# File 'lib/money/money.rb', line 196 def add_tax(tax) tax_breakdown(tax)[0] end |
#compound_interest(rate, count = 1, period = 12) ⇒ Object
Calculates compound interest Returns a money object with the sum of self + it
156 157 158 |
# File 'lib/money/money.rb', line 156 def compound_interest(rate, count = 1, period = 12) Money.new(cents * ((1 + rate / 100.0 / period) ** count - 1)) end |
#exchange_to(other_currency) ⇒ Object
Recieve the amount of this money object in another currency.
314 315 316 |
# File 'lib/money/money.rb', line 314 def exchange_to(other_currency) Money.new(@bank.exchange(self.cents, currency, other_currency), other_currency) end |
#format(*rules) ⇒ Object
Format the price according to several rules Currently supported are :with_currency, :no_cents, :symbol and :html.
:with_currency
Money.ca_dollar(100).format => "$1.00"
Money.ca_dollar(100).format(:with_currency => true) => "$1.00 CAD"
Money.us_dollar(85).format(:with_currency => true) => "$0.85 USD"
:no_cents
Money.ca_dollar(100).format(:no_cents) => "$1"
Money.ca_dollar(599).format(:no_cents) => "$5"
Money.ca_dollar(570).format(:no_cents, :with_currency) => "$5 CAD"
Money.ca_dollar(39000).format(:no_cents) => "$390"
:symbol
Money.new(100, :currency => "GBP").format(:symbol => "£") => "£1.00"
Money.new(100, :currency => "GBP").format(:symbol => "UU") => "UU1.00"
:display_free
Money.ca_dollar(0).format => "free"
Money.real(0).format(:display_free => "Gratis") => "Gratis"
:html
Money.ca_dollar(570).format(:html => true, :with_currency => true) => "$5.70 <span class=\"currency\">CAD</span>"
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
# File 'lib/money/money.rb', line 252 def format(*rules) # support for old format parameters rules = normalize_formatting_rules(rules) if cents == 0 if rules[:display_free].respond_to?(:to_str) return rules[:display_free] elsif rules[:display_free] return "free" end end curr = CURRENCIES[currency] symbol = rules.has_key?(:symbol) ? (rules[:symbol] || "") : (curr ? curr[:symbol] : "$") delimiter = (curr ? curr[:delimiter] : "," ) separator = (curr ? curr[:separator] : "." ) if rules[:no_cents] formatted = sprintf("#{symbol}%d", cents.to_f / 100) formatted.gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}") else formatted = sprintf("#{symbol}%.2f", cents.to_f / 100).split('.') formatted[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}") formatted = formatted.join(separator) end # Commify ("10000" => "10,000") formatted.gsub!(/(\d)(?=\d{3}+(?:\.|$))(\d{3}\..*)?/,'\1,\2') if rules[:with_currency] formatted << '<span class="currency">' if rules[:html] formatted << currency formatted << '</span>' if rules[:html] end formatted.gsub!(symbol,curr[:html]) if rules[:html] formatted end |
#in_installments_of(other_money, order = false) ⇒ Object
Split money in installments based on payment value
Money.new(1000_00).split_in_installments(Money.new(300_00))
> [ 334_00, 333_00, 333_00 ] (All Money instances)
218 219 220 |
# File 'lib/money/money.rb', line 218 def in_installments_of(other_money, order=false) split_in_installments(cents/other_money.cents, order) end |
#normalize_formatting_rules(rules) ⇒ Object
290 291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/money/money.rb', line 290 def normalize_formatting_rules(rules) if rules.size == 1 rules = rules.pop rules = { rules => true } if rules.is_a?(Symbol) else rules = rules.inject({}) do |h,s| h[s] = true h end end rules end |
#round_to_coin(coin) ⇒ Object
171 172 173 174 175 |
# File 'lib/money/money.rb', line 171 def round_to_coin(coin) coef = 1.0/coin val = (cents * coef).floor / coef Money.new(val, currency) end |
#simple_interest(rate, count = 1, period = 12) ⇒ Object
Calculate self + simple interest
161 162 163 |
# File 'lib/money/money.rb', line 161 def simple_interest(rate, count = 1, period = 12) Money.new(rate / 100 / period * cents * count) end |
#split_in_installments(fixnum, order = false) ⇒ Object
Split money in number of installments
Money.new(10_00).split_in_installments(3)
> [ 3.34, 3.33, 3.33 ] (All Money instances)
205 206 207 208 209 210 211 |
# File 'lib/money/money.rb', line 205 def split_in_installments(fixnum, order=false) wallet = Wallet.new(fixnum, Money.new(cents/fixnum,currency)) to_add = cents % fixnum to_add.times { |m| wallet[m] += Money.new(1) } wallet.reverse! if order wallet end |
#tax_breakdown(tax) ⇒ Object
Returns array a where
a[0] is price _after_ applying tax (tax base)
a[1] is tax
180 181 182 183 |
# File 'lib/money/money.rb', line 180 def tax_breakdown(tax) _tax = (cents * (tax / 100.0)).round [Money.new(cents + _tax, currency), Money.new(_tax, currency)] end |
#tax_reverse_breakdown(tax) ⇒ Object
188 189 190 191 192 |
# File 'lib/money/money.rb', line 188 def tax_reverse_breakdown(tax) coef = tax/100.0 [Money.new((cents / (1+coef)).round, currency), Money.new((cents*coef/(1+coef)).round, currency) ] end |
#to_f ⇒ Object
Money.ca_dollar(100).to_f => “1.0”
309 310 311 |
# File 'lib/money/money.rb', line 309 def to_f cents / 100.0 end |
#to_money ⇒ Object
Conversation to self
319 320 321 |
# File 'lib/money/money.rb', line 319 def to_money self end |
#to_s ⇒ Object
Money.ca_dollar(100).to_s => “1.00”
304 305 306 |
# File 'lib/money/money.rb', line 304 def to_s sprintf("%.2f", cents / 100.0) end |
#zero? ⇒ Boolean
Test if the money amount is zero
150 151 152 |
# File 'lib/money/money.rb', line 150 def zero? cents == 0 end |