money 6.0.0.pre3 → 6.0.0.pre4

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
  SHA1:
3
- metadata.gz: b9dae4831f4901cf906ae3d6f155c9bac6e3f67f
4
- data.tar.gz: 43718a7d7edfce6329053cd90a7b61ec2d4d3a78
3
+ metadata.gz: ea888a5a751fe5366637910259bed324998d8946
4
+ data.tar.gz: 23c2300799b945f0ae892d71bc64511e1978d209
5
5
  SHA512:
6
- metadata.gz: a13f5e9078a642608bc4d224639b27ca74b44952c6cba8790515534c5e09d50d77eba86c4f0fc0540fb4d840cf8b9c3cef6ef8af6a06fb5c81740850862e971e
7
- data.tar.gz: 652d159f7d083c9975f15ad14f3f92cd2aea19c475cacc3dead90711771d5ed04b32e96a66b97b08ee3153816670037088a8ad8fb49f2c5b552b8336a2dde2af
6
+ metadata.gz: c14c97b517d52e3e78ab675b033eb2f59a2d0d46315d592bc928d87fda3896c2b90a163512468697a8817395db147f98894aa9fc24b6b433b59a33892947386c
7
+ data.tar.gz: 05ac021536a9b31669856f93a47ccec21605fac4c99b0e828b579dbea7df6a4945dfe6742f71b25e19df28989014b553cccb84a8e2169ea08dccfecb76e88957
data/CHANGELOG.md CHANGED
@@ -19,6 +19,9 @@
19
19
  - Changed `thousands_separator` for Swedish Krona from dot to blank space.
20
20
  - Allow mathematical operations with first argument being not an instance of Money (eg. 2 * money instead of money * 2).
21
21
  - Money#dollars and Money#amount methods return numbers of type BigDecimal.
22
+ - Change Money.from_bigdecimal (and in that way .to_money too) to keep precision when using `Money.infinite_precision = true`
23
+ - Add :rounded_infinite_precision option to .format
24
+ - Changed the New Taiwan Dollar symbol position from after the amount to before the amount.
22
25
 
23
26
  ## 5.1.1
24
27
 
@@ -1994,7 +1994,7 @@
1994
1994
  "alternate_symbols": ["NT$"],
1995
1995
  "subunit": "Cent",
1996
1996
  "subunit_to_unit": 100,
1997
- "symbol_first": false,
1997
+ "symbol_first": true,
1998
1998
  "html_entity": "$",
1999
1999
  "decimal_mark": ".",
2000
2000
  "thousands_separator": ",",
@@ -5,6 +5,8 @@ require 'json'
5
5
  class Money
6
6
 
7
7
  # Represents a specific currency unit.
8
+ #
9
+ # @see http://en.wikipedia.org/wiki/Currency
8
10
  class Currency
9
11
  include Comparable
10
12
 
@@ -140,11 +142,14 @@ class Money
140
142
  # The international 3-letter code as defined by the ISO 4217 standard.
141
143
  #
142
144
  # @return [String]
145
+ # @see http://iso4217.net/
143
146
  attr_reader :iso_code
147
+
144
148
  #
145
149
  # The international 3-numeric code as defined by the ISO 4217 standard.
146
150
  #
147
151
  # @return [String]
152
+ # @see http://iso4217.net/
148
153
  attr_reader :iso_numeric
149
154
 
150
155
  # The currency name.
data/lib/money/money.rb CHANGED
@@ -4,7 +4,15 @@ require "money/money/arithmetic"
4
4
  require "money/money/parsing"
5
5
  require "money/money/formatting"
6
6
 
7
- # Represents an amount of money in a given currency.
7
+ # "Money is any object or record that is generally accepted as payment for
8
+ # goods and services and repayment of debts in a given socio-economic context
9
+ # or country." -Wikipedia
10
+ #
11
+ # An instance of Money represents an amount of a specific currency.
12
+ #
13
+ # Money is a value object and should be treated as immutable.
14
+ #
15
+ # @see http://en.wikipedia.org/wiki/Money
8
16
  class Money
9
17
  include Comparable
10
18
  include Arithmetic
@@ -13,14 +21,36 @@ class Money
13
21
 
14
22
  # Convenience method for fractional part of the amount. Synonym of #fractional
15
23
  #
16
- # @return [Integer]
24
+ # @return [Integer] when inifinte_precision is false
25
+ # @return [BigDecimal] when inifinte_precision is true
26
+ #
27
+ # @see infinite_precision
17
28
  def cents
