nofxx-money 2.3.8 → 2.3.9
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +12 -2
- data/VERSION +1 -1
- data/lib/money/exchange_bank.rb +17 -13
- data/money.gemspec +1 -1
- data/spec/money/exchange_bank_spec.rb +68 -17
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -9,7 +9,7 @@ This library aids one in handling money and different currencies. Features:
|
|
9
9
|
- Provides APIs for exchanging money from one currency to another.
|
10
10
|
- Has the ability to parse a money string into a Money object.
|
11
11
|
- Provides ActiveRecord "has_money" method.
|
12
|
-
|
12
|
+
- Autofetch rates from ECB
|
13
13
|
|
14
14
|
== Install
|
15
15
|
|
@@ -84,13 +84,23 @@ www.xe.com for the current rates or just returns <tt>rand(2)</tt>:
|
|
84
84
|
|
85
85
|
=== Default Currency
|
86
86
|
|
87
|
-
|
87
|
+
Money defaults to USD as its currency. This can be overwritten using:
|
88
88
|
|
89
89
|
Money.default_currency = "CAD"
|
90
90
|
|
91
91
|
If you use Rails, then environment.rb is a very good place to put this.
|
92
92
|
|
93
93
|
|
94
|
+
=== Autofetch rates
|
95
|
+
|
96
|
+
By default, Money won't fetch the rates automatically, you need to call: @bank.fetch_rates
|
97
|
+
|
98
|
+
If you have your bank default rates configured, it'll fetch all possible rates from it,
|
99
|
+
if you don't, It'll fetch all rates to and from your default_currency.
|
100
|
+
|
101
|
+
Money uses the ECB XML Feed.
|
102
|
+
|
103
|
+
|
94
104
|
== Webapps
|
95
105
|
|
96
106
|
=== Ruby on Rails
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.3.
|
1
|
+
2.3.9
|
data/lib/money/exchange_bank.rb
CHANGED
@@ -55,7 +55,7 @@ class Money
|
|
55
55
|
@mutex.synchronize do
|
56
56
|
@rates["#{from}<>#{to}".upcase] = rate
|
57
57
|
@rates["#{to}<>#{from}".upcase] = 1.0/rate
|
58
|
-
|
58
|
+
# @rates["sync_at"] = Time.now.to_i
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -82,27 +82,31 @@ class Money
|
|
82
82
|
def exchange(cents, from, to)
|
83
83
|
rate = get_rate(from, to)
|
84
84
|
raise(Money::UnknownRate, "No conversion rate for #{from} -> #{to}") unless rate
|
85
|
-
(cents * rate).floor
|
85
|
+
(cents * rate).floor # or round here?
|
86
86
|
end
|
87
87
|
|
88
|
-
def fetch_rate(
|
89
|
-
|
88
|
+
def fetch_rate(rate, xml)
|
89
|
+
curr = (xml/:Cube).select { |r| r["currency"] == rate }.first
|
90
|
+
diff = (rate == "EUR" || !curr) ? 1 : curr["rate"].to_f
|
91
|
+
(xml/:Cube).each do |x|
|
92
|
+
c = x['currency'] || ""
|
93
|
+
unless default_rates && !default_rates.include?(c)
|
94
|
+
parse_rate x['rate'].to_f / diff, curr ? rate : "EUR", c.upcase
|
95
|
+
end
|
96
|
+
end
|
97
|
+
parse_rate 1.0/diff, rate, "EUR" if curr
|
90
98
|
end
|
91
99
|
|
92
100
|
# Fetch rates
|
93
101
|
def fetch_rates
|
94
102
|
xml = Parser::XML(Net::HTTP.get(URI.parse('http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml')))
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
r = x['rate'].to_f
|
99
|
-
c = x['currency'] || ""
|
100
|
-
unless default_rates && !default_rates.include?(c)
|
101
|
-
parse_rate r / diff, curr ? Money.default_currency : "EUR", c.upcase
|
103
|
+
if default_rates
|
104
|
+
for rate in default_rates
|
105
|
+
fetch_rate(rate, xml)
|
102
106
|
end
|
107
|
+
else
|
108
|
+
fetch_rate Money.default_currency, xml
|
103
109
|
end
|
104
|
-
parse_rate diff, Money.default_currency, "EUR" if curr
|
105
|
-
self
|
106
110
|
end
|
107
111
|
|
108
112
|
# Auto fetch the currencies every X seconds
|
data/money.gemspec
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
2
|
|
3
|
+
# To spec better
|
4
|
+
class Money
|
5
|
+
class ExchangeBank
|
6
|
+
attr_reader :rates
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
3
10
|
describe Money::ExchangeBank do
|
4
11
|
before :each do
|
5
12
|
@bank = Money::ExchangeBank.new
|
@@ -91,27 +98,59 @@ describe Money::ExchangeBank do
|
|
91
98
|
lambda { @bank.exchange(10, "USD", "ABC") }.should raise_error(Money::UnknownRate)
|
92
99
|
end
|
93
100
|
|
94
|
-
describe "
|
101
|
+
describe "Auto fetching data" do
|
95
102
|
|
96
103
|
before(:each) do
|
97
104
|
URI.should_receive(:parse).with("http://www.ecb.int/stats/eurofxref/eurofxref-daily.xml").and_return(:uri)
|
98
105
|
Net::HTTP.should_receive(:get).with(:uri).and_return("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<gesmes:Envelope xmlns:gesmes=\"http://www.gesmes.org/xml/2002-08-01\" xmlns=\"http://www.ecb.int/vocabulary/2002-08-01/eurofxref\">\n\t<gesmes:subject>Reference rates</gesmes:subject>\n\t<gesmes:Sender>\n\t\t<gesmes:name>European Central Bank</gesmes:name>\n\t</gesmes:Sender>\n\t<Cube>\n\t\t<Cube time='2009-05-29'>\n\t\t\t<Cube currency='USD' rate='1.4098'/>\n\t\t\t<Cube currency='JPY' rate='135.22'/>\n\t\t\t<Cube currency='BGN' rate='1.9558'/>\n\t\t\t<Cube currency='CZK' rate='26.825'/>\n\t\t\t<Cube currency='DKK' rate='7.4453'/>\n\t\t\t<Cube currency='EEK' rate='15.6466'/>\n\t\t\t<Cube currency='GBP' rate='0.87290'/>\n\t\t\t<Cube currency='HUF' rate='282.48'/>\n\t\t\t<Cube currency='LTL' rate='3.4528'/>\n\t\t\t<Cube currency='LVL' rate='0.7093'/>\n\t\t\t<Cube currency='PLN' rate='4.4762'/>\n\t\t\t<Cube currency='RON' rate='4.1825'/>\n\t\t\t<Cube currency='SEK' rate='10.6678'/>\n\t\t\t<Cube currency='CHF' rate='1.5128'/>\n\t\t\t<Cube currency='NOK' rate='8.8785'/>\n\t\t\t<Cube currency='HRK' rate='7.3500'/>\n\t\t\t<Cube currency='RUB' rate='43.4455'/>\n\t\t\t<Cube currency='TRY' rate='2.1737'/>\n\t\t\t<Cube currency='AUD' rate='1.7671'/>\n\t\t\t<Cube currency='BRL' rate='2.8320'/>\n\t\t\t<Cube currency='CAD' rate='1.5501'/>\n\t\t\t<Cube currency='CNY' rate='9.6263'/>\n\t\t\t<Cube currency='HKD' rate='10.9273'/>\n\t\t\t<Cube currency='IDR' rate='14539.26'/>\n\t\t\t<Cube currency='INR' rate='66.4260'/>\n\t\t\t<Cube currency='KRW' rate='1764.04'/>\n\t\t\t<Cube currency='MXN' rate='18.4340'/>\n\t\t\t<Cube currency='MYR' rate='4.9167'/>\n\t\t\t<Cube currency='NZD' rate='2.2135'/>\n\t\t\t<Cube currency='PHP' rate='66.516'/>\n\t\t\t<Cube currency='SGD' rate='2.0350'/>\n\t\t\t<Cube currency='THB' rate='48.377'/>\n\t\t\t<Cube currency='ZAR' rate='11.2413'/>\n\t\t</Cube>\n\t</Cube>\n</gesmes:Envelope>")
|
99
106
|
end
|
100
107
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
108
|
+
describe "EUR Default" do
|
109
|
+
|
110
|
+
before(:each) do
|
111
|
+
Money.stub!(:default_currency).and_return("EUR")
|
112
|
+
@bank.fetch_rates
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should fetch data" do
|
116
|
+
@bank.get_rate("DKK").should be_close(7.4453, 0.0001)
|
117
|
+
@bank.get_rate("BRL").should be_close(2.832, 0.001)
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should fetch and exchange" do
|
121
|
+
@bank.exchange(10_00, "EUR", "BRL").should == 28_32
|
122
|
+
@bank.exchange(28_32, "BRL", "EUR").should == 10_00
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should fetch and exchange" do
|
126
|
+
@bank.exchange(10_00, "EUR", "DKK").should == 74_45
|
127
|
+
@bank.exchange(74_45, "DKK", "EUR").should == 9_99
|
128
|
+
end
|
129
|
+
|
107
130
|
end
|
108
131
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
132
|
+
describe "BRL Default" do
|
133
|
+
|
134
|
+
before(:each) do
|
135
|
+
Money.stub!(:default_currency).and_return("BRL")
|
136
|
+
@bank.fetch_rates
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should fetch diff than eur" do
|
140
|
+
@bank.get_rate("DKK").should be_close(2.6289, 0.0001)
|
141
|
+
@bank.get_rate("EEK").should be_close(5.5249, 0.0001)
|
142
|
+
@bank.get_rate("EUR").should be_close(0.3531, 0.001)
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should fetch and exchange" do
|
146
|
+
@bank.exchange(10_00, "EUR", "BRL").should == 28_32
|
147
|
+
@bank.exchange(28_32, "BRL", "EUR").should == 10_00
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should exchange diff than eur" do
|
151
|
+
@bank.exchange(10_00, "BRL", "DKK").should == 26_28
|
152
|
+
@bank.exchange(26_28, "DKK", "BRL").should == 9_99
|
153
|
+
end
|
115
154
|
end
|
116
155
|
|
117
156
|
it "should fetch for an unknown one" do
|
@@ -119,6 +158,8 @@ describe Money::ExchangeBank do
|
|
119
158
|
@bank.fetch_rates
|
120
159
|
@bank.get_rate("DKK").should be_nil
|
121
160
|
@bank.get_rate("EUR", "USD").should be_close(1.4098, 0.001)
|
161
|
+
@bank.exchange(10_00, "EUR", "BRL").should == 28_32
|
162
|
+
@bank.exchange(28_32, "BRL", "EUR").should == 10_00
|
122
163
|
end
|
123
164
|
|
124
165
|
it "should fetch only what I want" do
|
@@ -127,15 +168,25 @@ describe Money::ExchangeBank do
|
|
127
168
|
@bank.fetch_rates
|
128
169
|
@bank.get_rate("DKK").should be_nil
|
129
170
|
@bank.get_rate("USD").should be_nil
|
130
|
-
@bank.get_rate("EUR").should be_close(
|
171
|
+
@bank.get_rate("EUR").should be_close(0.3531, 0.001)
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should exchange only what I want" do
|
175
|
+
Money.stub!(:default_currency).and_return("BRL")
|
176
|
+
@bank.default_rates = ["BRL", "EUR"]
|
177
|
+
@bank.fetch_rates
|
178
|
+
lambda { @bank.exchange(100, "BRL", "DKK") }.should raise_error
|
179
|
+
lambda { @bank.exchange(100, "EUR", "DKK") }.should raise_error
|
180
|
+
@bank.rates.should have(2).keys
|
131
181
|
end
|
132
182
|
|
133
|
-
it "should
|
183
|
+
it "should convert B to C with default A" do
|
134
184
|
Money.stub!(:default_currency).and_return("USD")
|
135
185
|
@bank.default_rates = ["BRL", "EUR", "USD"]
|
136
186
|
@bank.fetch_rates
|
137
|
-
@bank.exchange(
|
138
|
-
@bank.exchange(
|
187
|
+
@bank.exchange(10_00, "EUR", "BRL").should == 28_32
|
188
|
+
@bank.exchange(28_32, "BRL", "EUR").should == 10_00
|
189
|
+
@bank.rates.should have(6).keys
|
139
190
|
end
|
140
191
|
|
141
192
|
end
|