money 6.13.0 → 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 +49 -2
- data/README.md +93 -3
- data/config/currency_backwards_compatible.json +31 -0
- data/config/currency_iso.json +18 -18
- data/lib/money/bank/variable_exchange.rb +14 -6
- data/lib/money/currency.rb +4 -4
- data/lib/money/currency/loader.rb +15 -13
- data/lib/money/locale_backend/currency.rb +11 -0
- data/lib/money/locale_backend/i18n.rb +2 -1
- data/lib/money/locale_backend/legacy.rb +2 -2
- data/lib/money/money.rb +100 -52
- data/lib/money/money/allocation.rb +8 -5
- data/lib/money/money/arithmetic.rb +20 -10
- data/lib/money/money/formatter.rb +3 -0
- data/lib/money/money/formatting_rules.rb +15 -5
- data/lib/money/money/locale_backend.rb +3 -1
- data/lib/money/rates_store/memory.rb +24 -23
- data/lib/money/version.rb +1 -1
- data/money.gemspec +4 -4
- metadata +11 -51
- data/.coveralls.yml +0 -1
- data/.gitignore +0 -23
- data/.rspec +0 -2
- data/.travis.yml +0 -32
- data/AUTHORS +0 -131
- data/CONTRIBUTING.md +0 -17
- data/Gemfile +0 -16
- data/Rakefile +0 -17
- data/spec/bank/base_spec.rb +0 -79
- data/spec/bank/single_currency_spec.rb +0 -13
- data/spec/bank/variable_exchange_spec.rb +0 -265
- data/spec/currency/heuristics_spec.rb +0 -11
- data/spec/currency/loader_spec.rb +0 -19
- data/spec/currency_spec.rb +0 -400
- data/spec/locale_backend/i18n_spec.rb +0 -62
- data/spec/locale_backend/legacy_spec.rb +0 -74
- data/spec/money/allocation_spec.rb +0 -130
- data/spec/money/arithmetic_spec.rb +0 -756
- data/spec/money/constructors_spec.rb +0 -91
- data/spec/money/formatting_spec.rb +0 -855
- data/spec/money/locale_backend_spec.rb +0 -14
- data/spec/money_spec.rb +0 -880
- data/spec/rates_store/memory_spec.rb +0 -80
- data/spec/spec_helper.rb +0 -30
- data/spec/support/shared_examples/money_examples.rb +0 -14
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,5 +1,52 @@
|
|
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
|
+
|
28
|
+
## 6.13.3
|
29
|
+
- Remove specs from the packaged gem
|
30
|
+
- Use Currency::Loader directly without extending
|
31
|
+
- Add Money.with_rounding_mode as a replacement for calling Money.rounding_mode with a block
|
32
|
+
- Fix currency search for two digit ISO numbers
|
33
|
+
- Add description to TypeError raised by +/- operations
|
34
|
+
|
35
|
+
## 6.13.2
|
36
|
+
- Prevent Money initialization with non-finite amounts
|
37
|
+
- Convert the fractional value of a Money object to BigDecimal when initializing
|
38
|
+
- Offer replacements for currency position deprecations
|
39
|
+
- Fix Peruvian Sol symbol
|
40
|
+
- Lock i18n to <= 1.2.0 for older (< 2.3) rubies
|
41
|
+
- Prevent Divide By Zero in `Money#allocate`
|
42
|
+
|
43
|
+
## 6.13.1
|
44
|
+
- Add bolívar soberano (VES)
|
45
|
+
- Deprecate bolívar fuerte (VEF)
|
46
|
+
- Deprecate old `#format` rules passed as a symbol
|
47
|
+
- Clarify `use_i18n` deprecation
|
48
|
+
- Add `:currency` locale_backend for explicit per-currency localization
|
49
|
+
|
3
50
|
## 6.13.0
|
4
51
|
- Add :format option to the Formatter
|
5
52
|
- Add ruby 2.6.0 support
|
@@ -20,7 +67,7 @@
|
|
20
67
|
- Wrap all amount parts when `:html_wrap` option is used
|
21
68
|
- Deprecate `#currency_as_string` and `#currency_as_string=` (in favour of `#with_currency`)
|
22
69
|
- Add `#with_currency` for swapping the currency
|
23
|
-
- Rewrite allocate/split (fixing some penny
|
70
|
+
- Rewrite allocate/split (fixing some penny losing issues)
|
24
71
|
|
25
72
|
## 6.11.3
|
26
73
|
- Fix regression: if enabled use i18n locales in Money#to_s
|
@@ -39,7 +86,7 @@
|
|
39
86
|
- Added new symbol for bitcoin denomination
|
40
87
|
- Specify custom rounding precision when using `infinite_precision`
|
41
88
|
- Allow splits with sums greater than 1
|
42
|
-
- Prevent arithmetic methods from
|
89
|
+
- Prevent arithmetic methods from losing reference to the bank
|
43
90
|
- Fix coerced zero numeric subtraction
|
44
91
|
- Fix south asian formatting to support whole numbers
|
45
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
|
@@ -392,6 +394,42 @@ m = Money.new('123', :gbp) # => #<Money fractional:123 currency:GBP>
|
|
392
394
|
m.format(symbol: m.currency.to_s + ' ') # => "GBP 1.23"
|
393
395
|
```
|
394
396
|
|
397
|
+
## Rounding
|
398
|
+
|
399
|
+
By default, `Money` objects are rounded to the nearest cent and the additional precision is not preserved:
|
400
|
+
|
401
|
+
```ruby
|
402
|
+
Money.from_amount(2.34567).format #=> "$2.35"
|
403
|
+
```
|
404
|
+
|
405
|
+
To retain the additional precision, you will also need to set `infinite_precision` to `true`.
|
406
|
+
|
407
|
+
```ruby
|
408
|
+
Money.infinite_precision = true
|
409
|
+
Money.from_amount(2.34567).format #=> "$2.34567"
|
410
|
+
```
|
411
|
+
|
412
|
+
To round to the nearest cent (or anything more precise), you can use the `round` method. However, note that the `round` method on a `Money` object does not work the same way as a normal Ruby `Float` object. Money's `round` method accepts different arguments. The first argument to the round method is the rounding mode, while the second argument is the level of precision relative to the cent.
|
413
|
+
|
414
|
+
```
|
415
|
+
# Float
|
416
|
+
2.34567.round #=> 2
|
417
|
+
2.34567.round(2) #=> 2.35
|
418
|
+
|
419
|
+
# Money
|
420
|
+
Money.infinite_precision = true
|
421
|
+
Money.new(2.34567).format #=> "$0.0234567"
|
422
|
+
Money.new(2.34567).round.format #=> "$0.02"
|
423
|
+
Money.new(2.34567).round(BigDecimal::ROUND_HALF_UP, 2).format #=> "$0.0235"
|
424
|
+
```
|
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
|
+
|
395
433
|
## Ruby on Rails
|
396
434
|
|
397
435
|
To integrate money in a Rails application use [money-rails](https://github.com/RubyMoney/money-rails).
|
@@ -434,6 +472,58 @@ If you wish to disable this feature and use defaults instead:
|
|
434
472
|
Money.locale_backend = nil
|
435
473
|
```
|
436
474
|
|
475
|
+
### Deprecation
|
476
|
+
|
477
|
+
The current default behaviour always checks the I18n locale first, falling back to "per currency"
|
478
|
+
localization. This is now deprecated and will be removed in favour of explicitly defined behaviour
|
479
|
+
in the next major release.
|
480
|
+
|
481
|
+
If you would like to use I18n localization (formatting depends on the locale):
|
482
|
+
|
483
|
+
```ruby
|
484
|
+
Money.locale_backend = :i18n
|
485
|
+
|
486
|
+
# example (using default localization from rails-i18n):
|
487
|
+
I18n.locale = :en
|
488
|
+
Money.new(10_000_00, 'USD').format # => $10,000.00
|
489
|
+
Money.new(10_000_00, 'EUR').format # => €10,000.00
|
490
|
+
|
491
|
+
I18n.locale = :es
|
492
|
+
Money.new(10_000_00, 'USD').format # => $10.000,00
|
493
|
+
Money.new(10_000_00, 'EUR').format # => €10.000,00
|
494
|
+
```
|
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
|
+
|
506
|
+
For the legacy behaviour of "per currency" localization (formatting depends only on currency):
|
507
|
+
|
508
|
+
```ruby
|
509
|
+
Money.locale_backend = :currency
|
510
|
+
|
511
|
+
# example:
|
512
|
+
Money.new(10_000_00, 'USD').format # => $10,000.00
|
513
|
+
Money.new(10_000_00, 'EUR').format # => €10.000,00
|
514
|
+
```
|
515
|
+
|
516
|
+
In case you don't need localization and would like to use default values (can be redefined using
|
517
|
+
`Money.default_formatting_rules`):
|
518
|
+
|
519
|
+
```ruby
|
520
|
+
Money.locale_backend = nil
|
521
|
+
|
522
|
+
# example:
|
523
|
+
Money.new(10_000_00, 'USD').format # => $10000.00
|
524
|
+
Money.new(10_000_00, 'EUR').format # => €10000.00
|
525
|
+
```
|
526
|
+
|
437
527
|
## Collection
|
438
528
|
|
439
529
|
In case you're working with collections of `Money` instances, have a look at [money-collection](https://github.com/RubyMoney/money-collection)
|
@@ -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",
|
@@ -169,5 +185,20 @@
|
|
169
185
|
"thousands_separator": ",",
|
170
186
|
"iso_numeric": "935",
|
171
187
|
"smallest_denomination": 100
|
188
|
+
},
|
189
|
+
"vef": {
|
190
|
+
"priority": 100,
|
191
|
+
"iso_code": "VEF",
|
192
|
+
"name": "Venezuelan Bolívar",
|
193
|
+
"symbol": "Bs.F",
|
194
|
+
"alternate_symbols": ["Bs"],
|
195
|
+
"subunit": "Céntimo",
|
196
|
+
"subunit_to_unit": 100,
|
197
|
+
"symbol_first": true,
|
198
|
+
"html_entity": "",
|
199
|
+
"decimal_mark": ",",
|
200
|
+
"thousands_separator": ".",
|
201
|
+
"iso_numeric": "937",
|
202
|
+
"smallest_denomination": 1
|
172
203
|
}
|
173
204
|
}
|
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": {
|
@@ -1647,12 +1647,12 @@
|
|
1647
1647
|
"priority": 100,
|
1648
1648
|
"iso_code": "PEN",
|
1649
1649
|
"name": "Peruvian Sol",
|
1650
|
-
"symbol": "S
|
1650
|
+
"symbol": "S/",
|
1651
1651
|
"alternate_symbols": [],
|
1652
1652
|
"subunit": "Céntimo",
|
1653
1653
|
"subunit_to_unit": 100,
|
1654
1654
|
"symbol_first": true,
|
1655
|
-
"html_entity": "S
|
1655
|
+
"html_entity": "S/",
|
1656
1656
|
"decimal_mark": ".",
|
1657
1657
|
"thousands_separator": ",",
|
1658
1658
|
"iso_numeric": "604",
|
@@ -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,
|
@@ -2271,19 +2271,19 @@
|
|
2271
2271
|
"iso_numeric": "860",
|
2272
2272
|
"smallest_denomination": 100
|
2273
2273
|
},
|
2274
|
-
"
|
2274
|
+
"ves": {
|
2275
2275
|
"priority": 100,
|
2276
|
-
"iso_code": "
|
2277
|
-
"name": "Venezuelan Bolívar",
|
2276
|
+
"iso_code": "VES",
|
2277
|
+
"name": "Venezuelan Bolívar Soberano",
|
2278
2278
|
"symbol": "Bs",
|
2279
|
-
"alternate_symbols": ["Bs.
|
2279
|
+
"alternate_symbols": ["Bs.S"],
|
2280
2280
|
"subunit": "Céntimo",
|
2281
2281
|
"subunit_to_unit": 100,
|
2282
2282
|
"symbol_first": true,
|
2283
2283
|
"html_entity": "",
|
2284
2284
|
"decimal_mark": ",",
|
2285
2285
|
"thousands_separator": ".",
|
2286
|
-
"iso_numeric": "
|
2286
|
+
"iso_numeric": "928",
|
2287
2287
|
"smallest_denomination": 1
|
2288
2288
|
},
|
2289
2289
|
"vnd": {
|
@@ -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
@@ -13,7 +13,6 @@ class Money
|
|
13
13
|
class Currency
|
14
14
|
include Comparable
|
15
15
|
extend Enumerable
|
16
|
-
extend Money::Currency::Loader
|
17
16
|
extend Money::Currency::Heuristics
|
18
17
|
|
19
18
|
# Keeping cached instances in sync between threads
|
@@ -76,9 +75,10 @@ class Money
|
|
76
75
|
#
|
77
76
|
# @example
|
78
77
|
# Money::Currency.find_by_iso_numeric(978) #=> #<Money::Currency id: eur ...>
|
78
|
+
# Money::Currency.find_by_iso_numeric(51) #=> #<Money::Currency id: amd ...>
|
79
79
|
# Money::Currency.find_by_iso_numeric('001') #=> nil
|
80
80
|
def find_by_iso_numeric(num)
|
81
|
-
num = num.to_s
|
81
|
+
num = num.to_s.rjust(3, '0')
|
82
82
|
return if num.empty?
|
83
83
|
id, _ = self.table.find { |key, currency| currency[:iso_numeric] == num }
|
84
84
|
new(id)
|
@@ -121,7 +121,7 @@ class Money
|
|
121
121
|
# See https://en.wikipedia.org/wiki/List_of_circulating_currencies and
|
122
122
|
# http://search.cpan.org/~tnguyen/Locale-Currency-Format-1.28/Format.pm
|
123
123
|
def table
|
124
|
-
@table ||= load_currencies
|
124
|
+
@table ||= Loader.load_currencies
|
125
125
|
end
|
126
126
|
|
127
127
|
# List the currencies imported and registered
|
@@ -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]
|