18
29
  fractional
19
30
  end
20
31
 
21
- # The value of the amount represented in the fractional unit of the currency. Example: USD, 1 dollar (amount) == 100 cents (fractional unit).
32
+ # The value of the monetary amount represented in the fractional or subunit
33
+ # of the currency.
34
+ #
35
+ # For example, in the US Dollar currency the fractional unit is cents, and
36
+ # there are 100 cents in one US Dollar. So given the Money representation of
37
+ # one US dollar, the fractional interpretation is 100.
38
+ #
39
+ # Another example is that of the Kuwaiti Dinar. In this case the fractional
40
+ # unit is the Fils and there 1000 Fils to one Kuwaiti Dinar. So given the
41
+ # Money representation of one Kuwaiti Dinar, the fractional interpretation is
42
+ # 1000.
43
+ #
44
+ # @example
45
+ # Money.new_with_amount(1, "USD").fractional #=> 100
46
+ # Money.new_with_amount(1, "KWD").fractional #=> 1000
47
+ # Money.new_with_amount(105.50, "USD").fractional #=> 10550
48
+ # Money.new_with_amount(15.763, 'KWD').fractional #=> 15763
22
49
  #
23
- # @return [Integer]
50
+ # @return [Integer] when inifinte_precision is false
51
+ # @return [BigDecimal] when inifinte_precision is true
52
+ #
53
+ # @see infinite_precision
24
54
  def fractional
25
55
  # Ensure we have a BigDecimal. If the Money object is created
26
56
  # from YAML, @fractional can end up being set to a Float.
@@ -188,12 +218,9 @@ class Money
188
218
  # @return [Money]
189
219
  #
190
220
  # @example
191
- # Money.new_with_amount(100)
192
- # #=> #<Money @fractional=10000 @currency="USD">
193
- # Money.new_with_amount(100, "USD")
194
- # #=> #<Money @fractional=10000 @currency="USD">
195
- # Money.new_with_amount(100, "EUR")
196
- # #=> #<Money @fractional=10000 @currency="EUR">
221
+ # Money.new_with_amount(100) #=> #<Money @fractional=10000 @currency="USD">
222
+ # Money.new_with_amount(100, "USD") #=> #<Money @fractional=10000 @currency="USD">
223
+ # Money.new_with_amount(100, "EUR") #=> #<Money @fractional=10000 @currency="EUR">
197
224
  #
198
225
  # @see Money.new
199
226
  #
@@ -225,8 +252,7 @@ class Money
225
252
  Money.default_bank.add_rate(from_currency, to_currency, rate)
226
253
  end
227
254
 
228
-
229
- # Creates a new Money object of value given in the
255
+ # Creates a new Money object of value given in the
230
256
  # +fractional unit+ of the given +currency+.
231
257
  #
232
258
  # Alternatively you can use the convenience
@@ -239,12 +265,9 @@ class Money
239
265
  # @return [Money]
240
266
  #
241
267
  # @example
242
- # Money.new(100)
243
- # #=> #<Money @fractional=100 @currency="USD">
244
- # Money.new(100, "USD")
245
- # #=> #<Money @fractional=100 @currency="USD">
246
- # Money.new(100, "EUR")
247
- # #=> #<Money @fractional=100 @currency="EUR">
268
+ # Money.new(100) #=> #<Money @fractional=100 @currency="USD">
269
+ # Money.new(100, "USD") #=> #<Money @fractional=100 @currency="USD">
270
+ # Money.new(100, "EUR") #=> #<Money @fractional=100 @currency="EUR">
248
271
  #
249
272
  # @see Money.new_with_dollars
250
273
  #
@@ -263,8 +286,8 @@ class Money
263
286
  # @return [BigDecimal]
264
287
  #
265
288
  # @example
266
- # Money.new(100).dollars # => 1.0
267
- # Money.new_with_dollars(1).dollar # => 1.0
289
+ # Money.new(1_00, "USD").dollars # => BigDecimal.new("1.00")
290
+ # Money.new_with_dollars(1).dollar # => BigDecimal.new("1.00")
268
291
  #
269
292
  # @see #amount
270
293
  # @see #to_d
@@ -279,8 +302,8 @@ class Money
279
302
  # @return [BigDecimal]
280
303
  #
281
304
  # @example
