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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6712c0205342cb855a5c816cbcf29a9d2d81266f12b34cf580055e4ad66977fe
4
- data.tar.gz: a8b33afc0657a7164bffa81fc6d0fa7115c6863d30af7fe2f52b93d223a51998
3
+ metadata.gz: dc61cac61fcc7b74bf7288a1145b89af079cb527f49dc3991dd7147ebe5b824a
4
+ data.tar.gz: fc8da46d16ceae4822a6f6e3974c050bafa732122d5918276bc33b5fd09531ff
5
5
  SHA512:
6
- metadata.gz: c138d27d24190e33af49618b03adbd2df9a2e3e72fc9b39ad7ad8e2ffefa47b6b73a17216221677732d7392b8b5998fb23b9b6ca8ba3f32f020372e63f924cf4
7
- data.tar.gz: 36b38e8effcd0566ef0f6c4ed48d1d53d4da140a208673c3747e89a7afca32fd18f6a9405c2589f3b559ae91bf79f0e42e46ac276384a920a29f278c28d1a0a2
6
+ metadata.gz: 96554a896dd94c5b23d274c2805421dade360cec6f77eeba451f41f0be49783264f191dd23f555df0a54230c6eb387562577fb470580223af411b22211fbeaa2
7
+ data.tar.gz: 0e2b4b110edede9724552d7ff36c35d8f6c80cd0d8449950092a84452d1fe5f64043116ccfb3f8aef1a2e7b9793973c09e47546c11d9afa31e3d98b3ce0abaa2
data/README.md CHANGED
@@ -1,14 +1,12 @@
1
1
  # ActiveCurrency
2
2
 
3
- [![CircleCI](https://circleci.com/gh/sunny/active_currency.svg?style=svg)](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 `money-rails` gem.
4
+ with the [money-rails] gem.
7
5
 
8
6
  ## Rationale
9
7
 
10
- Storing the current currency rates in the database using ActiveCurrency
11
- provides the following advantages:
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](https://github.com/Moove-it/sidekiq-scheduler),
29
- [whenever](https://github.com/javan/whenever),
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's `Gemfile`:
50
+ Add these lines to your applications `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
- By defaut it uses the [eu_central_bank] to update the currency rates.
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
- If you prefer another API, you can provide any Money-compatible bank when
77
- calling `ActiveCurrency::AddRates`. For example with the
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
- require 'money/bank/open_exchange_rates_bank'
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 = Money::Bank::OpenExchangeRatesBank.new(Money::RatesStore::Memory.new)
84
- bank.app_id = '…'
97
+ You can provide any Money-compatible bank when calling
98
+ `ActiveCurrency::AddRates`:
85
99
 
86
- ActiveCurrency::AddRates.call(%w[EUR USD], bank: bank)
100
+ ```rb
101
+ ActiveCurrency::AddRates.call(…, bank: …)
87
102
  ```
88
103
 
89
- The first currency you give to `AddRates` is considered the default currency
90
- against which other currency rates will be guessed if they are unavailable.
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', 1.4)
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-rails6.0 bundle install
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-rails6.0 bin/rake
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
- gem install bundler:1.17.2
136
- BUNDLE_GEMFILE=Gemfile-rails4.2 bundle update
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*.lock
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 'active_currency/migration'
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: 'index_active_currency_rates'
19
+ name: "index_active_currency_rates"
19
20
  end
20
21
  dir.down do
21
- remove_index :active_currency_rates, '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
- def initialize(currencies, bank: EuCentralBank.new)
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
- rates_hash.each do |(from, to), rate|
15
- store.add_rate(from, to, rate)
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 first currency (desperate)
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
- Rails.cache.delete(cache_key(from, to))
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
- ['active_currency_rate', from, to]
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['db/migrate'].expanded.each do |path|
11
+ config.paths["db/migrate"].expanded.each do |path|
12
12
  paths << path
13
13
  end
14
14
  paths.uniq!
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ActiveCurrency
4
4
  # Helps support previous version of Rails in migrations.
5
- if Rails.version > '5.0'
5
+ if Rails.version > "5.0"
6
6
  class Migration < ActiveRecord::Migration[5.0]; end
7
7
  else
8
8
  class Migration < ActiveRecord::Migration; end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveCurrency
4
- VERSION = '1.3.0'
4
+ VERSION = "1.4.0"
5
5
  end
@@ -1,14 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'money-rails'
4
- require 'eu_central_bank'
3
+ require "money-rails"
4
+ require "after_commit_everywhere"
5
5
 
6
- require 'active_currency/engine'
7
- require 'active_currency/database_store'
8
- require 'active_currency/cacheable_store'
9
- require 'active_currency/rate_store'
10
- require 'active_currency/add_rates'
11
- require 'active_currency/bank'
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.3.0
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: 2021-04-29 00:00:00.000000000 Z
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
- post_install_message:
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.0.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: []