Class: Money::ExchangeBank

Inherits:
Object
  • Object
show all
Defined in:
lib/money/exchange_bank.rb

Constant Summary collapse

@@singleton =
ExchangeBank.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeExchangeBank

Returns a new instance of ExchangeBank.



40
41
42
43
# File 'lib/money/exchange_bank.rb', line 40

def initialize
  @rates = {}
  @mutex = Mutex.new
end

Instance Attribute Details

#default_ratesObject

Rates to be autofetched



31
32
33
# File 'lib/money/exchange_bank.rb', line 31

def default_rates
  @default_rates
end

Class Method Details

.instanceObject

Returns the singleton instance of ExchangeBank.

By default, Money.default_bank returns the same object.



36
37
38
# File 'lib/money/exchange_bank.rb', line 36

def self.instance
  @@singleton
end

Instance Method Details

#add_rate(*params) ⇒ Object



45
46
47
48
49
50
51
# File 'lib/money/exchange_bank.rb', line 45

def add_rate(*params)
  if rate = params.delete_at(2)
    parse_rate(rate, *params)
  else
    parse_rate(params[1], Money.default_currency, params[0])
  end
end

#auto_fetch(time = 60*60) ⇒ Object

Auto fetch the currencies every X seconds if no time is give, will fetch every hour



114
115
116
117
118
119
120
121
122
# File 'lib/money/exchange_bank.rb', line 114

def auto_fetch(time = 60*60)
  @auto_fetch.kill if (@auto_fetch && @auto_fetch.alive?)
  @auto_fetch = Thread.new {
    loop do
      self.fetch_rates
      sleep time
    end
  }
end

#exchange(cents, from, to) ⇒ Object

Exchange the given amount of cents in from_currency to to_currency. Returns the amount of cents in to_currency as an integer, rounded down.

If the conversion rate is unknown, then Money::UnknownRate will be raised.

Raises:



82
83
84
85
86
# File 'lib/money/exchange_bank.rb', line 82

def exchange(cents, from, to)
  rate =  get_rate(from, to)
  raise(Money::UnknownRate, "No conversion rate for #{from} -> #{to}") unless rate
  (cents * rate).floor # or round here?
end

#fetch_rate(rate, xml) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
# File 'lib/money/exchange_bank.rb', line 88

def fetch_rate(rate, xml)
  curr = (xml/:Cube).select { |r| r["currency"] == rate }.first
  diff = (rate == "EUR" || !curr) ? 1 : curr["rate"].to_f
  (xml/:Cube).each do |x|
    c = x['currency'] || ""
    unless default_rates && !default_rates.include?(c)
      parse_rate x['rate'].to_f / diff, curr ? rate : "EUR", c.upcase
    end
  end
  parse_rate 1.0/diff, rate, "EUR" if curr
end

#fetch_ratesObject

Fetch rates



101
102
103
104
105
106
107
108
109
110
# File 'lib/money/exchange_bank.rb', line 101

def fetch_rates
  xml = Parser::XML(Net::HTTP.get(URI.parse('http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml')))
  if default_rates
    for rate in default_rates
      fetch_rate(rate, xml)
    end
  else
    fetch_rate Money.default_currency, xml
  end
end

#get_rate(from, to = nil) ⇒ Object



62
63
64
65
66
67
# File 'lib/money/exchange_bank.rb', line 62

def get_rate(from, to = nil)
  from, to = Money.default_currency, from unless to
  @mutex.synchronize do
    @rates["#{from}<>#{to}".upcase]
  end
end

#parse_rate(rate, from, to) ⇒ Object



53
54
55
56
57
58
59
60
# File 'lib/money/exchange_bank.rb', line 53

def parse_rate(rate,from,to)
  return if from.upcase == to.upcase
  @mutex.synchronize do
    @rates["#{from}<>#{to}".upcase] = rate
    @rates["#{to}<>#{from}".upcase] = 1.0/rate
  #  @rates["sync_at"] = Time.now.to_i
  end
end

#same_currency?(currency1, currency2) ⇒ Boolean

Given two currency names, checks whether they’re both the same currency.

bank = ExchangeBank.new
bank.same_currency?("usd", "USD")   # => true
bank.same_currency?("usd", "EUR")   # => false

Returns:

  • (Boolean)


74
75
76
# File 'lib/money/exchange_bank.rb', line 74

def same_currency?(currency1, currency2)
  currency1.upcase == currency2.upcase
end

#stop_fetchObject

stop auto fetch



125
126
127
# File 'lib/money/exchange_bank.rb', line 125

def stop_fetch
  @auto_fetch.kill if (@auto_fetch && @auto_fetch.alive?)
end