282
- # Money.new(100).amount # => 1.0
283
- # Money.new_with_amount(1).amount # => 1.0
305
+ # Money.new(1_00, "USD").amount # => BigDecimal.new("1.00")
306
+ # Money.new_with_amount(1).amount # => BigDecimal.new("1.00")
284
307
  #
285
308
  # @see #to_d
286
309
  # @see #fractional
@@ -388,7 +411,7 @@ class Money
388
411
  # @return [BigDecimal]
389
412
  #
390
413
  # @example
391
- # Money.us_dollar(100).to_d => BigDecimal.new("1.0")
414
+ # Money.us_dollar(1_00).to_d #=> BigDecimal.new("1.00")
392
415
  def to_d
393
416
  as_d(fractional) / as_d(currency.subunit_to_unit)
394
417
  end
@@ -401,7 +424,7 @@ class Money
401
424
  # @return [Float]
402
425
  #
403
426
  # @example
404
- # Money.us_dollar(100).to_f => 1.0
427
+ # Money.us_dollar(100).to_f #=> 1.0
405
428
  def to_f
406
429
  to_d.to_f
407
430
  end
@@ -473,13 +496,14 @@ class Money
473
496
  # be distributed round-robin amongst the parties. This means that parties
474
497
  # listed first will likely recieve more pennies then ones that are listed later
475
498
  #
476
- # @param [Array<Float, Float, Float>] splits [0.50, 0.25, 0.25] to give 50% of the cash to party1, 25% to party2, and 25% to party3.
499
+ # @param [Array<Numeric>] splits [0.50, 0.25, 0.25] to give 50% of the cash to party1, 25% to party2, and 25% to party3.
477
500
  #
478
- # @return [Array<Money, Money, Money>]
501
+ # @return [Array<Money>]
479
502
  #
480
503
  # @example
481
- # Money.new(5, "USD").allocate([0.3,0.7)) #=> [Money.new(2), Money.new(3)]
482
- # Money.new(100, "USD").allocate([0.33,0.33,0.33]) #=> [Money.new(34), Money.new(33), Money.new(33)]
504
+ # Money.new(5, "USD").allocate([0.3, 0.7]) #=> [Money.new(2), Money.new(3)]
505
+ # Money.new(100, "USD").allocate([0.33, 0.33, 0.33]) #=> [Money.new(34), Money.new(33), Money.new(33)]
506
+ #
483
507
  def allocate(splits)
484
508
  allocations = splits.inject(0) { |sum, n| sum + as_d(n) }
485
509
 
@@ -510,7 +534,7 @@ class Money
510
534
  #
511
535
  # @param [Numeric] num number of parties.
512
536
  #
513
- # @return [Array<Money, Money, Money>]
537
+ # @return [Array<Money>]
514
538
  #
515
539
  # @example
516
540
  # Money.new(100, "USD").split(3) #=> [Money.new(34), Money.new(33), Money.new(33)]
@@ -537,15 +561,19 @@ class Money
537
561
 
538
562
  # Round the monetary amount to smallest unit of coinage.
539
563
  #
540
- # This method is only useful when operating with infinite_precision turned
541
- # on. Without infinite_precision values are rounded to the smallest unit of
542
- # coinage automatically.
564
+ # @note
565
+ # This method is only useful when operating with infinite_precision turned
566
+ # on. Without infinite_precision values are rounded to the smallest unit of
567
+ # coinage automatically.
543
568
  #
544
569
  # @return [Money]
545
570
  #
546
571
  # @example
547
572
  # Money.new(10.1, 'USD').round #=> Money.new(10, 'USD')
548
573
  #
574
+ # @see
575
+ # Money.infinite_precision
576
+ #
549
577
  def round(rounding_mode = self.class.rounding_mode)
550
578
  if self.class.infinite_precision
551
579
  return Money.new(fractional.round(0, rounding_mode), self.currency)
@@ -63,10 +63,18 @@ class Money
63
63
  # should be appended to the result string.
64
64
  #
65
65
  # @example
66
- # Money.ca_dollar(100).format => "$1.00"
66
+ # Money.ca_dollar(100).format #=> "$1.00"
67
67
  # Money.ca_dollar(100).format(:with_currency => true) #=> "$1.00 CAD"
68
68
  # Money.us_dollar(85).format(:with_currency => true) #=> "$0.85 USD"
69
69
  #
