money 6.13.3 → 6.13.8
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 +5 -5
- data/CHANGELOG.md +28 -3
- data/README.md +22 -3
- data/config/currency_backwards_compatible.json +16 -0
- data/config/currency_iso.json +11 -11
- data/lib/money/bank/variable_exchange.rb +14 -6
- data/lib/money/currency.rb +1 -1
- data/lib/money/money.rb +78 -39
- data/lib/money/money/allocation.rb +3 -3
- data/lib/money/money/arithmetic.rb +3 -3
- data/lib/money/money/formatting_rules.rb +1 -0
- data/lib/money/rates_store/memory.rb +24 -23
- data/lib/money/version.rb +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 1773172616f278d2f107e19153498c029c5f1b63f4ae68a7468ef66fbbef8991
|
|
4
|
+
data.tar.gz: 035cd8170e536decc4748cd8a6c2ef1b7a7d5e985e6a2ecba0c989f8cf89096c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5636c6323a8538ccc669a2ecfd07a3108adde4f6315e43d0d2b0bb818fc31d1c230ff0ca9715a2c1ca67edcdfa7cb71c9c4d8405410f0764cc82aaad5d3af4e1
|
|
7
|
+
data.tar.gz: 4b2532f674ca8b665b43c745f5b8cc2beb3d7d5fda0584273bc53d8a42e8a551037758374b6864cfe4b227d61d043282394ed51b62e27f82b8f374ddb27dbe5b
|
data/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 6.13.8
|
|
4
|
+
- Update symbol for XOF
|
|
5
|
+
- Update UYU currency symbol
|
|
6
|
+
- Allow double conversion using same bank
|
|
7
|
+
- Warn when using unsafe serializer for rate import
|
|
8
|
+
- Move Icelandic symbol after the amount
|
|
9
|
+
|
|
10
|
+
## 6.13.7
|
|
11
|
+
- Improve deprecation warnings for the upcoming major release
|
|
12
|
+
|
|
13
|
+
## 6.13.6
|
|
14
|
+
- Fix a regression introduced in 6.13.5 that broken RatesStore::Memory subclasses
|
|
15
|
+
|
|
16
|
+
## 6.13.5
|
|
17
|
+
- Raise warning on using Money.default_currency
|
|
18
|
+
- Raise warning on using default Money.rounding_mode
|
|
19
|
+
- Add Second Ouguiya MRU 929 to currency iso file
|
|
20
|
+
- Add symbol for UZS
|
|
21
|
+
- Use monitor for recursive mutual exclusion in RatesStore::Memory
|
|
22
|
+
- Allow passing store as a string to Money::Bank::VariableExchange (to support Rails 6)
|
|
23
|
+
|
|
24
|
+
## 6.13.4
|
|
25
|
+
- Update currency config for Zambian Kwacha (ZMW)
|
|
26
|
+
- Do not modify options passed to FormattingRules
|
|
27
|
+
|
|
3
28
|
## 6.13.3
|
|
4
29
|
- Remove specs from the packaged gem
|
|
5
30
|
- Use Currency::Loader directly without extending
|
|
6
|
-
- Add Money.with_rounding_mode as a replacement for calling Money.
|
|
31
|
+
- Add Money.with_rounding_mode as a replacement for calling Money.rounding_mode with a block
|
|
7
32
|
- Fix currency search for two digit ISO numbers
|
|
8
33
|
- Add description to TypeError raised by +/- operations
|
|
9
34
|
|
|
@@ -42,7 +67,7 @@
|
|
|
42
67
|
- Wrap all amount parts when `:html_wrap` option is used
|
|
43
68
|
- Deprecate `#currency_as_string` and `#currency_as_string=` (in favour of `#with_currency`)
|
|
44
69
|
- Add `#with_currency` for swapping the currency
|
|
45
|
-
- Rewrite allocate/split (fixing some penny
|
|
70
|
+
- Rewrite allocate/split (fixing some penny losing issues)
|
|
46
71
|
|
|
47
72
|
## 6.11.3
|
|
48
73
|
- Fix regression: if enabled use i18n locales in Money#to_s
|
|
@@ -61,7 +86,7 @@
|
|
|
61
86
|
- Added new symbol for bitcoin denomination
|
|
62
87
|
- Specify custom rounding precision when using `infinite_precision`
|
|
63
88
|
- Allow splits with sums greater than 1
|
|
64
|
-
- Prevent arithmetic methods from
|
|
89
|
+
- Prevent arithmetic methods from losing reference to the bank
|
|
65
90
|
- Fix coerced zero numeric subtraction
|
|
66
91
|
- Fix south asian formatting to support whole numbers
|
|
67
92
|
- Refactor formatting logic
|
data/README.md
CHANGED
|
@@ -21,7 +21,7 @@ A Ruby Library for dealing with money and currency conversion.
|
|
|
21
21
|
|
|
22
22
|
### Features
|
|
23
23
|
|
|
24
|
-
- Provides a `Money` class which encapsulates all information about
|
|
24
|
+
- Provides a `Money` class which encapsulates all information about a certain
|
|
25
25
|
amount of money, such as its value and its currency.
|
|
26
26
|
- Provides a `Money::Currency` class which encapsulates all information about
|
|
27
27
|
a monetary unit.
|
|
@@ -253,7 +253,7 @@ The default bank is initialized with an in-memory store for exchange rates.
|
|
|
253
253
|
Money.default_bank = Money::Bank::VariableExchange.new(Money::RatesStore::Memory.new)
|
|
254
254
|
```
|
|
255
255
|
|
|
256
|
-
You can pass
|
|
256
|
+
You can pass your own store implementation, i.e. for storing and retrieving rates off a database, file, cache, etc.
|
|
257
257
|
|
|
258
258
|
```ruby
|
|
259
259
|
Money.default_bank = Money::Bank::VariableExchange.new(MyCustomStore.new)
|
|
@@ -270,7 +270,7 @@ Stores must implement the following interface:
|
|
|
270
270
|
# @return [Numeric] rate.
|
|
271
271
|
def add_rate(iso_from, iso_to, rate); end
|
|
272
272
|
|
|
273
|
-
# Get rate. Must be idempotent.
|
|
273
|
+
# Get rate. Must be idempotent. i.e. adding the same rate must not produce duplicates.
|
|
274
274
|
# @param [String] iso_from Currency ISO code. ex. 'USD'
|
|
275
275
|
# @param [String] iso_to Currency ISO code. ex. 'CAD'
|
|
276
276
|
#
|
|
@@ -334,6 +334,8 @@ end
|
|
|
334
334
|
Now you can use it with the default bank.
|
|
335
335
|
|
|
336
336
|
```ruby
|
|
337
|
+
# For Rails 6 pass model name as a string to make it compatible with zeitwerk
|
|
338
|
+
# Money.default_bank = Money::Bank::VariableExchange.new("ExchangeRate")
|
|
337
339
|
Money.default_bank = Money::Bank::VariableExchange.new(ExchangeRate)
|
|
338
340
|
|
|
339
341
|
# Add to the underlying store
|
|
@@ -421,6 +423,13 @@ Money.new(2.34567).round.format #=> "$0.02"
|
|
|
421
423
|
Money.new(2.34567).round(BigDecimal::ROUND_HALF_UP, 2).format #=> "$0.0235"
|
|
422
424
|
```
|
|
423
425
|
|
|
426
|
+
You can set the default rounding mode by passing one of the `BigDecimal` mode enumerables like so:
|
|
427
|
+
```ruby
|
|
428
|
+
Money.rounding_mode = BigDecimal::ROUND_HALF_EVEN
|
|
429
|
+
```
|
|
430
|
+
See [BigDecimal::ROUND_MODE](https://ruby-doc.org/stdlib-2.5.1/libdoc/bigdecimal/rdoc/BigDecimal.html#ROUND_MODE) for more information
|
|
431
|
+
|
|
432
|
+
|
|
424
433
|
## Ruby on Rails
|
|
425
434
|
|
|
426
435
|
To integrate money in a Rails application use [money-rails](https://github.com/RubyMoney/money-rails).
|
|
@@ -484,6 +493,16 @@ Money.new(10_000_00, 'USD').format # => $10.000,00
|
|
|
484
493
|
Money.new(10_000_00, 'EUR').format # => €10.000,00
|
|
485
494
|
```
|
|
486
495
|
|
|
496
|
+
If you need to localize the position of the currency symbol, you
|
|
497
|
+
have to pass it manually. *Note: this will become the default formatting
|
|
498
|
+
behavior in the next version.*
|
|
499
|
+
|
|
500
|
+
```ruby
|
|
501
|
+
I18n.locale = :fr
|
|
502
|
+
format = I18n.t :format, scope: 'number.currency.format'
|
|
503
|
+
Money.new(10_00, 'EUR').format(format: format) # => 10,00 €
|
|
504
|
+
```
|
|
505
|
+
|
|
487
506
|
For the legacy behaviour of "per currency" localization (formatting depends only on currency):
|
|
488
507
|
|
|
489
508
|
```ruby
|
|
@@ -60,6 +60,22 @@
|
|
|
60
60
|
"iso_numeric": "428",
|
|
61
61
|
"smallest_denomination": 1
|
|
62
62
|
},
|
|
63
|
+
"mro": {
|
|
64
|
+
"priority": 100,
|
|
65
|
+
"iso_code": "MRO",
|
|
66
|
+
"name": "Mauritanian Ouguiya",
|
|
67
|
+
"symbol": "UM",
|
|
68
|
+
"disambiguate_symbol": "A-UM",
|
|
69
|
+
"alternate_symbols": [],
|
|
70
|
+
"subunit": "Khoums",
|
|
71
|
+
"subunit_to_unit": 5,
|
|
72
|
+
"symbol_first": false,
|
|
73
|
+
"html_entity": "",
|
|
74
|
+
"decimal_mark": ".",
|
|
75
|
+
"thousands_separator": ",",
|
|
76
|
+
"iso_numeric": "478",
|
|
77
|
+
"smallest_denomination": 1
|
|
78
|
+
},
|
|
63
79
|
"mtl": {
|
|
64
80
|
"priority": 100,
|
|
65
81
|
"iso_code": "MTL",
|
data/config/currency_iso.json
CHANGED
|
@@ -1019,11 +1019,11 @@
|
|
|
1019
1019
|
"priority": 100,
|
|
1020
1020
|
"iso_code": "ISK",
|
|
1021
1021
|
"name": "Icelandic Króna",
|
|
1022
|
-
"symbol": "kr",
|
|
1022
|
+
"symbol": "kr.",
|
|
1023
1023
|
"alternate_symbols": ["Íkr"],
|
|
1024
1024
|
"subunit": null,
|
|
1025
1025
|
"subunit_to_unit": 1,
|
|
1026
|
-
"symbol_first":
|
|
1026
|
+
"symbol_first": false,
|
|
1027
1027
|
"html_entity": "",
|
|
1028
1028
|
"decimal_mark": ",",
|
|
1029
1029
|
"thousands_separator": ".",
|
|
@@ -1412,9 +1412,9 @@
|
|
|
1412
1412
|
"iso_numeric": "446",
|
|
1413
1413
|
"smallest_denomination": 10
|
|
1414
1414
|
},
|
|
1415
|
-
"
|
|
1415
|
+
"mru": {
|
|
1416
1416
|
"priority": 100,
|
|
1417
|
-
"iso_code": "
|
|
1417
|
+
"iso_code": "MRU",
|
|
1418
1418
|
"name": "Mauritanian Ouguiya",
|
|
1419
1419
|
"symbol": "UM",
|
|
1420
1420
|
"alternate_symbols": [],
|
|
@@ -1424,7 +1424,7 @@
|
|
|
1424
1424
|
"html_entity": "",
|
|
1425
1425
|
"decimal_mark": ".",
|
|
1426
1426
|
"thousands_separator": ",",
|
|
1427
|
-
"iso_numeric": "
|
|
1427
|
+
"iso_numeric": "929",
|
|
1428
1428
|
"smallest_denomination": 1
|
|
1429
1429
|
},
|
|
1430
1430
|
"mur": {
|
|
@@ -2245,12 +2245,12 @@
|
|
|
2245
2245
|
"priority": 100,
|
|
2246
2246
|
"iso_code": "UYU",
|
|
2247
2247
|
"name": "Uruguayan Peso",
|
|
2248
|
-
"symbol": "$",
|
|
2248
|
+
"symbol": "$U",
|
|
2249
2249
|
"alternate_symbols": ["$U"],
|
|
2250
2250
|
"subunit": "Centésimo",
|
|
2251
2251
|
"subunit_to_unit": 100,
|
|
2252
2252
|
"symbol_first": true,
|
|
2253
|
-
"html_entity": "
|
|
2253
|
+
"html_entity": "$U",
|
|
2254
2254
|
"decimal_mark": ",",
|
|
2255
2255
|
"thousands_separator": ".",
|
|
2256
2256
|
"iso_numeric": "858",
|
|
@@ -2260,7 +2260,7 @@
|
|
|
2260
2260
|
"priority": 100,
|
|
2261
2261
|
"iso_code": "UZS",
|
|
2262
2262
|
"name": "Uzbekistan Som",
|
|
2263
|
-
"symbol": "",
|
|
2263
|
+
"symbol": "so'm",
|
|
2264
2264
|
"alternate_symbols": ["so‘m", "сўм", "сум", "s", "с"],
|
|
2265
2265
|
"subunit": "Tiyin",
|
|
2266
2266
|
"subunit_to_unit": 100,
|
|
@@ -2336,7 +2336,7 @@
|
|
|
2336
2336
|
"priority": 100,
|
|
2337
2337
|
"iso_code": "XAF",
|
|
2338
2338
|
"name": "Central African Cfa Franc",
|
|
2339
|
-
"symbol": "
|
|
2339
|
+
"symbol": "CFA",
|
|
2340
2340
|
"disambiguate_symbol": "FCFA",
|
|
2341
2341
|
"alternate_symbols": ["FCFA"],
|
|
2342
2342
|
"subunit": "Centime",
|
|
@@ -2594,12 +2594,12 @@
|
|
|
2594
2594
|
"priority": 100,
|
|
2595
2595
|
"iso_code": "ZMW",
|
|
2596
2596
|
"name": "Zambian Kwacha",
|
|
2597
|
-
"symbol": "
|
|
2597
|
+
"symbol": "K",
|
|
2598
2598
|
"disambiguate_symbol": "ZMW",
|
|
2599
2599
|
"alternate_symbols": [],
|
|
2600
2600
|
"subunit": "Ngwee",
|
|
2601
2601
|
"subunit_to_unit": 100,
|
|
2602
|
-
"symbol_first":
|
|
2602
|
+
"symbol_first": true,
|
|
2603
2603
|
"html_entity": "",
|
|
2604
2604
|
"decimal_mark": ".",
|
|
2605
2605
|
"thousands_separator": ",",
|
|
@@ -42,7 +42,7 @@ class Money
|
|
|
42
42
|
# bank.get_rate 'USD', 'CAD'
|
|
43
43
|
class VariableExchange < Base
|
|
44
44
|
|
|
45
|
-
attr_reader :mutex
|
|
45
|
+
attr_reader :mutex
|
|
46
46
|
|
|
47
47
|
# Available formats for importing/exporting rates.
|
|
48
48
|
RATE_FORMATS = [:json, :ruby, :yaml].freeze
|
|
@@ -61,6 +61,10 @@ class Money
|
|
|
61
61
|
super(&block)
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
+
def store
|
|
65
|
+
@store.is_a?(String) ? Object.const_get(@store) : @store
|
|
66
|
+
end
|
|
67
|
+
|
|
64
68
|
def marshal_dump
|
|
65
69
|
[store.marshal_dump, @rounding_method]
|
|
66
70
|
end
|
|
@@ -110,7 +114,7 @@ class Money
|
|
|
110
114
|
if rate = get_rate(from.currency, to_currency)
|
|
111
115
|
fractional = calculate_fractional(from, to_currency)
|
|
112
116
|
from.class.new(
|
|
113
|
-
exchange(fractional, rate, &block), to_currency
|
|
117
|
+
exchange(fractional, rate, &block), to_currency, self
|
|
114
118
|
)
|
|
115
119
|
else
|
|
116
120
|
raise UnknownRate, "No conversion rate known for '#{from.currency.iso_code}' -> '#{to_currency}'"
|
|
@@ -213,8 +217,7 @@ class Money
|
|
|
213
217
|
# s = bank.export_rates(:json)
|
|
214
218
|
# s #=> "{\"USD_TO_CAD\":1.24515,\"CAD_TO_USD\":0.803115}"
|
|
215
219
|
def export_rates(format, file = nil, opts = {})
|
|
216
|
-
raise Money::Bank::UnknownRateFormat unless
|
|
217
|
-
RATE_FORMATS.include? format
|
|
220
|
+
raise Money::Bank::UnknownRateFormat unless RATE_FORMATS.include?(format)
|
|
218
221
|
|
|
219
222
|
store.transaction do
|
|
220
223
|
s = FORMAT_SERIALIZERS[format].dump(rates)
|
|
@@ -254,8 +257,13 @@ class Money
|
|
|
254
257
|
# bank.get_rate("USD", "CAD") #=> 1.24515
|
|
255
258
|
# bank.get_rate("CAD", "USD") #=> 0.803115
|
|
256
259
|
def import_rates(format, s, opts = {})
|
|
257
|
-
raise Money::Bank::UnknownRateFormat unless
|
|
258
|
-
|
|
260
|
+
raise Money::Bank::UnknownRateFormat unless RATE_FORMATS.include?(format)
|
|
261
|
+
|
|
262
|
+
if format == :ruby
|
|
263
|
+
warn '[WARNING] Using :ruby format when importing rates is potentially unsafe and ' \
|
|
264
|
+
'might lead to remote code execution via Marshal.load deserializer. Consider using ' \
|
|
265
|
+
'safe alternatives such as :json and :yaml.'
|
|
266
|
+
end
|
|
259
267
|
|
|
260
268
|
store.transaction do
|
|
261
269
|
data = FORMAT_SERIALIZERS[format].load(s)
|
data/lib/money/currency.rb
CHANGED
|
@@ -414,7 +414,7 @@ class Money
|
|
|
414
414
|
|
|
415
415
|
# Returns the relation between subunit and unit as a base 10 exponent.
|
|
416
416
|
#
|
|
417
|
-
# Note that MGA and
|
|
417
|
+
# Note that MGA and MRU are exceptions and are rounded to 1
|
|
418
418
|
# @see https://en.wikipedia.org/wiki/ISO_4217#Active_codes
|
|
419
419
|
#
|
|
420
420
|
# @return [Integer]
|
data/lib/money/money.rb
CHANGED
|
@@ -91,51 +91,63 @@ class Money
|
|
|
91
91
|
class << self
|
|
92
92
|
|
|
93
93
|
# @!attribute [rw] default_bank
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
#
|
|
97
|
-
#
|
|
98
|
-
#
|
|
94
|
+
# Used to set a default bank for currency exchange.
|
|
95
|
+
#
|
|
96
|
+
# Each Money object is associated with a bank
|
|
97
|
+
# object, which is responsible for currency exchange. This property
|
|
98
|
+
# allows you to specify the default bank object. The default value for
|
|
99
|
+
# this property is an instance of +Bank::VariableExchange.+ It allows
|
|
100
|
+
# one to specify custom exchange rates.
|
|
101
|
+
#
|
|
102
|
+
# @return [Money::Bank::Base]
|
|
99
103
|
#
|
|
100
104
|
# @!attribute default_formatting_rules
|
|
101
|
-
#
|
|
102
|
-
#
|
|
103
|
-
#
|
|
104
|
-
#
|
|
105
|
+
# Used to define a default hash of rules for every time
|
|
106
|
+
# +Money#format+ is called. Rules provided on method call will be
|
|
107
|
+
# merged with the default ones. To overwrite a rule, just provide the
|
|
108
|
+
# intended value while calling +format+.
|
|
105
109
|
#
|
|
106
|
-
# @see
|
|
110
|
+
# @see Money::Formatter#initialize Money::Formatter for more details
|
|
107
111
|
#
|
|
108
112
|
# @example
|
|
109
113
|
# Money.default_formatting_rules = { display_free: true }
|
|
110
114
|
# Money.new(0, "USD").format # => "free"
|
|
111
115
|
# Money.new(0, "USD").format(display_free: false) # => "$0.00"
|
|
112
116
|
#
|
|
117
|
+
# @return [Hash]
|
|
118
|
+
#
|
|
113
119
|
# @!attribute [rw] use_i18n
|
|
114
|
-
#
|
|
115
|
-
#
|
|
120
|
+
# Used to disable i18n even if it's used by other components of your app.
|
|
121
|
+
#
|
|
122
|
+
# @return [Boolean]
|
|
116
123
|
#
|
|
117
124
|
# @!attribute [rw] infinite_precision
|
|
118
|
-
#
|
|
125
|
+
# Used to enable infinite precision cents
|
|
126
|
+
#
|
|
127
|
+
# @return [Boolean]
|
|
119
128
|
#
|
|
120
129
|
# @!attribute [rw] conversion_precision
|
|
121
|
-
#
|
|
122
|
-
# to BigDecimal
|
|
123
|
-
attr_accessor :default_bank, :default_formatting_rules,
|
|
124
|
-
:use_i18n, :infinite_precision, :conversion_precision,
|
|
125
|
-
:locale_backend
|
|
126
|
-
|
|
127
|
-
# @attr_writer rounding_mode Use this to specify the rounding mode
|
|
130
|
+
# Used to specify precision for converting Rational to BigDecimal
|
|
128
131
|
#
|
|
129
|
-
#
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
# default value is Currency.new("USD"). The value must be a valid
|
|
133
|
-
# +Money::Currency+ instance.
|
|
134
|
-
attr_writer :rounding_mode, :default_currency
|
|
132
|
+
# @return [Integer]
|
|
133
|
+
attr_accessor :default_bank, :default_formatting_rules,
|
|
134
|
+
:infinite_precision, :conversion_precision
|
|
135
135
|
|
|
136
|
+
attr_reader :use_i18n, :locale_backend
|
|
136
137
|
end
|
|
137
138
|
|
|
139
|
+
# @!attribute default_currency
|
|
140
|
+
# @return [Money::Currency] The default currency, which is used when
|
|
141
|
+
# +Money.new+ is called without an explicit currency argument. The
|
|
142
|
+
# default value is Currency.new("USD"). The value must be a valid
|
|
143
|
+
# +Money::Currency+ instance.
|
|
138
144
|
def self.default_currency
|
|
145
|
+
if @using_deprecated_default_currency
|
|
146
|
+
warn '[WARNING] The default currency will change from `USD` to `nil` in the next major release. Make ' \
|
|
147
|
+
'sure to set it explicitly using `Money.default_currency=` to avoid potential issues'
|
|
148
|
+
@using_deprecated_default_currency = false
|
|
149
|
+
end
|
|
150
|
+
|
|
139
151
|
if @default_currency.respond_to?(:call)
|
|
140
152
|
Money::Currency.new(@default_currency.call)
|
|
141
153
|
else
|
|
@@ -143,10 +155,21 @@ class Money
|
|
|
143
155
|
end
|
|
144
156
|
end
|
|
145
157
|
|
|
158
|
+
def self.default_currency=(currency)
|
|
159
|
+
@using_deprecated_default_currency = false
|
|
160
|
+
@default_currency = currency
|
|
161
|
+
end
|
|
162
|
+
|
|
146
163
|
def self.locale_backend=(value)
|
|
147
164
|
@locale_backend = value ? LocaleBackend.find(value) : nil
|
|
148
165
|
end
|
|
149
166
|
|
|
167
|
+
# @attr_writer rounding_mode Use this to specify the rounding mode
|
|
168
|
+
def self.rounding_mode=(new_rounding_mode)
|
|
169
|
+
@using_deprecated_default_rounding_mode = false
|
|
170
|
+
@rounding_mode = new_rounding_mode
|
|
171
|
+
end
|
|
172
|
+
|
|
150
173
|
def self.use_i18n=(value)
|
|
151
174
|
if value
|
|
152
175
|
warn '[DEPRECATION] `use_i18n` is deprecated - use `Money.locale_backend = :i18n` instead for locale based formatting'
|
|
@@ -163,6 +186,7 @@ class Money
|
|
|
163
186
|
|
|
164
187
|
# Set the default currency for creating new +Money+ object.
|
|
165
188
|
self.default_currency = Currency.new("USD")
|
|
189
|
+
@using_deprecated_default_currency = true
|
|
166
190
|
|
|
167
191
|
# Default to using i18n
|
|
168
192
|
@use_i18n = true
|
|
@@ -175,6 +199,7 @@ class Money
|
|
|
175
199
|
|
|
176
200
|
# Default to bankers rounding
|
|
177
201
|
self.rounding_mode = BigDecimal::ROUND_HALF_EVEN
|
|
202
|
+
@using_deprecated_default_rounding_mode = true
|
|
178
203
|
|
|
179
204
|
# Default the conversion of Rationals precision to 16
|
|
180
205
|
self.conversion_precision = 16
|
|
@@ -192,18 +217,30 @@ class Money
|
|
|
192
217
|
#
|
|
193
218
|
# @return [BigDecimal::ROUND_MODE] rounding mode
|
|
194
219
|
def self.rounding_mode(mode = nil)
|
|
195
|
-
|
|
220
|
+
if mode
|
|
221
|
+
warn "[DEPRECATION] calling `rounding_mode` with a block is deprecated. Please use `.with_rounding_mode` instead."
|
|
222
|
+
return with_rounding_mode(mode) { yield }
|
|
223
|
+
end
|
|
196
224
|
|
|
197
|
-
|
|
198
|
-
|
|
225
|
+
return Thread.current[:money_rounding_mode] if Thread.current[:money_rounding_mode]
|
|
226
|
+
|
|
227
|
+
if @using_deprecated_default_rounding_mode
|
|
228
|
+
warn '[WARNING] The default rounding mode will change from `ROUND_HALF_EVEN` to `ROUND_HALF_UP` in the ' \
|
|
229
|
+
'next major release. Set it explicitly using `Money.rounding_mode=` to avoid potential problems.'
|
|
230
|
+
@using_deprecated_default_rounding_mode = false
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
@rounding_mode
|
|
199
234
|
end
|
|
200
235
|
|
|
201
|
-
#
|
|
202
|
-
# results of the block instead.
|
|
236
|
+
# Temporarily changes the rounding mode in a given block.
|
|
203
237
|
#
|
|
204
238
|
# @param [BigDecimal::ROUND_MODE] mode
|
|
205
239
|
#
|
|
206
|
-
# @
|
|
240
|
+
# @yield The block within which rounding mode will be changed. Its return
|
|
241
|
+
# value will also be the return value of the whole method.
|
|
242
|
+
#
|
|
243
|
+
# @return [Object] block results
|
|
207
244
|
#
|
|
208
245
|
# @example
|
|
209
246
|
# fee = Money.with_rounding_mode(BigDecimal::ROUND_HALF_UP) do
|
|
@@ -509,13 +546,15 @@ class Money
|
|
|
509
546
|
exchange_to("EUR")
|
|
510
547
|
end
|
|
511
548
|
|
|
512
|
-
# Splits a given amount in parts without
|
|
513
|
-
# distributed round-robin amongst the parties. This means that
|
|
514
|
-
# receive more pennies than ones
|
|
549
|
+
# Splits a given amount in parts without losing pennies. The left-over pennies will be
|
|
550
|
+
# distributed round-robin amongst the parties. This means that parts listed first will likely
|
|
551
|
+
# receive more pennies than ones listed later.
|
|
552
|
+
#
|
|
553
|
+
# Pass [2, 1, 1] as input to give twice as much to part1 as part2 or
|
|
554
|
+
# part3 which results in 50% of the cash to party1, 25% to part2, and 25% to part3. Passing a
|
|
555
|
+
# number instead of an array will split the amount evenly (without losing pennies when rounding).
|
|
515
556
|
#
|
|
516
|
-
# @param [Array<Numeric>, Numeric]
|
|
517
|
-
# party3 which results in 50% of the cash to party1, 25% to party2, and 25% to party3. Passing a
|
|
518
|
-
# number instead of an array will split the amount evenly (without loosing pennies when rounding).
|
|
557
|
+
# @param [Array<Numeric>, Numeric] parts how amount should be distributed to parts
|
|
519
558
|
#
|
|
520
559
|
# @return [Array<Money>]
|
|
521
560
|
#
|
|
@@ -553,7 +592,7 @@ class Money
|
|
|
553
592
|
|
|
554
593
|
# Creates a formatted price string according to several rules.
|
|
555
594
|
#
|
|
556
|
-
# @param [Hash] See Money::Formatter for the list of formatting options
|
|
595
|
+
# @param [Hash] rules See {Money::Formatter Money::Formatter} for the list of formatting options
|
|
557
596
|
#
|
|
558
597
|
# @return [String]
|
|
559
598
|
#
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
class Money
|
|
4
4
|
class Allocation
|
|
5
|
-
# Splits a given amount in parts without
|
|
6
|
-
# The left-over pennies will be distributed round-robin amongst the
|
|
7
|
-
#
|
|
5
|
+
# Splits a given amount in parts without losing pennies.
|
|
6
|
+
# The left-over pennies will be distributed round-robin amongst the parts. This means that
|
|
7
|
+
# parts listed first will likely receive more pennies than the ones listed later.
|
|
8
8
|
#
|
|
9
9
|
# The results should always add up to the original amount.
|
|
10
10
|
#
|
|
@@ -46,7 +46,7 @@ class Money
|
|
|
46
46
|
# Compares two Money objects. If money objects have a different currency it
|
|
47
47
|
# will attempt to convert the currency.
|
|
48
48
|
#
|
|
49
|
-
# @param [Money]
|
|
49
|
+
# @param [Money] other Value to compare with.
|
|
50
50
|
#
|
|
51
51
|
# @return [Integer]
|
|
52
52
|
#
|
|
@@ -103,7 +103,7 @@ class Money
|
|
|
103
103
|
# values. If +other_money+ has a different currency then its monetary value
|
|
104
104
|
# is automatically exchanged to this object's currency using +exchange_to+.
|
|
105
105
|
#
|
|
106
|
-
# @param [Money]
|
|
106
|
+
# @param [Money] other Other +Money+ object to add.
|
|
107
107
|
#
|
|
108
108
|
# @return [Money]
|
|
109
109
|
#
|
|
@@ -116,7 +116,7 @@ class Money
|
|
|
116
116
|
# its monetary value is automatically exchanged to this object's currency
|
|
117
117
|
# using +exchange_to+.
|
|
118
118
|
#
|
|
119
|
-
# @param [Money]
|
|
119
|
+
# @param [Money] other Other +Money+ object to subtract.
|
|
120
120
|
#
|
|
121
121
|
# @return [Money]
|
|
122
122
|
#
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'monitor'
|
|
2
|
+
|
|
1
3
|
class Money
|
|
2
4
|
module RatesStore
|
|
3
5
|
|
|
@@ -17,11 +19,11 @@ class Money
|
|
|
17
19
|
#
|
|
18
20
|
# @param [Hash] opts Optional store options.
|
|
19
21
|
# @option opts [Boolean] :without_mutex disables the usage of a mutex
|
|
20
|
-
# @param [Hash]
|
|
21
|
-
def initialize(opts = {},
|
|
22
|
-
@
|
|
23
|
-
@
|
|
24
|
-
@
|
|
22
|
+
# @param [Hash] rates Optional initial exchange rate data.
|
|
23
|
+
def initialize(opts = {}, rates = {})
|
|
24
|
+
@rates = rates
|
|
25
|
+
@options = opts
|
|
26
|
+
@guard = Monitor.new
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
# Registers a conversion rate and returns it. Uses +Mutex+ to synchronize data access.
|
|
@@ -37,7 +39,9 @@ class Money
|
|
|
37
39
|
# store.add_rate("USD", "CAD", 1.24515)
|
|
38
40
|
# store.add_rate("CAD", "USD", 0.803115)
|
|
39
41
|
def add_rate(currency_iso_from, currency_iso_to, rate)
|
|
40
|
-
|
|
42
|
+
guard.synchronize do
|
|
43
|
+
rates[rate_key_for(currency_iso_from, currency_iso_to)] = rate
|
|
44
|
+
end
|
|
41
45
|
end
|
|
42
46
|
|
|
43
47
|
# Retrieve the rate for the given currencies. Uses +Mutex+ to synchronize data access.
|
|
@@ -54,24 +58,21 @@ class Money
|
|
|
54
58
|
#
|
|
55
59
|
# store.get_rate("USD", "CAD") #=> 1.24515
|
|
56
60
|
def get_rate(currency_iso_from, currency_iso_to)
|
|
57
|
-
|
|
61
|
+
guard.synchronize do
|
|
62
|
+
rates[rate_key_for(currency_iso_from, currency_iso_to)]
|
|
63
|
+
end
|
|
58
64
|
end
|
|
59
65
|
|
|
60
66
|
def marshal_dump
|
|
61
|
-
|
|
67
|
+
guard.synchronize do
|
|
68
|
+
return [self.class, options, rates.dup]
|
|
69
|
+
end
|
|
62
70
|
end
|
|
63
71
|
|
|
64
72
|
# Wraps block execution in a thread-safe transaction
|
|
65
73
|
def transaction(&block)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
else
|
|
69
|
-
@mutex.synchronize do
|
|
70
|
-
@in_transaction = true
|
|
71
|
-
result = block.call
|
|
72
|
-
@in_transaction = false
|
|
73
|
-
result
|
|
74
|
-
end
|
|
74
|
+
guard.synchronize do
|
|
75
|
+
yield
|
|
75
76
|
end
|
|
76
77
|
end
|
|
77
78
|
|
|
@@ -88,19 +89,19 @@ class Money
|
|
|
88
89
|
# puts [iso_from, iso_to, rate].join
|
|
89
90
|
# end
|
|
90
91
|
def each_rate(&block)
|
|
91
|
-
|
|
92
|
-
|
|
92
|
+
return to_enum(:each_rate) unless block_given?
|
|
93
|
+
|
|
94
|
+
guard.synchronize do
|
|
95
|
+
rates.each do |key, rate|
|
|
93
96
|
iso_from, iso_to = key.split(INDEX_KEY_SEPARATOR)
|
|
94
|
-
|
|
97
|
+
yield iso_from, iso_to, rate
|
|
95
98
|
end
|
|
96
99
|
end
|
|
97
|
-
|
|
98
|
-
block_given? ? enum.each(&block) : enum
|
|
99
100
|
end
|
|
100
101
|
|
|
101
102
|
private
|
|
102
103
|
|
|
103
|
-
attr_reader :
|
|
104
|
+
attr_reader :rates, :options, :guard
|
|
104
105
|
|
|
105
106
|
# Return the rate hashkey for the given currencies.
|
|
106
107
|
#
|
data/lib/money/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: money
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 6.13.
|
|
4
|
+
version: 6.13.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shane Emmons
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2020-07-04 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: i18n
|
|
@@ -159,8 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
159
159
|
- !ruby/object:Gem::Version
|
|
160
160
|
version: '0'
|
|
161
161
|
requirements: []
|
|
162
|
-
|
|
163
|
-
rubygems_version: 2.6.8
|
|
162
|
+
rubygems_version: 3.1.2
|
|
164
163
|
signing_key:
|
|
165
164
|
specification_version: 4
|
|
166
165
|
summary: A Ruby Library for dealing with money and currency conversion.
|