active_currency 1.3.0 → 1.4.0
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/README.md +60 -35
- data/db/migrate/20180911202100_create_active_currency_rates.rb +5 -3
- data/lib/active_currency/add_rates.rb +28 -10
- data/lib/active_currency/cacheable_store.rb +6 -2
- data/lib/active_currency/configuration.rb +15 -0
- data/lib/active_currency/engine.rb +1 -1
- data/lib/active_currency/migration.rb +1 -1
- data/lib/active_currency/version.rb +1 -1
- data/lib/active_currency.rb +42 -8
- metadata +65 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc61cac61fcc7b74bf7288a1145b89af079cb527f49dc3991dd7147ebe5b824a
|
4
|
+
data.tar.gz: fc8da46d16ceae4822a6f6e3974c050bafa732122d5918276bc33b5fd09531ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96554a896dd94c5b23d274c2805421dade360cec6f77eeba451f41f0be49783264f191dd23f555df0a54230c6eb387562577fb470580223af411b22211fbeaa2
|
7
|
+
data.tar.gz: 0e2b4b110edede9724552d7ff36c35d8f6c80cd0d8449950092a84452d1fe5f64043116ccfb3f8aef1a2e7b9793973c09e47546c11d9afa31e3d98b3ce0abaa2
|
data/README.md
CHANGED
@@ -1,14 +1,12 @@
|
|
1
1
|
# ActiveCurrency
|
2
2
|
|
3
|
-
[](https://circleci.com/gh/sunny/active_currency)
|
4
|
-
|
5
3
|
Rails plugin to retrieve and store the currency rates daily to integrate
|
6
|
-
with the
|
4
|
+
with the [money-rails] gem.
|
7
5
|
|
8
6
|
## Rationale
|
9
7
|
|
10
|
-
Storing the current currency rates
|
11
|
-
|
8
|
+
Storing the current currency rates with ActiveCurrency provides the following
|
9
|
+
advantages:
|
12
10
|
|
13
11
|
- Lets you query for the currency rate you actually used in your application at
|
14
12
|
any given time.
|
@@ -25,13 +23,11 @@ a call to the database.
|
|
25
23
|
## Usage
|
26
24
|
|
27
25
|
Store the current rate regularly by calling in a scheduled job (using something
|
28
|
-
like [sidekiq-scheduler]
|
29
|
-
|
30
|
-
or [active_scheduler](https://github.com/JustinAiken/active_scheduler))
|
31
|
-
with the currencies you want to store:
|
26
|
+
like [sidekiq-scheduler], [whenever], or [active_scheduler]) with the currencies
|
27
|
+
you want to store:
|
32
28
|
|
33
29
|
```rb
|
34
|
-
ActiveCurrency::AddRates.call(%w[EUR USD])
|
30
|
+
ActiveCurrency::AddRates.call(currencies: %w[EUR USD])
|
35
31
|
```
|
36
32
|
|
37
33
|
You can then exchange money by using the Money gem helpers:
|
@@ -51,7 +47,7 @@ ActiveCurrency::Rate.where(from: 'EUR', to: 'USD').pluck(:value)
|
|
51
47
|
|
52
48
|
## Installation
|
53
49
|
|
54
|
-
Add these lines to your application
|
50
|
+
Add these lines to your application’s `Gemfile`:
|
55
51
|
|
56
52
|
```rb
|
57
53
|
# Store and retrieve the currency from the database.
|
@@ -71,23 +67,52 @@ the currency rates and fill it for the first time.
|
|
71
67
|
|
72
68
|
## Fetching rates
|
73
69
|
|
74
|
-
|
70
|
+
Call the following regularly in a scheduled job:
|
71
|
+
|
72
|
+
```rb
|
73
|
+
ActiveCurrency::AddRates.call(currencies: %w[EUR USD])
|
74
|
+
```
|
75
|
+
|
76
|
+
The first currency you give in `currencies` is considered the default currency
|
77
|
+
against which other currency rates will be guessed if they are unavailable.
|
78
|
+
|
79
|
+
### Fetching from the European Central Bank
|
80
|
+
|
81
|
+
By defaut it uses the [eu_central_bank] to fill the currency rates.
|
75
82
|
|
76
|
-
|
77
|
-
|
78
|
-
[money-open-exchange-rates] gem
|
83
|
+
### Fetching from openexchangerates.org
|
84
|
+
|
85
|
+
To use the [money-open-exchange-rates] gem, add the gem to your `Gemfile`, then
|
86
|
+
add the following to your application’s initializers:
|
79
87
|
|
80
88
|
```rb
|
81
|
-
|
89
|
+
ActiveCurrency.configure do |config|
|
90
|
+
config.remote_bank = :open_exchange_rates
|
91
|
+
config.open_exchange_rates_app_id = '…'
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
### Fetching from a custom bank
|
82
96
|
|
83
|
-
bank
|
84
|
-
|
97
|
+
You can provide any Money-compatible bank when calling
|
98
|
+
`ActiveCurrency::AddRates`:
|
85
99
|
|
86
|
-
|
100
|
+
```rb
|
101
|
+
ActiveCurrency::AddRates.call(…, bank: …)
|
87
102
|
```
|
88
103
|
|
89
|
-
|
90
|
-
|
104
|
+
## Apply a multiplier
|
105
|
+
|
106
|
+
If you want to increase or decrease the currency rates by a given multiplier,
|
107
|
+
you can do so by setting the `multiplier` option:
|
108
|
+
|
109
|
+
```rb
|
110
|
+
ActiveCurrency.configure do |config|
|
111
|
+
config.multiplier = {
|
112
|
+
["EUR", "USD"] => 1.01,
|
113
|
+
}
|
114
|
+
end
|
115
|
+
```
|
91
116
|
|
92
117
|
## Tests
|
93
118
|
|
@@ -100,7 +125,7 @@ For that, you can use a fake rate store in your `rails_helper.rb`:
|
|
100
125
|
MoneyRails.configure do |config|
|
101
126
|
rate_store = Money::RatesStore::Memory.new.tap do |store|
|
102
127
|
store.add_rate('USD', 'EUR', 1.5)
|
103
|
-
store.add_rate('EUR', 'USD',
|
128
|
+
store.add_rate('EUR', 'USD', 0.67)
|
104
129
|
end
|
105
130
|
config.default_bank = Money::Bank::VariableExchange.new(rate_store)
|
106
131
|
end
|
@@ -108,21 +133,20 @@ end
|
|
108
133
|
|
109
134
|
## Contributing
|
110
135
|
|
111
|
-
Please file issues and pull requests
|
112
|
-
[on GitHub](https://github.com/sunny/active_currency).
|
136
|
+
Please file issues and pull requests [on GitHub].
|
113
137
|
|
114
138
|
## Development
|
115
139
|
|
116
140
|
Install:
|
117
141
|
|
118
142
|
```sh
|
119
|
-
BUNDLE_GEMFILE=Gemfile-
|
143
|
+
BUNDLE_GEMFILE=Gemfile-rails7.0 bundle install
|
120
144
|
```
|
121
145
|
|
122
146
|
Launch specs and linters:
|
123
147
|
|
124
148
|
```sh
|
125
|
-
BUNDLE_GEMFILE=Gemfile-
|
149
|
+
BUNDLE_GEMFILE=Gemfile-rails7.0 bin/rake
|
126
150
|
```
|
127
151
|
|
128
152
|
## Release
|
@@ -132,22 +156,23 @@ Update `CHANGELOG.md`, update version in `lib/active_currency/version.rb`.
|
|
132
156
|
Then:
|
133
157
|
|
134
158
|
```sh
|
135
|
-
|
136
|
-
BUNDLE_GEMFILE=Gemfile-
|
137
|
-
BUNDLE_GEMFILE=Gemfile-rails5.2 bundle update
|
138
|
-
|
139
|
-
gem install bundler:2.1.2
|
140
|
-
BUNDLE_GEMFILE=Gemfile-rails6.0 bundle update
|
159
|
+
BUNDLE_GEMFILE=Gemfile-rails6.1 bundle update
|
160
|
+
BUNDLE_GEMFILE=Gemfile-rails7.0 bundle update
|
141
161
|
|
142
|
-
git add CHANGELOG.md lib/active_currency/version.rb Gemfile-rails
|
162
|
+
git add CHANGELOG.md lib/active_currency/version.rb Gemfile-rails*
|
143
163
|
git commit -m v`ruby -r./lib/active_currency/version <<< 'puts ActiveCurrency::VERSION'`
|
144
164
|
bin/rake release
|
145
165
|
```
|
146
166
|
|
147
167
|
## License
|
148
168
|
|
149
|
-
The gem is available as open source under the terms of the
|
150
|
-
[MIT License](http://opensource.org/licenses/MIT).
|
169
|
+
The gem is available as open source under the terms of the [MIT License].
|
151
170
|
|
171
|
+
[money-rails]: https://github.com/RubyMoney/money-rails
|
172
|
+
[sidekiq-scheduler]: https://github.com/Moove-it/sidekiq-scheduler
|
173
|
+
[whenever]: https://github.com/javan/whenever
|
174
|
+
[active_scheduler]: https://github.com/JustinAiken/active_scheduler
|
152
175
|
[eu_central_bank]: https://github.com/RubyMoney/eu_central_bank
|
153
176
|
[money-open-exchange-rates]: https://github.com/spk/money-open-exchange-rates
|
177
|
+
[on GitHub]: https://github.com/sunny/active_currency
|
178
|
+
[MIT License]: http://opensource.org/licenses/MIT
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "active_currency/migration"
|
4
4
|
|
5
5
|
class CreateActiveCurrencyRates < ActiveCurrency::Migration
|
6
|
+
# rubocop:disable Metrics/MethodLength
|
6
7
|
def change
|
7
8
|
create_table :active_currency_rates do |t|
|
8
9
|
t.string :from
|
@@ -15,11 +16,12 @@ class CreateActiveCurrencyRates < ActiveCurrency::Migration
|
|
15
16
|
dir.up do
|
16
17
|
add_index :active_currency_rates,
|
17
18
|
%i[from to created_at],
|
18
|
-
name:
|
19
|
+
name: "index_active_currency_rates"
|
19
20
|
end
|
20
21
|
dir.down do
|
21
|
-
remove_index :active_currency_rates,
|
22
|
+
remove_index :active_currency_rates, "index_active_currency_rates"
|
22
23
|
end
|
23
24
|
end
|
24
25
|
end
|
26
|
+
# rubocop:enable Metrics/MethodLength
|
25
27
|
end
|
@@ -3,27 +3,41 @@
|
|
3
3
|
module ActiveCurrency
|
4
4
|
# Store the latest currency rates.
|
5
5
|
class AddRates
|
6
|
-
|
6
|
+
include AfterCommitEverywhere
|
7
|
+
|
8
|
+
def self.call(deprecated_currencies = nil, currencies: nil, bank: nil)
|
9
|
+
currencies ||= deprecated_currencies
|
10
|
+
bank ||= ActiveCurrency.remote_bank
|
11
|
+
|
12
|
+
new(currencies: currencies, bank: bank).send(:call)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def initialize(currencies:, bank:)
|
18
|
+
if currencies.size < 2
|
19
|
+
raise ArgumentError, "At least two currencies are required"
|
20
|
+
end
|
21
|
+
|
7
22
|
@currencies = currencies.map(&:to_s).map(&:upcase)
|
8
23
|
@bank = bank
|
9
24
|
end
|
10
25
|
|
26
|
+
private_class_method :new
|
27
|
+
|
11
28
|
def call
|
12
29
|
bank.update_rates
|
13
30
|
|
14
|
-
|
15
|
-
|
31
|
+
in_transaction do
|
32
|
+
rates_hash.each do |(from, to), rate|
|
33
|
+
rate = multiply_rate(from, to, rate)
|
34
|
+
store.add_rate(from, to, rate)
|
35
|
+
end
|
16
36
|
end
|
17
37
|
|
18
38
|
nil
|
19
39
|
end
|
20
40
|
|
21
|
-
def self.call(currencies, *options)
|
22
|
-
new(currencies, *options).call
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
41
|
attr_accessor :bank, :currencies
|
28
42
|
|
29
43
|
def store
|
@@ -48,7 +62,7 @@ module ActiveCurrency
|
|
48
62
|
inverse = hash[[to, from]]
|
49
63
|
return 1.fdiv(inverse) if inverse
|
50
64
|
|
51
|
-
# Rate going through the
|
65
|
+
# Rate going through the main currency (desperate)
|
52
66
|
from_main = hash[[from, main_currency]]
|
53
67
|
to_main = hash[[main_currency, to]]
|
54
68
|
return from_main * to_main if from_main && to_main
|
@@ -56,6 +70,10 @@ module ActiveCurrency
|
|
56
70
|
raise "Unknown rate between #{from} and #{to}"
|
57
71
|
end
|
58
72
|
|
73
|
+
def multiply_rate(from, to, rate)
|
74
|
+
rate * ActiveCurrency.configuration.multiplier.fetch([from, to], 1)
|
75
|
+
end
|
76
|
+
|
59
77
|
def main_currency
|
60
78
|
currencies.first
|
61
79
|
end
|
@@ -4,6 +4,8 @@ module ActiveCurrency
|
|
4
4
|
# Mixin to add caching capability to a rate store when getting the current
|
5
5
|
# cache.
|
6
6
|
module CacheableStore
|
7
|
+
include AfterCommitEverywhere
|
8
|
+
|
7
9
|
def get_rate(from, to, date = nil)
|
8
10
|
return super if date
|
9
11
|
|
@@ -15,13 +17,15 @@ module ActiveCurrency
|
|
15
17
|
def add_rate(from, to, rate, date = nil)
|
16
18
|
super
|
17
19
|
|
18
|
-
|
20
|
+
after_commit do
|
21
|
+
Rails.cache.delete(cache_key(from, to))
|
22
|
+
end
|
19
23
|
end
|
20
24
|
|
21
25
|
private
|
22
26
|
|
23
27
|
def cache_key(from, to)
|
24
|
-
[
|
28
|
+
["active_currency_rate", from, to]
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveCurrency
|
4
|
+
class Configuration
|
5
|
+
def initialize
|
6
|
+
@remote_bank = :eu_central_bank
|
7
|
+
@open_exchange_rates_app_id = nil
|
8
|
+
@multiplier = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_accessor :remote_bank,
|
12
|
+
:open_exchange_rates_app_id,
|
13
|
+
:multiplier
|
14
|
+
end
|
15
|
+
end
|
@@ -8,7 +8,7 @@ module ActiveCurrency
|
|
8
8
|
next if app.root.to_s.match(root.to_s)
|
9
9
|
|
10
10
|
paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
|
11
|
-
config.paths[
|
11
|
+
config.paths["db/migrate"].expanded.each do |path|
|
12
12
|
paths << path
|
13
13
|
end
|
14
14
|
paths.uniq!
|
data/lib/active_currency.rb
CHANGED
@@ -1,14 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "money-rails"
|
4
|
+
require "after_commit_everywhere"
|
5
5
|
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
6
|
+
require "active_currency/configuration"
|
7
|
+
require "active_currency/engine"
|
8
|
+
require "active_currency/database_store"
|
9
|
+
require "active_currency/cacheable_store"
|
10
|
+
require "active_currency/rate_store"
|
11
|
+
require "active_currency/add_rates"
|
12
|
+
require "active_currency/bank"
|
12
13
|
|
13
14
|
module ActiveCurrency
|
15
|
+
class << self
|
16
|
+
def configure
|
17
|
+
yield configuration
|
18
|
+
end
|
19
|
+
|
20
|
+
def configuration
|
21
|
+
@configuration ||= Configuration.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def remote_bank
|
25
|
+
case configuration.remote_bank
|
26
|
+
when :eu_central_bank then eu_central_bank_instance
|
27
|
+
when :open_exchange_rates then open_exchange_rates_instance
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def eu_central_bank_instance
|
34
|
+
require "eu_central_bank"
|
35
|
+
|
36
|
+
EuCentralBank.new
|
37
|
+
end
|
38
|
+
|
39
|
+
def open_exchange_rates_instance
|
40
|
+
require "money/bank/open_exchange_rates_bank"
|
41
|
+
|
42
|
+
store = Money::RatesStore::Memory.new
|
43
|
+
bank = Money::Bank::OpenExchangeRatesBank.new(store)
|
44
|
+
bank.app_id = configuration.open_exchange_rates_app_id
|
45
|
+
bank
|
46
|
+
end
|
47
|
+
end
|
14
48
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_currency
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sunny Ripert
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: after_commit_everywhere
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.3.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 1.3.0
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: eu_central_bank
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +66,20 @@ dependencies:
|
|
52
66
|
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: 1.3.1
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: money-open-exchange-rates
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: sqlite3
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +122,20 @@ dependencies:
|
|
94
122
|
- - ">="
|
95
123
|
- !ruby/object:Gem::Version
|
96
124
|
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rspec-github
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
97
139
|
- !ruby/object:Gem::Dependency
|
98
140
|
name: rspec_junit_formatter
|
99
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,6 +206,20 @@ dependencies:
|
|
164
206
|
- - ">="
|
165
207
|
- !ruby/object:Gem::Version
|
166
208
|
version: '0'
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: rubocop-rspec
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - ">="
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '0'
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - ">="
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '0'
|
167
223
|
description: Store your currency.
|
168
224
|
email:
|
169
225
|
- sunny@sunfox.org
|
@@ -179,6 +235,7 @@ files:
|
|
179
235
|
- lib/active_currency/add_rates.rb
|
180
236
|
- lib/active_currency/bank.rb
|
181
237
|
- lib/active_currency/cacheable_store.rb
|
238
|
+
- lib/active_currency/configuration.rb
|
182
239
|
- lib/active_currency/database_store.rb
|
183
240
|
- lib/active_currency/engine.rb
|
184
241
|
- lib/active_currency/migration.rb
|
@@ -187,8 +244,9 @@ files:
|
|
187
244
|
homepage: https://github.com/sunny/active_currency
|
188
245
|
licenses:
|
189
246
|
- MIT
|
190
|
-
metadata:
|
191
|
-
|
247
|
+
metadata:
|
248
|
+
rubygems_mfa_required: 'true'
|
249
|
+
post_install_message:
|
192
250
|
rdoc_options: []
|
193
251
|
require_paths:
|
194
252
|
- lib
|
@@ -203,8 +261,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
203
261
|
- !ruby/object:Gem::Version
|
204
262
|
version: '0'
|
205
263
|
requirements: []
|
206
|
-
rubygems_version: 3.
|
207
|
-
signing_key:
|
264
|
+
rubygems_version: 3.3.26
|
265
|
+
signing_key:
|
208
266
|
specification_version: 4
|
209
267
|
summary: Rails plugin to store your currency regularly
|
210
268
|
test_files: []
|