70
+ # @option *rules [Boolean] :rounded_infinite_precision (false) Whether the
71
+ # amount of money should be rounded when using infinite_precision
72
+ #
73
+ # @example
74
+ # Money.us_dollar(100.1).format #=> "$1.001"
75
+ # Money.us_dollar(100.1).format(:rounded_infinite_precision => true) #=> "$1"
76
+ # Money.us_dollar(100.9).format(:rounded_infinite_precision => true) #=> "$1.01"
77
+ #
70
78
  # @option *rules [Boolean] :no_cents (false) Whether cents should be omitted.
71
79
  #
72
80
  # @example
@@ -220,12 +228,24 @@ class Money
220
228
  symbol
221
229
  end
222
230
 
223
- sign = self.negative? ? '-' : ''
224
- formatted = rules[:no_cents] ? "#{self.abs.to_s.to_i}" : self.abs.to_s
231
+ formatted = self.abs.to_s
232
+
233
+ if rules[:rounded_infinite_precision]
234
+ formatted = ((BigDecimal(formatted) * currency.subunit_to_unit).round / BigDecimal(currency.subunit_to_unit.to_s)).to_s("F")
235
+ formatted.gsub!(/\..*/) do |decimal_part|
236
+ if decimal_part == '.0'
237
+ ''
238
+ else
239
+ decimal_part << '0' while decimal_part.length < (currency.decimal_places + 1)
240
+ decimal_part
241
+ end
242
+ end
243
+ end
225
244
 
245
+ sign = self.negative? ? '-' : ''
226
246
 
227
- if rules[:no_cents_if_whole] && cents % currency.subunit_to_unit == 0
228
- formatted = "#{self.to_s.to_i}"
247
+ if rules[:no_cents] || (rules[:no_cents_if_whole] && cents % currency.subunit_to_unit == 0)
248
+ formatted = "#{formatted.to_i}"
229
249
  end
230
250
 
231
251
  thousands_separator_value = thousands_separator
@@ -187,7 +187,8 @@ class Money
187
187
  def from_bigdecimal(value, currency = Money.default_currency)
188
188
  currency = Money::Currency.wrap(currency)
189
189
  amount = value * currency.subunit_to_unit
190
- new(amount.round, currency)
190
+ amount = amount.round unless Money.infinite_precision
191
+ new(amount, currency)
191
192
  end
192
193
 
193
194
  # Converts a Numeric value into a Money object treating the +value+
data/money.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  Gem::Specification.new do |s|
3
3
  s.name = "money"
4
- s.version = "6.0.0.pre3"
4
+ s.version = "6.0.0.pre4"
5
5
  s.platform = Gem::Platform::RUBY
6
6
  s.authors = ["Tobias Luetke", "Hongli Lai", "Jeremy McNevin",
7
7
  "Shane Emmons", "Simone Carletti"]
@@ -439,6 +439,36 @@ describe Money, "formatting" do
439
439
  end
440
440
  end
441
441
 
442
+ describe ":rounded_infinite_precision option" do
443
+ before do
444
+ Money.infinite_precision = true
445
+ end
446
+
447
+ after do
448
+ Money.infinite_precision = false
449
+ end
450
+
451
+ it "does round fractional when set to true" do
452
+ Money.new(BigDecimal.new('12.1'), "USD").format(:rounded_infinite_precision => true).should == "$0.12"
453
+ Money.new(BigDecimal.new('12.5'), "USD").format(:rounded_infinite_precision => true).should == "$0.13"
454
+ Money.new(BigDecimal.new('123.1'), "BHD").format(:rounded_infinite_precision => true).should == "ب.د0.123"
455
+ Money.new(BigDecimal.new('123.5'), "BHD").format(:rounded_infinite_precision => true).should == "ب.د0.124"
456
+ Money.new(BigDecimal.new('100.1'), "USD").format(:rounded_infinite_precision => true).should == "$1"
457
+ Money.new(BigDecimal.new('109.5'), "USD").format(:rounded_infinite_precision => true).should == "$1.10"
458
+ Money.new(BigDecimal.new('1'), "MGA").format(:rounded_infinite_precision => true).should == "Ar0.2"
459
+ end
460
+
461
+ it "does not round fractional when set to false" do
462
+ Money.new(BigDecimal.new('12.1'), "USD").format(:rounded_infinite_precision => false).should == "$0.121"
463
+ Money.new(BigDecimal.new('12.5'), "USD").format(:rounded_infinite_precision => false).should == "$0.125"
464
+ Money.new(BigDecimal.new('123.1'), "BHD").format(:rounded_infinite_precision => false).should == "ب.د0.1231"
465
+ Money.new(BigDecimal.new('123.5'), "BHD").format(:rounded_infinite_precision => false).should == "ب.د0.1235"
466
+ Money.new(BigDecimal.new('100.1'), "USD").format(:rounded_infinite_precision => false).should == "$1.001"
467
+ Money.new(BigDecimal.new('109.5'), "USD").format(:rounded_infinite_precision => false).should == "$1.095"
468
+ Money.new(BigDecimal.new('1'), "MGA").format(:rounded_infinite_precision => false).should == "Ar0.1"
469
+ end
470
+ end
471
+
442
472
  context "when the monetary value is 0" do
