money 7.0.2 → 7.1.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/CHANGELOG.md +9 -0
- data/README.md +1 -0
- data/config/currency_iso.json +4 -4
- data/lib/money/bank/base.rb +3 -7
- data/lib/money/bank/single_currency.rb +2 -3
- data/lib/money/bank/variable_exchange.rb +34 -37
- data/lib/money/currency/heuristics.rb +1 -1
- data/lib/money/currency/loader.rb +1 -1
- data/lib/money/currency.rb +53 -32
- data/lib/money/locale_backend/base.rb +1 -1
- data/lib/money/locale_backend/currency.rb +1 -1
- data/lib/money/locale_backend/i18n.rb +6 -4
- data/lib/money/money/allocation.rb +10 -9
- data/lib/money/money/arithmetic.rb +34 -25
- data/lib/money/money/constructors.rb +5 -6
- data/lib/money/money/formatter.rb +25 -20
- data/lib/money/money/formatting_rules.rb +4 -2
- data/lib/money/money/locale_backend.rb +4 -4
- data/lib/money/money.rb +25 -30
- data/lib/money/rates_store/memory.rb +5 -8
- data/lib/money/version.rb +1 -1
- data/money.gemspec +7 -7
- data/sig/lib/money/bank/base.rbs +117 -0
- data/sig/lib/money/bank/single_currency.rbs +15 -0
- data/sig/lib/money/bank/variable_exchange.rbs +198 -0
- data/sig/lib/money/currency/heuristics.rbs +8 -0
- data/sig/lib/money/currency.rbs +322 -0
- data/sig/lib/money/locale_backend/base.rbs +6 -0
- data/sig/lib/money/locale_backend/errors.rbs +9 -0
- data/sig/lib/money/locale_backend/i18n.rbs +11 -0
- data/sig/lib/money/money/allocation.rbs +24 -0
- data/sig/lib/money/money/arithmetic.rbs +225 -0
- data/sig/lib/money/money/constructors.rbs +73 -0
- data/sig/lib/money/money/formatter.rbs +214 -0
- data/sig/lib/money/money/formatting_rules.rbs +32 -0
- data/sig/lib/money/money/locale_backend.rbs +7 -0
- data/sig/lib/money/money.rbs +522 -0
- data/sig/lib/money/rates_store/memory.rbs +90 -0
- data/sig/manifest.yaml +10 -0
- metadata +20 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3a44852483d5fd18199ba0d2fdd0db1507c14ff84b2303080029a4a7323f50b2
|
|
4
|
+
data.tar.gz: 2e7ba93f0fd0963992fdede55c944383e61c61426fb67d3a6ae0281a54095ee2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c6d5f8ed8ddabb9cd8cb9641afc2a80721cbfc1edf1b5143695072297484ead6551424fb8f2f92a84b2da24baf483745ce0d34b8e9a84cec54f3b4e0c630a712
|
|
7
|
+
data.tar.gz: '0639a68c4ee3b0d896d96b2bbc8fcf7419b8e6d6ba55ae68f4811c4082f7e2288c9d7f694ee869d629f143a8b00a4d2356fd536307744eb713c9aa1f75f1ae14'
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 7.1.0
|
|
6
|
+
|
|
7
|
+
- Fix symbol for XPF (CFP Franc) currency to use "₣"
|
|
8
|
+
- Fix name for ANG currency
|
|
9
|
+
- Change disambiguate symbol for ARS from historical to international format
|
|
10
|
+
- Update documentation of disambiguate feature
|
|
11
|
+
- Include RBS type signatures (`sig/`) in the released gem
|
|
12
|
+
- Fix RBS signatures: add the missing `Money#+`, `Money#-`, `Money.from_dollars`, `Money::Currency#cents_based?` and the error classes, drop entries for methods that no longer exist, and validate the signatures in CI
|
|
13
|
+
|
|
5
14
|
## 7.0.2
|
|
6
15
|
|
|
7
16
|
- Fix `Money::Currency.register` exception when table is not initialized.
|
data/README.md
CHANGED
|
@@ -441,6 +441,7 @@ implementations.
|
|
|
441
441
|
- [money-historical-bank](https://github.com/atwam/money-historical-bank)
|
|
442
442
|
- [russian_central_bank](https://github.com/rmustafin/russian_central_bank)
|
|
443
443
|
- [money-uphold-bank](https://github.com/subvisual/money-uphold-bank)
|
|
444
|
+
- [money-unirate-api](https://github.com/UniRate-API/money-unirate-api)
|
|
444
445
|
|
|
445
446
|
## Formatting
|
|
446
447
|
|
data/config/currency_iso.json
CHANGED
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"ang": {
|
|
68
68
|
"priority": 100,
|
|
69
69
|
"iso_code": "ANG",
|
|
70
|
-
"name": "Netherlands Antillean
|
|
70
|
+
"name": "Netherlands Antillean Guilder",
|
|
71
71
|
"symbol": "ƒ",
|
|
72
72
|
"alternate_symbols": ["NAƒ", "NAf", "f"],
|
|
73
73
|
"subunit": "Cent",
|
|
@@ -100,8 +100,8 @@
|
|
|
100
100
|
"iso_code": "ARS",
|
|
101
101
|
"name": "Argentine Peso",
|
|
102
102
|
"symbol": "$",
|
|
103
|
-
"disambiguate_symbol": "$
|
|
104
|
-
"alternate_symbols": ["$
|
|
103
|
+
"disambiguate_symbol": "AR$",
|
|
104
|
+
"alternate_symbols": ["AR$"],
|
|
105
105
|
"subunit": "Centavo",
|
|
106
106
|
"subunit_to_unit": 100,
|
|
107
107
|
"symbol_first": true,
|
|
@@ -2624,7 +2624,7 @@
|
|
|
2624
2624
|
"priority": 100,
|
|
2625
2625
|
"iso_code": "XPF",
|
|
2626
2626
|
"name": "Cfp Franc",
|
|
2627
|
-
"symbol": "
|
|
2627
|
+
"symbol": "₣",
|
|
2628
2628
|
"alternate_symbols": ["F"],
|
|
2629
2629
|
"subunit": "Centime",
|
|
2630
2630
|
"subunit_to_unit": 1,
|
data/lib/money/bank/base.rb
CHANGED
|
@@ -4,7 +4,6 @@ class Money
|
|
|
4
4
|
# Provides classes that aid in the ability of exchange one currency with
|
|
5
5
|
# another.
|
|
6
6
|
module Bank
|
|
7
|
-
|
|
8
7
|
# The lowest Money::Bank error class.
|
|
9
8
|
# All Money::Bank errors should inherit from it.
|
|
10
9
|
class Error < StandardError
|
|
@@ -15,7 +14,6 @@ class Money
|
|
|
15
14
|
class UnknownRate < Error
|
|
16
15
|
end
|
|
17
16
|
|
|
18
|
-
|
|
19
17
|
# Money::Bank::Base is the basic interface for creating a money exchange
|
|
20
18
|
# object, also called Bank.
|
|
21
19
|
#
|
|
@@ -40,12 +38,11 @@ class Money
|
|
|
40
38
|
# +Money::Bank+ class. You can also override +#setup+ instead of
|
|
41
39
|
# +#initialize+ to setup initial variables, etc.
|
|
42
40
|
class Base
|
|
43
|
-
|
|
44
41
|
# Returns the singleton instance of the Base bank.
|
|
45
42
|
#
|
|
46
43
|
# @return [Money::Bank::Base]
|
|
47
44
|
def self.instance
|
|
48
|
-
@
|
|
45
|
+
@instance ||= new
|
|
49
46
|
end
|
|
50
47
|
|
|
51
48
|
# The rounding method to use when exchanging rates.
|
|
@@ -81,8 +78,7 @@ class Money
|
|
|
81
78
|
# +Money::Bank+ class.
|
|
82
79
|
#
|
|
83
80
|
# @return [self]
|
|
84
|
-
def setup
|
|
85
|
-
end
|
|
81
|
+
def setup; end
|
|
86
82
|
|
|
87
83
|
# Exchanges the given +Money+ object to a new +Money+ object in
|
|
88
84
|
# +to_currency+.
|
|
@@ -102,7 +98,7 @@ class Money
|
|
|
102
98
|
# @yieldreturn [Integer]
|
|
103
99
|
#
|
|
104
100
|
# @return [Money]
|
|
105
|
-
def exchange_with(from, to_currency, &
|
|
101
|
+
def exchange_with(from, to_currency, &)
|
|
106
102
|
raise NotImplementedError, "#exchange_with must be implemented"
|
|
107
103
|
end
|
|
108
104
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "money/bank/base"
|
|
4
4
|
|
|
5
5
|
class Money
|
|
6
6
|
module Bank
|
|
@@ -15,10 +15,9 @@ class Money
|
|
|
15
15
|
# where exchanges happen are erroneous. Using this as the default bank
|
|
16
16
|
# means that that these mistakes don't silently do the wrong thing.
|
|
17
17
|
class SingleCurrency < Base
|
|
18
|
-
|
|
19
18
|
# Raises a DifferentCurrencyError to remove possibility of accidentally
|
|
20
19
|
# exchanging currencies
|
|
21
|
-
def exchange_with(from, to_currency, &
|
|
20
|
+
def exchange_with(from, to_currency, &)
|
|
22
21
|
raise DifferentCurrencyError, "No exchanging of currencies allowed: #{from} #{from.currency} to #{to_currency}"
|
|
23
22
|
end
|
|
24
23
|
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
3
|
+
require "money/bank/base"
|
|
4
|
+
require "money/rates_store/memory"
|
|
5
|
+
require "json"
|
|
6
|
+
require "yaml"
|
|
7
7
|
|
|
8
8
|
class Money
|
|
9
9
|
module Bank
|
|
@@ -43,13 +43,12 @@ class Money
|
|
|
43
43
|
# # Get rate from redis
|
|
44
44
|
# bank.get_rate 'USD', 'CAD'
|
|
45
45
|
class VariableExchange < Base
|
|
46
|
-
|
|
47
46
|
attr_reader :mutex
|
|
48
47
|
|
|
49
48
|
# Available formats for importing/exporting rates.
|
|
50
49
|
RATE_FORMATS = [:json, :ruby, :yaml].freeze
|
|
51
|
-
SERIALIZER_SEPARATOR =
|
|
52
|
-
FORMAT_SERIALIZERS = {json: JSON, ruby: Marshal, yaml: YAML}.freeze
|
|
50
|
+
SERIALIZER_SEPARATOR = "_TO_"
|
|
51
|
+
FORMAT_SERIALIZERS = { json: JSON, ruby: Marshal, yaml: YAML }.freeze
|
|
53
52
|
|
|
54
53
|
# Initializes a new +Money::Bank::VariableExchange+ object.
|
|
55
54
|
# It defaults to using an in-memory, thread safe store instance for
|
|
@@ -58,9 +57,9 @@ class Money
|
|
|
58
57
|
# @param [RateStore] st An exchange rate store, used to persist exchange rate pairs.
|
|
59
58
|
# @yield [n] Optional block to use when rounding after exchanging one
|
|
60
59
|
# currency for another. See +Money::bank::base+
|
|
61
|
-
def initialize(
|
|
62
|
-
@store =
|
|
63
|
-
super(&
|
|
60
|
+
def initialize(store = Money::RatesStore::Memory.new, &)
|
|
61
|
+
@store = store
|
|
62
|
+
super(&)
|
|
64
63
|
end
|
|
65
64
|
|
|
66
65
|
def store
|
|
@@ -108,21 +107,19 @@ class Money
|
|
|
108
107
|
#
|
|
109
108
|
# # Exchange 100 CAD to USD:
|
|
110
109
|
# bank.exchange_with(c2, "USD") #=> #<Money fractional:8031 currency:USD>
|
|
111
|
-
def exchange_with(from, to_currency, &
|
|
110
|
+
def exchange_with(from, to_currency, &)
|
|
112
111
|
to_currency = Currency.wrap(to_currency)
|
|
113
112
|
if from.currency == to_currency
|
|
114
113
|
from
|
|
114
|
+
elsif (rate = get_rate(from.currency, to_currency))
|
|
115
|
+
fractional = calculate_fractional(from, to_currency)
|
|
116
|
+
from.dup_with(
|
|
117
|
+
fractional: exchange(fractional, rate, &),
|
|
118
|
+
currency: to_currency,
|
|
119
|
+
bank: self,
|
|
120
|
+
)
|
|
115
121
|
else
|
|
116
|
-
|
|
117
|
-
fractional = calculate_fractional(from, to_currency)
|
|
118
|
-
from.dup_with(
|
|
119
|
-
fractional: exchange(fractional, rate, &block),
|
|
120
|
-
currency: to_currency,
|
|
121
|
-
bank: self
|
|
122
|
-
)
|
|
123
|
-
else
|
|
124
|
-
raise UnknownRate, "No conversion rate known for '#{from.currency.iso_code}' -> '#{to_currency}'"
|
|
125
|
-
end
|
|
122
|
+
raise UnknownRate, "No conversion rate known for '#{from.currency.iso_code}' -> '#{to_currency}'"
|
|
126
123
|
end
|
|
127
124
|
end
|
|
128
125
|
|
|
@@ -133,7 +130,7 @@ class Money
|
|
|
133
130
|
)
|
|
134
131
|
end
|
|
135
132
|
|
|
136
|
-
def exchange(fractional, rate, &
|
|
133
|
+
def exchange(fractional, rate, &)
|
|
137
134
|
ex = fractional * BigDecimal(rate.to_s)
|
|
138
135
|
if block_given?
|
|
139
136
|
yield ex
|
|
@@ -176,7 +173,7 @@ class Money
|
|
|
176
173
|
# bank = Money::Bank::VariableExchange.new
|
|
177
174
|
# bank.set_rate("USD", "CAD", 1.24515)
|
|
178
175
|
# bank.set_rate("CAD", "USD", 0.803115)
|
|
179
|
-
def set_rate(from, to, rate,
|
|
176
|
+
def set_rate(from, to, rate, _opts = {})
|
|
180
177
|
store.add_rate(Currency.wrap(from).iso_code, Currency.wrap(to).iso_code, rate)
|
|
181
178
|
end
|
|
182
179
|
|
|
@@ -197,7 +194,7 @@ class Money
|
|
|
197
194
|
#
|
|
198
195
|
# bank.get_rate("USD", "CAD") #=> 1.24515
|
|
199
196
|
# bank.get_rate("CAD", "USD") #=> 0.803115
|
|
200
|
-
def get_rate(from, to,
|
|
197
|
+
def get_rate(from, to, _opts = {})
|
|
201
198
|
store.get_rate(Currency.wrap(from).iso_code, Currency.wrap(to).iso_code)
|
|
202
199
|
end
|
|
203
200
|
|
|
@@ -220,14 +217,14 @@ class Money
|
|
|
220
217
|
#
|
|
221
218
|
# s = bank.export_rates(:json)
|
|
222
219
|
# s #=> "{\"USD_TO_CAD\":1.24515,\"CAD_TO_USD\":0.803115}"
|
|
223
|
-
def export_rates(format, file = nil,
|
|
220
|
+
def export_rates(format, file = nil, _opts = {})
|
|
224
221
|
raise Money::Bank::UnknownRateFormat unless RATE_FORMATS.include?(format)
|
|
225
222
|
|
|
226
223
|
store.transaction do
|
|
227
224
|
s = FORMAT_SERIALIZERS[format].dump(rates)
|
|
228
225
|
|
|
229
226
|
unless file.nil?
|
|
230
|
-
File.
|
|
227
|
+
File.write(file, s)
|
|
231
228
|
end
|
|
232
229
|
|
|
233
230
|
s
|
|
@@ -236,17 +233,17 @@ class Money
|
|
|
236
233
|
|
|
237
234
|
# This should be deprecated.
|
|
238
235
|
def rates
|
|
239
|
-
store.each_rate.
|
|
236
|
+
store.each_rate.with_object({}) do |(from, to, rate), hash|
|
|
240
237
|
hash[[from, to].join(SERIALIZER_SEPARATOR)] = rate
|
|
241
238
|
end
|
|
242
239
|
end
|
|
243
240
|
|
|
244
|
-
# Loads rates provided in +
|
|
241
|
+
# Loads rates provided in +string+ given the specified format. Available
|
|
245
242
|
# formats are +:json+, +:ruby+ and +:yaml+.
|
|
246
243
|
# Delegates to +Money::RatesStore::Memory+
|
|
247
244
|
#
|
|
248
|
-
# @param [Symbol] format The format of +
|
|
249
|
-
# @param [String]
|
|
245
|
+
# @param [Symbol] format The format of +string+.
|
|
246
|
+
# @param [String] string The rates string.
|
|
250
247
|
# @param [Hash] opts Options hash to set special parameters. Backwards compatibility only.
|
|
251
248
|
#
|
|
252
249
|
# @return [self]
|
|
@@ -254,23 +251,23 @@ class Money
|
|
|
254
251
|
# @raise +Money::Bank::UnknownRateFormat+ if format is unknown.
|
|
255
252
|
#
|
|
256
253
|
# @example
|
|
257
|
-
#
|
|
254
|
+
# string = "{\"USD_TO_CAD\":1.24515,\"CAD_TO_USD\":0.803115}"
|
|
258
255
|
# bank = Money::Bank::VariableExchange.new
|
|
259
|
-
# bank.import_rates(:json,
|
|
256
|
+
# bank.import_rates(:json, string)
|
|
260
257
|
#
|
|
261
258
|
# bank.get_rate("USD", "CAD") #=> 1.24515
|
|
262
259
|
# bank.get_rate("CAD", "USD") #=> 0.803115
|
|
263
|
-
def import_rates(format,
|
|
260
|
+
def import_rates(format, string, _opts = {})
|
|
264
261
|
raise Money::Bank::UnknownRateFormat unless RATE_FORMATS.include?(format)
|
|
265
262
|
|
|
266
263
|
if format == :ruby
|
|
267
|
-
warn
|
|
268
|
-
|
|
269
|
-
|
|
264
|
+
warn "[WARNING] Using :ruby format when importing rates is potentially unsafe and " \
|
|
265
|
+
"might lead to remote code execution via Marshal.load deserializer. Consider using " \
|
|
266
|
+
"safe alternatives such as :json and :yaml."
|
|
270
267
|
end
|
|
271
268
|
|
|
272
269
|
store.transaction do
|
|
273
|
-
data = FORMAT_SERIALIZERS[format].load(
|
|
270
|
+
data = FORMAT_SERIALIZERS[format].load(string)
|
|
274
271
|
|
|
275
272
|
data.each do |key, rate|
|
|
276
273
|
from, to = key.split(SERIALIZER_SEPARATOR)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
class Money
|
|
4
4
|
class Currency
|
|
5
5
|
module Loader
|
|
6
|
-
DATA_PATH = File.expand_path("
|
|
6
|
+
DATA_PATH = File.expand_path("../../../config", __dir__)
|
|
7
7
|
|
|
8
8
|
class << self
|
|
9
9
|
# Loads and returns the currencies stored in JSON files in the config directory.
|
data/lib/money/currency.rb
CHANGED
|
@@ -5,7 +5,6 @@ require "money/currency/loader"
|
|
|
5
5
|
require "money/currency/heuristics"
|
|
6
6
|
|
|
7
7
|
class Money
|
|
8
|
-
|
|
9
8
|
# Represents a specific currency unit.
|
|
10
9
|
#
|
|
11
10
|
# @see https://en.wikipedia.org/wiki/Currency
|
|
@@ -24,7 +23,7 @@ class Money
|
|
|
24
23
|
class MissingAttributeError < StandardError
|
|
25
24
|
def initialize(method, currency, attribute)
|
|
26
25
|
super(
|
|
27
|
-
"Can't call Currency.#{method} - currency '#{currency}' is missing "\
|
|
26
|
+
"Can't call Currency.#{method} - currency '#{currency}' is missing " \
|
|
28
27
|
"the attribute '#{attribute}'"
|
|
29
28
|
)
|
|
30
29
|
end
|
|
@@ -81,8 +80,9 @@ class Money
|
|
|
81
80
|
# Money::Currency.find_by_iso_numeric(51) #=> #<Money::Currency id: amd ...>
|
|
82
81
|
# Money::Currency.find_by_iso_numeric('001') #=> nil
|
|
83
82
|
def find_by_iso_numeric(num)
|
|
84
|
-
num = num.to_s.rjust(3,
|
|
83
|
+
num = num.to_s.rjust(3, "0")
|
|
85
84
|
return if num.empty?
|
|
85
|
+
|
|
86
86
|
id = iso_numeric_index[num]
|
|
87
87
|
new(id) if id
|
|
88
88
|
rescue UnknownCurrency
|
|
@@ -139,6 +139,7 @@ class Money
|
|
|
139
139
|
if c.priority.nil?
|
|
140
140
|
raise MissingAttributeError.new(:all, c.id, :priority)
|
|
141
141
|
end
|
|
142
|
+
|
|
142
143
|
c
|
|
143
144
|
end.sort_by(&:priority)
|
|
144
145
|
end
|
|
@@ -195,19 +196,22 @@ class Money
|
|
|
195
196
|
#
|
|
196
197
|
# @return [Boolean] true if the currency previously existed, false
|
|
197
198
|
# if it didn't.
|
|
199
|
+
# rubocop:disable Naming/PredicateMethod
|
|
198
200
|
def unregister(curr)
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
201
|
+
key =
|
|
202
|
+
if curr.is_a?(Hash)
|
|
203
|
+
curr.fetch(:iso_code).downcase.to_sym
|
|
204
|
+
else
|
|
205
|
+
curr.downcase.to_sym
|
|
206
|
+
end
|
|
204
207
|
existed = @table.delete(key)
|
|
205
208
|
@stringified_keys = nil if existed
|
|
206
209
|
existed ? true : false
|
|
207
210
|
end
|
|
211
|
+
# rubocop:enable Naming/PredicateMethod
|
|
208
212
|
|
|
209
|
-
def each
|
|
210
|
-
all.each
|
|
213
|
+
def each(&)
|
|
214
|
+
all.each(&)
|
|
211
215
|
end
|
|
212
216
|
|
|
213
217
|
def reset!
|
|
@@ -271,12 +275,12 @@ class Money
|
|
|
271
275
|
# this currency)
|
|
272
276
|
|
|
273
277
|
attr_reader :id, :priority, :iso_code, :iso_numeric, :name, :symbol,
|
|
274
|
-
|
|
275
|
-
|
|
278
|
+
:disambiguate_symbol, :html_entity, :subunit, :subunit_to_unit, :decimal_mark,
|
|
279
|
+
:thousands_separator, :symbol_first, :smallest_denomination, :format
|
|
276
280
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
281
|
+
alias separator decimal_mark
|
|
282
|
+
alias delimiter thousands_separator
|
|
283
|
+
alias eql? ==
|
|
280
284
|
|
|
281
285
|
# Create a new +Currency+ object.
|
|
282
286
|
#
|
|
@@ -305,12 +309,12 @@ class Money
|
|
|
305
309
|
# c1 <=> c2 #=> 1
|
|
306
310
|
# c2 <=> c1 #=> -1
|
|
307
311
|
# c1 <=> c1 #=> 0
|
|
308
|
-
def <=>(
|
|
312
|
+
def <=>(other)
|
|
309
313
|
# <=> returns nil when one of the values is nil
|
|
310
|
-
comparison =
|
|
314
|
+
comparison = priority <=> other.priority || 0
|
|
311
315
|
|
|
312
316
|
if comparison == 0
|
|
313
|
-
|
|
317
|
+
id <=> other.id
|
|
314
318
|
else
|
|
315
319
|
comparison
|
|
316
320
|
end
|
|
@@ -328,19 +332,9 @@ class Money
|
|
|
328
332
|
# c2 = Money::Currency.new(:jpy)
|
|
329
333
|
# c1 == c1 #=> true
|
|
330
334
|
# c1 == c2 #=> false
|
|
331
|
-
def ==(
|
|
332
|
-
|
|
333
|
-
end
|
|
334
|
-
|
|
335
|
-
def compare_ids(other_currency)
|
|
336
|
-
other_currency_id = if other_currency.is_a?(Currency)
|
|
337
|
-
other_currency.id.to_s.downcase
|
|
338
|
-
else
|
|
339
|
-
other_currency.to_s.downcase
|
|
340
|
-
end
|
|
341
|
-
self.id.to_s.downcase == other_currency_id
|
|
335
|
+
def ==(other)
|
|
336
|
+
equal?(other) || compare_ids(other)
|
|
342
337
|
end
|
|
343
|
-
private :compare_ids
|
|
344
338
|
|
|
345
339
|
# Returns a Integer hash value based on the +id+ attribute in order to use
|
|
346
340
|
# functions like & (intersection), group_by, etc.
|
|
@@ -360,7 +354,22 @@ class Money
|
|
|
360
354
|
# @example
|
|
361
355
|
# Money::Currency.new(:usd) #=> #<Currency id: usd ...>
|
|
362
356
|
def inspect
|
|
363
|
-
"#<#{self.class.name}
|
|
357
|
+
"#<#{self.class.name} " \
|
|
358
|
+
"id: #{id}, " \
|
|
359
|
+
"priority: #{priority}, " \
|
|
360
|
+
"symbol_first: #{symbol_first}, " \
|
|
361
|
+
"thousands_separator: #{thousands_separator}, " \
|
|
362
|
+
"html_entity: #{html_entity}, " \
|
|
363
|
+
"decimal_mark: #{decimal_mark}, " \
|
|
364
|
+
"name: #{name}, " \
|
|
365
|
+
"symbol: #{symbol}, " \
|
|
366
|
+
"subunit_to_unit: #{subunit_to_unit}, " \
|
|
367
|
+
"exponent: #{exponent}, " \
|
|
368
|
+
"iso_code: #{iso_code}, " \
|
|
369
|
+
"iso_numeric: #{iso_numeric}, " \
|
|
370
|
+
"subunit: #{subunit}, " \
|
|
371
|
+
"smallest_denomination: #{smallest_denomination}, " \
|
|
372
|
+
"format: #{format}>"
|
|
364
373
|
end
|
|
365
374
|
|
|
366
375
|
# Returns a string representation corresponding to the upcase +id+
|
|
@@ -428,7 +437,7 @@ class Money
|
|
|
428
437
|
# Money::Currency.new(:usd).iso?
|
|
429
438
|
#
|
|
430
439
|
def iso?
|
|
431
|
-
iso_numeric && iso_numeric !=
|
|
440
|
+
iso_numeric && iso_numeric != ""
|
|
432
441
|
end
|
|
433
442
|
|
|
434
443
|
# Returns true if a subunit is cents-based.
|
|
@@ -455,6 +464,18 @@ class Money
|
|
|
455
464
|
|
|
456
465
|
private
|
|
457
466
|
|
|
467
|
+
# rubocop:disable Naming/PredicateMethod
|
|
468
|
+
def compare_ids(other_currency)
|
|
469
|
+
other_currency_id =
|
|
470
|
+
if other_currency.is_a?(Currency)
|
|
471
|
+
other_currency.id.to_s.downcase
|
|
472
|
+
else
|
|
473
|
+
other_currency.to_s.downcase
|
|
474
|
+
end
|
|
475
|
+
id.to_s.downcase == other_currency_id
|
|
476
|
+
end
|
|
477
|
+
# rubocop:enable Naming/PredicateMethod
|
|
478
|
+
|
|
458
479
|
def initialize_data!
|
|
459
480
|
data = self.class.table[@id]
|
|
460
481
|
@alternate_symbols = data[:alternate_symbols]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "money/locale_backend/base"
|
|
4
4
|
|
|
5
5
|
class Money
|
|
6
6
|
module LocaleBackend
|
|
@@ -13,15 +13,17 @@ class Money
|
|
|
13
13
|
}.freeze
|
|
14
14
|
|
|
15
15
|
def initialize
|
|
16
|
-
raise NotSupported,
|
|
16
|
+
raise NotSupported, "I18n not found" unless defined?(::I18n)
|
|
17
|
+
|
|
18
|
+
super
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
def lookup(key, _)
|
|
20
22
|
i18n_key = KEY_MAP[key]
|
|
21
23
|
|
|
22
|
-
::I18n.t i18n_key, scope:
|
|
24
|
+
::I18n.t i18n_key, scope: "number.currency.format", raise: true
|
|
23
25
|
rescue ::I18n::MissingTranslationData
|
|
24
|
-
::I18n.t i18n_key, scope:
|
|
26
|
+
::I18n.t i18n_key, scope: "number.format", default: nil
|
|
25
27
|
end
|
|
26
28
|
end
|
|
27
29
|
end
|
|
@@ -22,15 +22,16 @@ class Money
|
|
|
22
22
|
# @return [Array<Numeric>] An array containing the allocated amounts.
|
|
23
23
|
# @raise [ArgumentError] If parts is empty or not provided.
|
|
24
24
|
def self.generate(amount, parts, decimal_cutoff = true)
|
|
25
|
-
parts =
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
parts =
|
|
26
|
+
if parts.is_a?(Numeric)
|
|
27
|
+
Array.new(parts, 1)
|
|
28
|
+
elsif parts.all?(&:zero?)
|
|
29
|
+
Array.new(parts.count, 1)
|
|
30
|
+
else
|
|
31
|
+
parts.dup
|
|
32
|
+
end
|
|
32
33
|
|
|
33
|
-
raise ArgumentError,
|
|
34
|
+
raise ArgumentError, "need at least one part" if parts.empty?
|
|
34
35
|
|
|
35
36
|
if [amount, *parts].any? { |i| i.is_a?(BigDecimal) || i.is_a?(Float) || i.is_a?(Rational) }
|
|
36
37
|
amount = convert_to_big_decimal(amount)
|
|
@@ -44,7 +45,7 @@ class Money
|
|
|
44
45
|
|
|
45
46
|
parts_sum = parts.sum
|
|
46
47
|
|
|
47
|
-
until parts.empty?
|
|
48
|
+
until parts.empty?
|
|
48
49
|
part = parts.pop
|
|
49
50
|
|
|
50
51
|
current_split = 0
|