danconia 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/Gemfile.lock +1 -1
- data/README.md +2 -0
- data/examples/currency_layer.rb +21 -0
- data/examples/{basic.rb → fixed_rates.rb} +1 -1
- data/lib/danconia.rb +4 -0
- data/lib/danconia/config.rb +0 -2
- data/lib/danconia/currency.rb +1 -1
- data/lib/danconia/exchanges/currency_layer.rb +2 -6
- data/lib/danconia/exchanges/exchange.rb +32 -0
- data/lib/danconia/exchanges/fixed_rates.rb +8 -3
- data/lib/danconia/money.rb +20 -11
- data/lib/danconia/stores/active_record.rb +24 -0
- data/lib/danconia/test_helpers.rb +18 -0
- data/lib/danconia/version.rb +1 -1
- data/spec/danconia/exchanges/currency_layer_spec.rb +0 -1
- data/spec/danconia/money_spec.rb +29 -14
- data/spec/danconia/stores/active_record_spec.rb +33 -0
- data/spec/spec_helper.rb +1 -1
- metadata +10 -6
- data/lib/danconia/exchange.rb +0 -32
- data/spec/support/helpers.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 38d88815b5c3c9155db3c64433d6469614656a2464ab6a0c0eae51b3429b084d
|
4
|
+
data.tar.gz: d8962d50c98a68e8acfbc2a1424e81b77b1d506d069d4e87c0fa32803482d2b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69fa03e8ae6c01a37eaafaf9fe358b1e57eca34bd4e1113fb795002b80d4f5dc2a3934c06f1b3102a3c64e3403e16f3d6fd97c9f301b819f9de6b742c3ea088d
|
7
|
+
data.tar.gz: 4881c55540c4b0e51e6018a23aae7923effc31ea9694295aae07a08a62fa60b32d6943adea8bd3798d5349b6f15c97ab2948f6410593c6d03ceb35c136e12c9b
|
data/.travis.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
language: ruby
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'danconia'
|
2
|
+
|
3
|
+
ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
|
4
|
+
|
5
|
+
ActiveRecord::Schema.define do
|
6
|
+
create_table :exchange_rates do |t|
|
7
|
+
t.string :pair, limit: 6
|
8
|
+
t.decimal :rate, precision: 12, scale: 6
|
9
|
+
t.index :pair, unique: true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
Danconia.configure do |config|
|
14
|
+
config.default_exchange = Danconia::Exchanges::CurrencyLayer.new(access_key: ENV['ACCESS_KEY'], store: Danconia::Stores::ActiveRecord.new)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Periodically do this
|
18
|
+
puts 'Updating dates with CurrencyLayer API...'
|
19
|
+
Danconia.config.default_exchange.update_rates!
|
20
|
+
|
21
|
+
puts Money(1, 'USD').exchange_to('EUR').inspect # => 0.854896 EUR
|
data/lib/danconia.rb
CHANGED
@@ -4,4 +4,8 @@ require 'danconia/currency'
|
|
4
4
|
require 'danconia/money'
|
5
5
|
require 'danconia/kernel'
|
6
6
|
require 'danconia/integrations/active_record'
|
7
|
+
require 'danconia/exchanges/exchange'
|
7
8
|
require 'danconia/exchanges/fixed_rates'
|
9
|
+
require 'danconia/exchanges/currency_layer'
|
10
|
+
require 'danconia/stores/in_memory'
|
11
|
+
require 'danconia/stores/active_record'
|
data/lib/danconia/config.rb
CHANGED
data/lib/danconia/currency.rb
CHANGED
@@ -2,7 +2,7 @@ module Danconia
|
|
2
2
|
class Currency < Struct.new(:code, :symbol, :description, keyword_init: true)
|
3
3
|
def self.find code, exchange
|
4
4
|
return code if code.is_a? Currency
|
5
|
-
new exchange.
|
5
|
+
new exchange.currencies.find { |c| c[:code] == code } || {code: code, symbol: '$'}
|
6
6
|
end
|
7
7
|
end
|
8
8
|
end
|
@@ -5,15 +5,11 @@ require 'json'
|
|
5
5
|
module Danconia
|
6
6
|
module Exchanges
|
7
7
|
class CurrencyLayer < Exchange
|
8
|
-
def initialize access_key
|
9
|
-
super
|
8
|
+
def initialize access_key:, **args
|
9
|
+
super args
|
10
10
|
@access_key = access_key
|
11
11
|
end
|
12
12
|
|
13
|
-
def update_rates!
|
14
|
-
@store.save_rates fetch_rates
|
15
|
-
end
|
16
|
-
|
17
13
|
def fetch_rates
|
18
14
|
response = JSON.parse Net::HTTP.get URI "http://www.apilayer.net/api/live?access_key=#{@access_key}"
|
19
15
|
if response['success']
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Danconia
|
2
|
+
module Exchanges
|
3
|
+
class Exchange
|
4
|
+
attr_reader :store, :currencies
|
5
|
+
|
6
|
+
def initialize store: Stores::InMemory.new, currencies: []
|
7
|
+
@store = store
|
8
|
+
@currencies = currencies
|
9
|
+
end
|
10
|
+
|
11
|
+
def rate from, to
|
12
|
+
if from == 'USD' and direct_rate = @store.direct_rate(from, to)
|
13
|
+
direct_rate
|
14
|
+
elsif to == 'USD' and inverse_rate = @store.direct_rate(to, from)
|
15
|
+
(1.0 / inverse_rate).round 6
|
16
|
+
elsif from != 'USD' and to != 'USD' and from_in_usd = rate(from, 'USD') and to_per_usd = rate('USD', to)
|
17
|
+
(from_in_usd * to_per_usd).round 6
|
18
|
+
else
|
19
|
+
raise Errors::ExchangeRateNotFound.new(from, to)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def rates
|
24
|
+
@store.rates
|
25
|
+
end
|
26
|
+
|
27
|
+
def update_rates!
|
28
|
+
@store.save_rates fetch_rates
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,9 +1,14 @@
|
|
1
1
|
module Danconia
|
2
2
|
module Exchanges
|
3
3
|
class FixedRates < Exchange
|
4
|
-
def initialize rates: {}
|
5
|
-
super
|
6
|
-
@
|
4
|
+
def initialize rates: {}, **args
|
5
|
+
super args
|
6
|
+
@rates = rates
|
7
|
+
update_rates!
|
8
|
+
end
|
9
|
+
|
10
|
+
def fetch_rates
|
11
|
+
@rates
|
7
12
|
end
|
8
13
|
end
|
9
14
|
end
|
data/lib/danconia/money.rb
CHANGED
@@ -8,17 +8,21 @@ module Danconia
|
|
8
8
|
|
9
9
|
def initialize amount, currency_code = nil, decimals: 2, exchange: Danconia.config.default_exchange
|
10
10
|
@decimals = decimals
|
11
|
-
@amount = parse
|
11
|
+
@amount = parse amount
|
12
12
|
@currency = Currency.find(currency_code || Danconia.config.default_currency, exchange)
|
13
13
|
@exchange = exchange
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
16
|
+
def format decimals: @decimals
|
17
17
|
ActiveSupport::NumberHelper.number_to_currency amount, precision: decimals, unit: currency.symbol
|
18
18
|
end
|
19
19
|
|
20
|
+
def to_s
|
21
|
+
format
|
22
|
+
end
|
23
|
+
|
20
24
|
def inspect
|
21
|
-
"
|
25
|
+
"#{amount} #{currency.code}"
|
22
26
|
end
|
23
27
|
|
24
28
|
def == other
|
@@ -43,11 +47,17 @@ module Danconia
|
|
43
47
|
end
|
44
48
|
|
45
49
|
def exchange_to other_currency
|
46
|
-
other_currency = Currency.find(other_currency, exchange)
|
47
|
-
rate =
|
50
|
+
other_currency = other_currency.presence && Currency.find(other_currency, exchange) || currency
|
51
|
+
rate = exchange_rate_to(other_currency.code)
|
48
52
|
clone_with amount * rate, other_currency
|
49
53
|
end
|
50
54
|
|
55
|
+
def exchange_rate_to to
|
56
|
+
from = currency.code
|
57
|
+
return 1 if from == to
|
58
|
+
exchange.rate from, to
|
59
|
+
end
|
60
|
+
|
51
61
|
%w(+ - * /).each do |op|
|
52
62
|
class_eval <<-EOR, __FILE__, __LINE__ + 1
|
53
63
|
def #{op} other
|
@@ -65,6 +75,10 @@ module Danconia
|
|
65
75
|
(self * 100).round
|
66
76
|
end
|
67
77
|
|
78
|
+
def default_currency?
|
79
|
+
currency.code == Danconia.config.default_currency
|
80
|
+
end
|
81
|
+
|
68
82
|
def method_missing method, *args
|
69
83
|
if @amount.respond_to? method
|
70
84
|
@amount.send method, *args
|
@@ -80,16 +94,11 @@ module Danconia
|
|
80
94
|
private
|
81
95
|
|
82
96
|
def parse object
|
83
|
-
BigDecimal(object.to_s) rescue BigDecimal(
|
97
|
+
BigDecimal(object.to_s) rescue BigDecimal(0)
|
84
98
|
end
|
85
99
|
|
86
100
|
def clone_with amount, currency = @currency
|
87
101
|
Money.new amount, currency, decimals: decimals, exchange: exchange
|
88
102
|
end
|
89
|
-
|
90
|
-
def exchange_rate from, to
|
91
|
-
return 1 if from == to
|
92
|
-
exchange.rate from.code, to.code
|
93
|
-
end
|
94
103
|
end
|
95
104
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Danconia
|
2
|
+
module Stores
|
3
|
+
class ActiveRecord
|
4
|
+
def save_rates rates
|
5
|
+
ExchangeRate.transaction do
|
6
|
+
rates.each do |pair, rate|
|
7
|
+
ExchangeRate.where(pair: pair).first_or_initialize.update rate: rate
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def direct_rate from, to
|
13
|
+
ExchangeRate.find_by(pair: [from, to].join)&.rate
|
14
|
+
end
|
15
|
+
|
16
|
+
def rates
|
17
|
+
ExchangeRate.all
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class ExchangeRate < ::ActiveRecord::Base
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Danconia
|
2
|
+
module TestHelpers
|
3
|
+
class << self
|
4
|
+
def with_config &block
|
5
|
+
old_config = Danconia.config.dup
|
6
|
+
Danconia.configure &block
|
7
|
+
Danconia.config = old_config
|
8
|
+
end
|
9
|
+
|
10
|
+
def with_rates rates
|
11
|
+
with_config do |config|
|
12
|
+
config.default_exchange = Exchanges::FixedRates.new rates: rates, currencies: config.default_exchange.currencies
|
13
|
+
yield
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/danconia/version.rb
CHANGED
data/spec/danconia/money_spec.rb
CHANGED
@@ -9,11 +9,12 @@ module Danconia
|
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'non numeric values are treated as zero' do
|
12
|
+
expect(Money(nil)).to eq Money(0)
|
12
13
|
expect(Money('a')).to eq Money(0)
|
13
14
|
end
|
14
15
|
|
15
16
|
it 'should use the default currency if not specified' do
|
16
|
-
with_config do |config|
|
17
|
+
TestHelpers.with_config do |config|
|
17
18
|
config.default_currency = 'ARS'
|
18
19
|
expect(Money(0).currency.code).to eq 'ARS'
|
19
20
|
|
@@ -71,9 +72,7 @@ module Danconia
|
|
71
72
|
end
|
72
73
|
|
73
74
|
it 'should exchange to the source currency if they differ' do
|
74
|
-
|
75
|
-
config.default_exchange = fake_exchange(rate: 4)
|
76
|
-
|
75
|
+
TestHelpers.with_rates 'USDARS' => 4 do |config|
|
77
76
|
expect(Money(3, 'ARS') < Money(1, 'USD')).to be true
|
78
77
|
expect(Money(4, 'ARS') < Money(1, 'USD')).to be false
|
79
78
|
end
|
@@ -86,12 +85,18 @@ module Danconia
|
|
86
85
|
end
|
87
86
|
end
|
88
87
|
|
88
|
+
context 'format' do
|
89
|
+
it 'allow to override the number of decimals' do
|
90
|
+
expect(Money(3.561, decimals: 3).format(decimals: 1)).to eq '$3.6'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
89
94
|
context 'to_s' do
|
90
95
|
it 'should add the currency symbol' do
|
91
96
|
expect(Money(3.25).to_s).to eq '$3.25'
|
92
97
|
|
93
|
-
with_config do |config|
|
94
|
-
config.default_exchange =
|
98
|
+
TestHelpers.with_config do |config|
|
99
|
+
config.default_exchange = Exchanges::FixedRates.new currencies: [{code: 'EUR', symbol: '€'}, {code: 'JPY', symbol: '¥'}]
|
95
100
|
|
96
101
|
expect(Money(1, 'EUR').to_s).to eq '€1.00'
|
97
102
|
expect(Money(1, 'JPY').to_s).to eq '¥1.00'
|
@@ -103,15 +108,11 @@ module Danconia
|
|
103
108
|
expect(Money(3.256, decimals: 2).to_s).to eq '$3.26'
|
104
109
|
expect(Money(3.2517, decimals: 3).to_s).to eq '$3.252'
|
105
110
|
end
|
106
|
-
|
107
|
-
it 'nil should be like zero' do
|
108
|
-
expect(Money(nil).to_s).to eq '$0.00'
|
109
|
-
end
|
110
111
|
end
|
111
112
|
|
112
113
|
context '.inspect' do
|
113
114
|
it 'should display the object internals' do
|
114
|
-
expect(Money(10.25, 'ARS', decimals: 3).inspect).to eq '
|
115
|
+
expect(Money(10.25, 'ARS', decimals: 3).inspect).to eq '10.25 ARS'
|
115
116
|
end
|
116
117
|
end
|
117
118
|
|
@@ -121,8 +122,7 @@ module Danconia
|
|
121
122
|
end
|
122
123
|
|
123
124
|
it 'should use the default exchange if not set' do
|
124
|
-
|
125
|
-
config.default_exchange = Exchanges::FixedRates.new(rates: {'USDEUR' => 3, 'USDARS' => 4})
|
125
|
+
TestHelpers.with_rates 'USDEUR' => 3, 'USDARS' => 4 do
|
126
126
|
expect(Money(2, 'USD').exchange_to('EUR')).to eq Money(6, 'EUR')
|
127
127
|
expect(Money(2, 'USD').exchange_to('ARS')).to eq Money(8, 'ARS')
|
128
128
|
end
|
@@ -143,6 +143,21 @@ module Danconia
|
|
143
143
|
expect(m2.decimals).to eq 0
|
144
144
|
expect(m1).to eq Money(1, 'USD')
|
145
145
|
end
|
146
|
+
|
147
|
+
it 'if the destination currency is blank should not do the conversion' do
|
148
|
+
expect(Money(1, 'USD').exchange_to('')).to eq Money(1, 'USD')
|
149
|
+
expect(Money(1, 'ARS').exchange_to('')).to eq Money(1, 'ARS')
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context 'default_currency?' do
|
154
|
+
it 'is true if the currency is the configured default' do
|
155
|
+
TestHelpers.with_config do |config|
|
156
|
+
config.default_currency = 'ARS'
|
157
|
+
expect(Money(1, 'ARS')).to be_default_currency
|
158
|
+
expect(Money(1, 'USD')).to_not be_default_currency
|
159
|
+
end
|
160
|
+
end
|
146
161
|
end
|
147
162
|
|
148
163
|
context 'delegation' do
|
@@ -153,7 +168,7 @@ module Danconia
|
|
153
168
|
end
|
154
169
|
|
155
170
|
def fake_exchange args = {}
|
156
|
-
double 'exchange', args.reverse_merge(rate: nil,
|
171
|
+
double 'exchange', args.reverse_merge(rate: nil, currencies: [])
|
157
172
|
end
|
158
173
|
end
|
159
174
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Danconia
|
4
|
+
module Stores
|
5
|
+
describe ActiveRecord, active_record: true do
|
6
|
+
context 'save_rates' do
|
7
|
+
it 'should create or update the rates' do
|
8
|
+
ExchangeRate.create! pair: 'USDEUR', rate: 2
|
9
|
+
expect { subject.save_rates 'USDEUR' => 3, 'USDARS' => 4 }.to change { ExchangeRate.count }.by 1
|
10
|
+
expect(subject.rates.map { |e| [e.pair, e.rate] }).to eq({'USDEUR' => 3, 'USDARS' => 4}.to_a)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context '#direct_rate' do
|
15
|
+
it 'should find the rate for the pair' do
|
16
|
+
ExchangeRate.create! pair: 'USDEUR', rate: 2
|
17
|
+
expect(subject.direct_rate('USD', 'EUR')).to eq 2
|
18
|
+
expect(subject.direct_rate('USD', 'ARS')).to eq nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
before do
|
23
|
+
::ActiveRecord::Schema.define do
|
24
|
+
create_table :exchange_rates do |t|
|
25
|
+
t.string :pair, limit: 6
|
26
|
+
t.decimal :rate, precision: 12, scale: 6
|
27
|
+
t.index :pair, unique: true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'danconia'
|
2
|
+
require 'danconia/test_helpers'
|
2
3
|
require 'webmock/rspec'
|
3
4
|
|
4
5
|
Dir["#{__dir__}/support/*.rb"].each { |f| require f }
|
5
6
|
|
6
7
|
RSpec.configure do |config|
|
7
8
|
config.filter_run_when_matching :focus
|
8
|
-
config.include Helpers
|
9
9
|
config.include DatabaseCleaner
|
10
10
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: danconia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emmanuel Nicolau
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-07-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -118,6 +118,7 @@ files:
|
|
118
118
|
- ".gitignore"
|
119
119
|
- ".rspec"
|
120
120
|
- ".ruby-version"
|
121
|
+
- ".travis.yml"
|
121
122
|
- Gemfile
|
122
123
|
- Gemfile.lock
|
123
124
|
- Guardfile
|
@@ -125,27 +126,30 @@ files:
|
|
125
126
|
- README.md
|
126
127
|
- Rakefile
|
127
128
|
- danconia.gemspec
|
128
|
-
- examples/
|
129
|
+
- examples/currency_layer.rb
|
130
|
+
- examples/fixed_rates.rb
|
129
131
|
- lib/danconia.rb
|
130
132
|
- lib/danconia/config.rb
|
131
133
|
- lib/danconia/currency.rb
|
132
134
|
- lib/danconia/errors/api_error.rb
|
133
135
|
- lib/danconia/errors/exchange_rate_not_found.rb
|
134
|
-
- lib/danconia/exchange.rb
|
135
136
|
- lib/danconia/exchanges/currency_layer.rb
|
137
|
+
- lib/danconia/exchanges/exchange.rb
|
136
138
|
- lib/danconia/exchanges/fixed_rates.rb
|
137
139
|
- lib/danconia/integrations/active_record.rb
|
138
140
|
- lib/danconia/kernel.rb
|
139
141
|
- lib/danconia/money.rb
|
142
|
+
- lib/danconia/stores/active_record.rb
|
140
143
|
- lib/danconia/stores/in_memory.rb
|
144
|
+
- lib/danconia/test_helpers.rb
|
141
145
|
- lib/danconia/version.rb
|
142
146
|
- spec/danconia/exchanges/currency_layer_spec.rb
|
143
147
|
- spec/danconia/exchanges/fixed_rates_spec.rb
|
144
148
|
- spec/danconia/integrations/active_record_spec.rb
|
145
149
|
- spec/danconia/money_spec.rb
|
150
|
+
- spec/danconia/stores/active_record_spec.rb
|
146
151
|
- spec/spec_helper.rb
|
147
152
|
- spec/support/database.rb
|
148
|
-
- spec/support/helpers.rb
|
149
153
|
homepage: ''
|
150
154
|
licenses: []
|
151
155
|
metadata: {}
|
@@ -174,6 +178,6 @@ test_files:
|
|
174
178
|
- spec/danconia/exchanges/fixed_rates_spec.rb
|
175
179
|
- spec/danconia/integrations/active_record_spec.rb
|
176
180
|
- spec/danconia/money_spec.rb
|
181
|
+
- spec/danconia/stores/active_record_spec.rb
|
177
182
|
- spec/spec_helper.rb
|
178
183
|
- spec/support/database.rb
|
179
|
-
- spec/support/helpers.rb
|
data/lib/danconia/exchange.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
require 'danconia/stores/in_memory'
|
2
|
-
|
3
|
-
module Danconia
|
4
|
-
class Exchange
|
5
|
-
attr_reader :store
|
6
|
-
|
7
|
-
def initialize store: Stores::InMemory.new
|
8
|
-
@store = store
|
9
|
-
end
|
10
|
-
|
11
|
-
def rate from, to
|
12
|
-
if from == 'USD' and direct_rate = @store.direct_rate(from, to)
|
13
|
-
direct_rate
|
14
|
-
elsif to == 'USD' and inverse_rate = @store.direct_rate(to, from)
|
15
|
-
(1.0 / inverse_rate).round 6
|
16
|
-
elsif from != 'USD' and to != 'USD' and from_in_usd = rate(from, 'USD') and to_per_usd = rate('USD', to)
|
17
|
-
(from_in_usd * to_per_usd).round 6
|
18
|
-
else
|
19
|
-
raise Errors::ExchangeRateNotFound.new(from, to)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def rates
|
24
|
-
@store.rates
|
25
|
-
end
|
26
|
-
|
27
|
-
# Currently is only needed for money formatting
|
28
|
-
def available_currencies
|
29
|
-
[]
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|