443
473
  let(:money) { Money.us_dollar(0) }
444
474
 
@@ -260,6 +260,23 @@ describe Money, "parsing" do
260
260
  m = Money.from_bigdecimal(BigDecimal.new("1"), "EUR")
261
261
  m.currency.should == Money::Currency.wrap("EUR")
262
262
  end
263
+
264
+ context "infinite_precision = true" do
265
+ before do
266
+ Money.infinite_precision = true
267
+ end
268
+
269
+ after do
270
+ Money.infinite_precision = false
271
+ end
272
+
273
+ it "keeps precision" do
274
+ Money.from_bigdecimal(BigDecimal.new("1.23456")).should == Money.new(123.456)
275
+ Money.from_bigdecimal(BigDecimal.new("-1.23456")).should == Money.new(-123.456)
276
+ Money.from_bigdecimal(BigDecimal.new("1.23456")).should == Money.new(123.456, "USD")
277
+ Money.from_bigdecimal(BigDecimal.new("1.23456"), "EUR").should == Money.new(123.456, "EUR")
278
+ end
279
+ end
263
280
  end
264
281
 
265
282
  describe ".from_numeric" do
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.0.0.pre3
4
+ version: 6.0.0.pre4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Luetke
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2013-09-04 00:00:00.000000000 Z
15
+ date: 2013-09-14 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: i18n
@@ -77,32 +77,32 @@ executables: []
77
77
  extensions: []
78
78
  extra_rdoc_files: []
79
79
  files:
80
- - config/currency_backwards_compatible.json
81
80
  - config/currency_iso.json
81
+ - config/currency_backwards_compatible.json
82
82
  - config/currency_non_iso.json
83
- - lib/money.rb
84
- - lib/money/bank/base.rb
85
- - lib/money/bank/variable_exchange.rb
86
- - lib/money/core_extensions.rb
87
83
  - lib/money/currency.rb
88
- - lib/money/currency/heuristics.rb
89
- - lib/money/currency/loader.rb
90
- - lib/money/deprecations.rb
91
- - lib/money/money.rb
92
84
  - lib/money/money/arithmetic.rb
93
- - lib/money/money/formatting.rb
94
85
  - lib/money/money/parsing.rb
95
- - spec/bank/base_spec.rb
96
- - spec/bank/variable_exchange_spec.rb
97
- - spec/core_extensions_spec.rb
98
- - spec/currency/heuristics_spec.rb
86
+ - lib/money/money/formatting.rb
87
+ - lib/money/core_extensions.rb
88
+ - lib/money/deprecations.rb
89
+ - lib/money/currency/loader.rb
90
+ - lib/money/currency/heuristics.rb
91
+ - lib/money/bank/variable_exchange.rb
92
+ - lib/money/bank/base.rb
93
+ - lib/money/money.rb
94
+ - lib/money.rb
95
+ - spec/support/default_currency_helper.rb
99
96
  - spec/currency_spec.rb
97
+ - spec/core_extensions_spec.rb
98
+ - spec/money/parsing_spec.rb
100
99
  - spec/money/arithmetic_spec.rb
101
100
  - spec/money/formatting_spec.rb
102
- - spec/money/parsing_spec.rb
103
101
  - spec/money_spec.rb
102
+ - spec/currency/heuristics_spec.rb
104
103
  - spec/spec_helper.rb
105
- - spec/support/default_currency_helper.rb
104
+ - spec/bank/variable_exchange_spec.rb
105
+ - spec/bank/base_spec.rb
106
106
  - CHANGELOG.md
107
107
  - LICENSE
108
108
  - README.md