active_currency 1.2.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 938c7b875052bf9d26b9ade8d9f1f268a94da7949a1685961a4265b01ed70a1c
4
- data.tar.gz: cd167c1b911156c2025d75b29be92cfdfceed15aac7533b736db5bb63a59d3bc
3
+ metadata.gz: dc61cac61fcc7b74bf7288a1145b89af079cb527f49dc3991dd7147ebe5b824a
4
+ data.tar.gz: fc8da46d16ceae4822a6f6e3974c050bafa732122d5918276bc33b5fd09531ff
5
5
  SHA512:
6
- metadata.gz: 51af4e890792d65780f3ce822ca6bef58465b2a34578b7edb0c6776d8d104ba569ef282dd7004715944e7d388b44a3935c5e0659ae87fdbf3f01ce1b36fd1cec
7
- data.tar.gz: 2b66ea9433ccf5e35b54e22296b95a765dd9b249930e02c056d49afcc0c9f8a6731e7340db6db606fcbda33be7b4bc5d4f6fac53dc75dbae7e4a1b6991f634cc
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,11 +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`, `whenever`, or `active_scheduler`) with the currencies
26
+ like [sidekiq-scheduler], [whenever], or [active_scheduler]) with the currencies
29
27
  you want to store:
30
28
 
31
29
  ```rb
32
- ActiveCurrency::AddRates.call(%w[EUR USD])
30
+ ActiveCurrency::AddRates.call(currencies: %w[EUR USD])
33
31
  ```
34
32
 
35
33
  You can then exchange money by using the Money gem helpers:
@@ -49,7 +47,7 @@ ActiveCurrency::Rate.where(from: 'EUR', to: 'USD').pluck(:value)
49
47
 
50
48
  ## Installation
51
49
 
52
- Add these lines to your application's `Gemfile`:
50
+ Add these lines to your applications `Gemfile`:
53
51
 
54
52
  ```rb
55
53
  # Store and retrieve the currency from the database.
@@ -69,23 +67,52 @@ the currency rates and fill it for the first time.
69
67
 
70
68
  ## Fetching rates
71
69
 
72
- 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.
73
82
 
