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$" }, "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
-
#/(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
89 90 91 92 93 |
# File 'lib/money/money.rb', line 89 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
322 323 324 325 326 327 328 |
# File 'lib/money/money.rb', line 322 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
80 81 82 |
# File 'lib/money/money.rb', line 80 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.
61 62 63 |
# File 'lib/money/money.rb', line 61 def self.ca_dollar(cents) Money.new(cents, "CAD") end |
.empty(currency = default_currency) ⇒ Object
Create a new money object with value 0.
56 57 58 |
# File 'lib/money/money.rb', line 56 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.
71 72 73 |
# File 'lib/money/money.rb', line 71 def self.euro(cents) Money.new(cents, "EUR") end |
.real(cents) ⇒ Object
Creates a new Money object of the given value, using the Brazilian Real currency.
76 77 78 |
# File 'lib/money/money.rb', line 76 def self.real(cents) Money.new(cents, "BRL") end |
.us_dollar(cents) ⇒ Object
Creates a new Money object of the given value, using the American dollar currency.
66 67 68 |
# File 'lib/money/money.rb', line 66 def self.us_dollar(cents) Money.new(cents, "USD") end |
Instance Method Details
#%(fixnum) ⇒ Object
139 140 141 |
# File 'lib/money/money.rb', line 139 def %(fixnum) Money.new(cents % fixnum, currency) end |
#*(fixnum) ⇒ Object
multiply money by fixnum
129 130 131 |
# File 'lib/money/money.rb', line 129 def *(fixnum) Money.new(cents * fixnum, currency) end |
#+(other_money) ⇒ Object
110 111 112 113 114 115 116 117 |
# File 'lib/money/money.rb', line 110 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
119 120 121 122 123 124 125 126 |
# File 'lib/money/money.rb', line 119 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
135 136 137 |
# File 'lib/money/money.rb', line 135 def /(fixnum) Money.new(cents / fixnum, currency) end |
#<=>(other_money) ⇒ Object
101 102 103 104 105 106 107 108 |
# File 'lib/money/money.rb', line 101 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
96 97 98 99 |
# File 'lib/money/money.rb', line 96 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
190 191 192 |
# File 'lib/money/money.rb', line 190 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
150 151 152 |
# File 'lib/money/money.rb', line 150 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.
313 314 315 |
# File 'lib/money/money.rb', line 313 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(0).format => "free"
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"
html:
Money.ca_dollar(570).format(:html => true, :with_currency => true) => "$5.70 <span class=\"currency\">CAD</span>"
241 242 243 244 245 246 247 248 249 250 251 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 |
# File 'lib/money/money.rb', line 241 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 if rules.has_key?(:symbol) if rules[:symbol] symbol = rules[:symbol] else symbol = "" end else symbol = (CURRENCIES[currency] ? CURRENCIES[currency][:symbol] : "$") end self.currency delimiter = (CURRENCIES[currency] ? CURRENCIES[currency][:delimiter] : "," ) separator = (CURRENCIES[currency] ? CURRENCIES[currency][: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 << " " formatted << '<span class="currency">' if rules[:html] formatted << currency formatted << '</span>' if rules[:html] end formatted.gsub!(symbol,CURRENCIES[currency][: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)
212 213 214 |
# File 'lib/money/money.rb', line 212 def in_installments_of(other_money, order=false) split_in_installments(cents/other_money.cents, order) end |
#normalize_formatting_rules(rules) ⇒ Object
289 290 291 292 293 294 295 296 297 298 299 300 |
# File 'lib/money/money.rb', line 289 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
Round to nearest coin value basically, we don’t have coins for cents in CZK, our smallest fraction is 0.50CZK
Money.new(14_58).round_to_coin(50) => 14.50
165 166 167 168 169 |
# File 'lib/money/money.rb', line 165 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
155 156 157 |
# File 'lib/money/money.rb', line 155 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)
199 200 201 202 203 204 205 |
# File 'lib/money/money.rb', line 199 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_ tax (tax base)
a[1] is tax
174 175 176 177 |
# File 'lib/money/money.rb', line 174 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
182 183 184 185 186 |
# File 'lib/money/money.rb', line 182 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”
308 309 310 |
# File 'lib/money/money.rb', line 308 def to_f cents / 100.0 end |
#to_money ⇒ Object
Conversation to self
318 319 320 |
# File 'lib/money/money.rb', line 318 def to_money self end |
#to_s ⇒ Object
Money.ca_dollar(100).to_s => “1.00”
303 304 305 |
# File 'lib/money/money.rb', line 303 def to_s sprintf("%.2f", cents / 100.0) end |
#zero? ⇒ Boolean
Test if the money amount is zero
144 145 146 |
# File 'lib/money/money.rb', line 144 def zero? cents == 0 end |