74
- If you prefer another API, you can provide any Money-compatible bank when
75
- calling `ActiveCurrency::AddRates`. For example with the
76
- [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:
77
87
 
78
88
  ```rb
79
- 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
80
96
 
81
- bank = Money::Bank::OpenExchangeRatesBank.new(Money::RatesStore::Memory.new)
82
- bank.app_id = '…'
97
+ You can provide any Money-compatible bank when calling
98
+ `ActiveCurrency::AddRates`:
83
99
 
84
- ActiveCurrency::AddRates.call(%w[EUR USD], bank: bank)
100
+ ```rb
101
+ ActiveCurrency::AddRates.call(…, bank: …)
85
102
  ```
86
103
 
87
- The first currency you give to `AddRates` is considered the default currency
88
- 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
+ ```
89
116
 
90
117
  ## Tests
91
118
 
@@ -98,7 +125,7 @@ For that, you can use a fake rate store in your `rails_helper.rb`:
98
125
  MoneyRails.configure do |config|
99
126
  rate_store = Money::RatesStore::Memory.new.tap do |store|
100
127
  store.add_rate('USD', 'EUR', 1.5)
101
- store.add_rate('EUR', 'USD', 1.4)
128
+ store.add_rate('EUR', 'USD', 0.67)
102
129
  end
103
130
  config.default_bank = Money::Bank::VariableExchange.new(rate_store)
104
131
  end
@@ -106,21 +133,20 @@ end
106
133
 
107
134
  ## Contributing
108
135
 
109
- Please file issues and pull requests
110
- [on GitHub](https://github.com/sunny/active_currency).
136
+ Please file issues and pull requests [on GitHub].
111
137
 
112
138
  ## Development
113
139
 
114
140
  Install:
115
141
 
116
142
  ```sh
117
- BUNDLE_GEMFILE=Gemfile-rails6.0 bundle install
143
+ BUNDLE_GEMFILE=Gemfile-rails7.0 bundle install
118
144
  ```
119
145
 
120
146
  Launch specs and linters:
121
147
 
122
148
  ```sh
123
- BUNDLE_GEMFILE=Gemfile-rails6.0 bin/rake
149
+ BUNDLE_GEMFILE=Gemfile-rails7.0 bin/rake
124
150
  ```
125
151
 
126
152
  ## Release
@@ -130,23 +156,23 @@ Update `CHANGELOG.md`, update version in `lib/active_currency/version.rb`.
130
156
  Then:
131
157
 
132
158
  ```sh
133
- gem install bundler:1.3.0
134
- BUNDLE_GEMFILE=Gemfile-rails3.2 bundle update
135
- BUNDLE_GEMFILE=Gemfile-rails4.2 bundle update
136
- BUNDLE_GEMFILE=Gemfile-rails5.2 bundle update
137
-
138
- gem install bundler:2.1.2
139
- BUNDLE_GEMFILE=Gemfile-rails6.0 bundle update
159
+ BUNDLE_GEMFILE=Gemfile-rails6.1 bundle update
160
+ BUNDLE_GEMFILE=Gemfile-rails7.0 bundle update
140
161
 
141
- git add CHANGELOG.md lib/active_currency/version.rb Gemfile-rails*.lock
162
+ git add CHANGELOG.md lib/active_currency/version.rb Gemfile-rails*
142
163
  git commit -m v`ruby -r./lib/active_currency/version <<< 'puts ActiveCurrency::VERSION'`
143
164
  bin/rake release
144
165
  ```
145
166
 
146
167
  ## License
147
168
 
148
- The gem is available as open source under the terms of the
149
- [MIT License](http://opensource.org/licenses/MIT).
169
+ The gem is available as open source under the terms of the [MIT License].
150
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
151
175
  [eu_central_bank]: https://github.com/RubyMoney/eu_central_bank
152
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
@@ -15,17 +15,12 @@ module ActiveCurrency
15
15
  to = Money::Currency.new(to)
16
16
  return 1 if from == to
17
17
 
18
- scope = date ? before(date) : all_scope
18
+ scope = date ? before(date) : all
19
19
  scope
20
20
  .where(from: from.iso_code, to: to.iso_code)
21
21
  .order(:created_at)
22
22
  .last
23
23
  &.value
24
24
  end
25
-
26
- # Scope retrocompatibility for Rails 3.2.
27
- def self.all_scope
28
- respond_to?(:scoped) ? scoped : all
29
- end
30
25
  end
31
26
  end
@@ -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
@@ -11,8 +12,16 @@ class CreateActiveCurrencyRates < ActiveCurrency::Migration
11
12
  t.datetime :created_at
12
13
  end
13
14
 
14
- add_index :active_currency_rates,
15
- %i[from to created_at],
16
- name: 'index_active_currency_rates'
15
+ reversible do |dir|
16
+ dir.up do
17
+ add_index :active_currency_rates,
18
+ %i[from to created_at],
19
+ name: "index_active_currency_rates"
20
+ end
21
+ dir.down do
22
+ remove_index :active_currency_rates, "index_active_currency_rates"
23
+ end
24
+ end
17
25
  end
26
+ # rubocop:enable Metrics/MethodLength
18
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
@@ -7,8 +7,8 @@ module ActiveCurrency
7
7
  initializer :append_migrations do |app|
8
8
  next if app.root.to_s.match(root.to_s)
9
9
 
10
- paths = ActiveRecord::Migrator.migrations_paths
11
- config.paths['db/migrate'].expanded.each do |path|
10
+ paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
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.2.1'
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.2.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: 2020-09-03 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
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '3.2'
19
+ version: '4.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '3.2'
26
+ version: '4.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: money-rails
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -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: []