money 6.0.0 → 6.0.1.beta1

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.
@@ -11,7 +11,6 @@ class Money
11
11
  Money.new(-fractional, currency)
12
12
  end
13
13
 
14
-
15
14
  # Checks whether two money objects have the same currency and the same
16
15
  # amount. Checks against money objects with a different currency and checks
17
16
  # against objects that do not respond to #to_money will always return false.
@@ -25,7 +24,9 @@ class Money
25
24
  # Money.new(100) == Money.new(100) #=> true
26
25
  def ==(other_money)
27
26
  if other_money.respond_to?(:to_money)
28
- Money.deprecate "as of Money 6.1.0 you must `require 'money/core_extension'` to compare Money to core classes." unless other_money.is_a? Money
27
+ unless other_money.is_a?(Money)
28
+ Money.deprecate "as of Money 6.1.0 you must `require 'money/core_extensions'` to compare Money to core classes." unless Money.silence_core_extensions_deprecations
29
+ end
29
30
  other_money = other_money.to_money
30
31
  fractional == other_money.fractional && currency == other_money.currency
31
32
  else
@@ -46,7 +47,9 @@ class Money
46
47
 
47
48
  def <=>(other_money)
48
49
  if other_money.respond_to?(:to_money)
49
- Money.deprecate "as of Money 6.1.0 you must `require 'money/core_extension'` to compare Money to core classes." unless other_money.is_a? Money
50
+ unless other_money.is_a?(Money)
51
+ Money.deprecate "as of Money 6.1.0 you must `require 'money/core_extensions'` to compare Money to core classes." unless Money.silence_core_extensions_deprecations
52
+ end
50
53
  other_money = other_money.to_money
51
54
  if fractional == 0 || other_money.fractional == 0 || currency == other_money.currency
52
55
  fractional <=> other_money.fractional
@@ -7,369 +7,39 @@ class Money
7
7
  end
8
8
 
9
9
  module ClassMethods
10
- # Parses the current string and converts it to a +Money+ object.
11
- # Excess characters will be discarded.
12
- #
13
- # @param [String, #to_s] input The input to parse.
14
- # @param [Currency, String, Symbol] currency The currency format.
15
- # The currency to set the resulting +Money+ object to.
16
- #
17
- # @return [Money]
18
- #
19
- # @raise [ArgumentError] If any +currency+ is supplied and
20
- # given value doesn't match the one extracted from
21
- # the +input+ string.
22
- #
23
- # @example
24
- # '100'.to_money #=> #<Money @fractional=10000>
25
- # '100.37'.to_money #=> #<Money @fractional=10037>
26
- # '100 USD'.to_money #=> #<Money @fractional=10000, @currency=#<Money::Currency id: usd>>
27
- # 'USD 100'.to_money #=> #<Money @fractional=10000, @currency=#<Money::Currency id: usd>>
28
- # '$100 USD'.to_money #=> #<Money @fractional=10000, @currency=#<Money::Currency id: usd>>
29
- # 'hello 2000 world'.to_money #=> #<Money @fractional=200000 @currency=#<Money::Currency id: usd>>
30
- #
31
- # @example Mismatching currencies
32
- # 'USD 2000'.to_money("EUR") #=> ArgumentError
33
- #
34
- # @see #from_string
35
- #
36
10
  def parse(input, currency = nil)
37
- Money.deprecate ".parse is depreciated and will be remove in 6.1.0. Please write your own parsing methods."
38
- i = input.to_s.strip
39
-
40
- # raise Money::Currency.table.collect{|c| c[1][:symbol]}.inspect
41
-
42
- # Check the first character for a currency symbol, alternatively get it
43
- # from the stated currency string
44
- c = if Money.assume_from_symbol && i =~ /^(\$|€|£)/
45
- case i
46
- when /^\$/ then "USD"
47
- when /^€/ then "EUR"
48
- when /^£/ then "GBP"
49
- end
50
- else
51
- i[/[A-Z]{2,3}/]
52
- end
53
-
54
- # check that currency passed and embedded currency are the same,
55
- # and negotiate the final currency
56
- if currency.nil? and c.nil?
57
- currency = Money.default_currency
58
- elsif currency.nil?
59
- currency = c
60
- elsif c.nil?
61
- currency = currency
62
- elsif currency != c
63
- # TODO: ParseError
64
- raise ArgumentError, "Mismatching Currencies"
65
- end
66
- currency = Money::Currency.wrap(currency)
67
-
68
- fractional = extract_cents(i, currency)
69
- new(fractional, currency)
11
+ Money.deprecate ".parse is deprecated and will be removed in 6.1.0. Please use the `monetize` gem."
12
+ Monetize.parse(input, currency)
70
13
  end
71
14
 
72
- # Converts a String into a Money object treating the +value+
73
- # as amount and converting to fractional unit,
74
- # according to +currency+ subunit property,
75
- # before instantiating the Money object.
76
- #
77
- # Behind the scenes, this method relies on {#from_bigdecimal}
78
- # to avoid problems with string-to-numeric conversion.
79
- #
80
- # @param [String, #to_s] value The money amount, in dollars.
81
- # @param [Currency, String, Symbol] currency
82
- # The currency to set the resulting +Money+ object to.
83
- #
84
- # @return [Money]
85
- #
86
- # @example
87
- # Money.from_string("100")
88
- # #=> #<Money @fractional=10000 @currency="USD">
89
- # Money.from_string("100", "USD")
90
- # #=> #<Money @fractional=10000 @currency="USD">
91
- # Money.from_string("100", "EUR")
92
- # #=> #<Money @fractional=10000 @currency="EUR">
93
- # Money.from_string("100", "BHD")
94
- # #=> #<Money @fractional=100 @currency="BHD">
95
- #
96
- # @see String#to_money
97
- # @see #parse
98
- #
99
15
  def from_string(value, currency = Money.default_currency)
100
- Money.deprecate ".from_string is depreciated and will be remove in 6.1.0. Please write your own parsing methods."
101
- from_bigdecimal(BigDecimal.new(value.to_s), currency)
16
+ Money.deprecate ".from_string is deprecated and will be removed in 6.1.0. Please use the `monetize` gem."
17
+ Monetize.from_string(value, currency)
102
18
  end
103
19
 
104
- # Converts a Fixnum into a Money object treating the +value+
105
- # as amount and to corresponding fractional unit,
106
- # according to +currency+ subunit property,
107
- # before instantiating the Money object.
108
- #
109
- # @param [Fixnum] value The money amount, in dollars.
110
- # @param [Currency, String, Symbol] currency The currency format.
111
- #
112
- # @return [Money]
113
- #
114
- # @example
115
- # Money.from_fixnum(100)
116
- # #=> #<Money @fractional=10000 @currency="USD">
117
- # Money.from_fixnum(100, "USD")
118
- # #=> #<Money @fractional=10000 @currency="USD">
119
- # Money.from_fixnum(100, "EUR")
120
- # #=> #<Money @fractional=10000 @currency="EUR">
121
- # Money.from_fixnum(100, "BHD")
122
- # #=> #<Money @fractional=100 @currency="BHD">
123
- #
124
- # @see Fixnum#to_money
125
- # @see #from_numeric
126
- #
127
20
  def from_fixnum(value, currency = Money.default_currency)
128
- currency = Money::Currency.wrap(currency)
129
- amount = value * currency.subunit_to_unit
130
- new(amount, currency)
21
+ Money.deprecate ".from_fixnum is deprecated and will be removed in 6.1.0. Please use the `monetize` gem."
22
+ Monetize.from_fixnum(value, currency)
131
23
  end
132
24
 
133
- # Converts a Float into a Money object treating the +value+
134
- # as dollars and to corresponding fractional unit,
135
- # according to +currency+ subunit property,
136
- # before instantiating the Money object.
137
- #
138
- # Behind the scenes, this method relies on Money.from_bigdecimal
139
- # to avoid problems with floating point precision.
140
- #
141
- # @param [Float] value The money amount, in dollars.
142
- # @param [Currency, String, Symbol] currency The currency format.
143
- #
144
- # @return [Money]
145
- #
146
- # @example
147
- # Money.from_float(100.0)
148
- # #=> #<Money @fractional=10000 @currency="USD">
149
- # Money.from_float(100.0, "USD")
150
- # #=> #<Money @fractional=10000 @currency="USD">
151
- # Money.from_float(100.0, "EUR")
152
- # #=> #<Money @fractional=10000 @currency="EUR">
153
- # Money.from_float(100.0, "BHD")
154
- # #=> #<Money @fractional=100 @currency="BHD">
155
- #
156
- # @see Float#to_money
157
- # @see #from_numeric
158
- #
159
25
  def from_float(value, currency = Money.default_currency)
160
- Money.deprecate ".from_float is depreciated and will be remove in 6.1.0. Please write your own parsing methods."
161
- from_bigdecimal(BigDecimal.new(value.to_s), currency)
26
+ Money.deprecate ".from_float is deprecated and will be removed in 6.1.0. Please use the `monetize` gem."
27
+ Monetize.from_float(value, currency)
162
28
  end
163
29
 
164
- # Converts a BigDecimal into a Money object treating the +value+
165
- # as dollars and converting to corresponding fractional unit,
166
- # according to +currency+ subunit property,
167
- # before instantiating the Money object.
168
- #
169
- # @param [BigDecimal] value The money amount, in dollars.
170
- # @param [Currency, String, Symbol] currency The currency format.
171
- #
172
- # @return [Money]
173
- #
174
- # @example
175
- # Money.from_bigdecimal(BigDecimal.new("100")
176
- # #=> #<Money @fractional=10000 @currency="USD">
177
- # Money.from_bigdecimal(BigDecimal.new("100", "USD")
178
- # #=> #<Money @fractional=10000 @currency="USD">
179
- # Money.from_bigdecimal(BigDecimal.new("100", "EUR")
180
- # #=> #<Money @fractional=10000 @currency="EUR">
181
- # Money.from_bigdecimal(BigDecimal.new("100", "BHD")
182
- # #=> #<Money @fractional=100 @currency="BHD">
183
- #
184
- # @see BigDecimal#to_money
185
- # @see #from_numeric
186
- #
187
30
  def from_bigdecimal(value, currency = Money.default_currency)
188
- currency = Money::Currency.wrap(currency)
189
- amount = value * currency.subunit_to_unit
190
- amount = amount.round unless Money.infinite_precision
191
- new(amount, currency)
31
+ Money.deprecate ".from_bigdecimal is deprecated and will be removed in 6.1.0. Please use the `monetize` gem."
32
+ Monetize.from_bigdecimal(value, currency)
192
33
  end
193
34
 
194
- # Converts a Numeric value into a Money object treating the +value+
195
- # as dollars and converting to corresponding fractional unit,
196
- # according to +currency+ subunit property,
197
- # before instantiating the Money object.
198
- #
199
- # This method relies on various +Money.from_*+ methods
200
- # and tries to forwards the call to the most appropriate method
201
- # in order to reduce computation effort.
202
- # For instance, if +value+ is an Integer, this method calls
203
- # {#from_fixnum} instead of using the default
204
- # {#from_bigdecimal} which adds the overload to converts
205
- # the value into a slower BigDecimal instance.
206
- #
207
- # @param [Numeric] value The money amount, in dollars.
208
- # @param [Currency, String, Symbol] currency The currency format.
209
- #
210
- # @return [Money]
211
- #
212
- # @raise +ArgumentError+ Unless +value+ is a supported type.
213
- #
214
- # @example
215
- # Money.from_numeric(100)
216
- # #=> #<Money @fractional=10000 @currency="USD">
217
- # Money.from_numeric(100.00)
218
- # #=> #<Money @fractional=10000 @currency="USD">
219
- # Money.from_numeric("100")
220
- # #=> ArgumentError
221
- #
222
- # @see Numeric#to_money
223
- # @see #from_fixnum
224
- # @see #from_bigdecimal
225
- #
226
35
  def from_numeric(value, currency = Money.default_currency)
227
- case value
228
- when Fixnum
229
- from_fixnum(value, currency)
230
- when Numeric
231
- from_bigdecimal(BigDecimal.new(value.to_s), currency)
232
- else
233
- raise ArgumentError, "`value' should be a Numeric object"
234
- end
36
+ Money.deprecate ".from_numeric is deprecated and will be removed in 6.1.0. Please use the `monetize` gem."
37
+ Monetize.from_numeric(value, currency)
235
38
  end
236
39
 
237
- # Takes a number string and attempts to massage out the number.
238
- #
239
- # @param [String] input The string containing a potential number.
240
- #
241
- # @return [Integer]
242
- #
243
40
  def extract_cents(input, currency = Money.default_currency)
244
- Money.deprecate ".extract_cents is depreciated and will be remove in 6.1.0. Please write your own parsing methods."
245
- # remove anything that's not a number, potential thousands_separator, or minus sign
246
- num = input.gsub(/[^\d.,'-]/, '')
247
-
248
- # set a boolean flag for if the number is negative or not
249
- negative = num =~ /^-|-$/ ? true : false
250
-
251
- # decimal mark character
252
- decimal_char = currency.decimal_mark
253
-
254
- # if negative, remove the minus sign from the number
255
- # if it's not negative, the hyphen makes the value invalid
256
- if negative
257
- num = num.sub(/^-|-$/, '')
258
- end
259
-
260
- raise ArgumentError, "Invalid currency amount (hyphen)" if num.include?('-')
261
-
262
- #if the number ends with punctuation, just throw it out. If it means decimal,
263
- #it won't hurt anything. If it means a literal period or comma, this will
264
- #save it from being mis-interpreted as a decimal.
265
- num.chop! if num.match(/[\.|,]$/)
266
-
267
- # gather all decimal_marks within the result number
268
- used_delimiters = num.scan(/[^\d]/)
269
-
270
- # determine the number of unique decimal_marks within the number
271
- #
272
- # e.g.
273
- # $1,234,567.89 would return 2 (, and .)
274
- # $125,00 would return 1
275
- # $199 would return 0
276
- # $1 234,567.89 would raise an error (decimal_marks are space, comma, and period)
277
- case used_delimiters.uniq.length
278
- # no decimal_mark or thousands_separator; major (dollars) is the number, and minor (cents) is 0
279
- when 0 then major, minor = num, 0
280
-
281
- # two decimal_marks, so we know the last item in this array is the
282
- # major/minor thousands_separator and the rest are decimal_marks
283
- when 2
284
- thousands_separator, decimal_mark = used_delimiters.uniq
285
-
286
- # remove all thousands_separator, split on the decimal_mark
287
- major, minor = num.gsub(thousands_separator, '').split(decimal_mark)
288
- min = 0 unless min
289
- when 1
290
- # we can't determine if the comma or period is supposed to be a decimal_mark or a thousands_separator
291
- # e.g.
292
- # 1,00 - comma is a thousands_separator
293
- # 1.000 - period is a thousands_separator
294
- # 1,000 - comma is a decimal_mark
295
- # 1,000,000 - comma is a decimal_mark
296
- # 10000,00 - comma is a thousands_separator
297
- # 1000,000 - comma is a thousands_separator
298
-
299
- # assign first decimal_mark for reusability
300
- decimal_mark = used_delimiters.first
301
-
302
- # When we have identified the decimal mark character
303
- if decimal_char == decimal_mark
304
- major, minor = num.split(decimal_char)
305
-
306
- else
307
- # decimal_mark is used as a decimal_mark when there are multiple instances, always
308
- if num.scan(decimal_mark).length > 1 # multiple matches; treat as decimal_mark
309
- major, minor = num.gsub(decimal_mark, ''), 0
310
- else
311
- # ex: 1,000 - 1.0000 - 10001.000
312
- # split number into possible major (dollars) and minor (cents) values
313
- possible_major, possible_minor = num.split(decimal_mark)
314
- possible_major ||= "0"
315
- possible_minor ||= "00"
316
-
317
- # if the minor (cents) length isn't 3, assign major/minor from the possibles
318
- # e.g.
319
- # 1,00 => 1.00
320
- # 1.0000 => 1.00
321
- # 1.2 => 1.20
322
- if possible_minor.length != 3 # thousands_separator
323
- major, minor = possible_major, possible_minor
324
- else
325
- # minor length is three
326
- # let's try to figure out intent of the thousands_separator
327
-
328
- # the major length is greater than three, which means
329
- # the comma or period is used as a thousands_separator
330
- # e.g.
331
- # 1000,000
332
- # 100000,000
333
- if possible_major.length > 3
334
- major, minor = possible_major, possible_minor
335
- else
336
- # number is in format ###{sep}### or ##{sep}### or #{sep}###
337
- # handle as , is sep, . is thousands_separator
338
- if decimal_mark == '.'
339
- major, minor = possible_major, possible_minor
340
- else
341
- major, minor = "#{possible_major}#{possible_minor}", 0
342
- end
343
- end
344
- end
345
- end
346
- end
347
- else
348
- # TODO: ParseError
349
- raise ArgumentError, "Invalid currency amount"
350
- end
351
-
352
- # build the string based on major/minor since decimal_mark/thousands_separator have been removed
353
- # avoiding floating point arithmetic here to ensure accuracy
354
- cents = (major.to_i * currency.subunit_to_unit)
355
- # Because of an bug in JRuby, we can't just call #floor
356
- minor = minor.to_s
357
- minor = if minor.size < currency.decimal_places
358
- (minor + ("0" * currency.decimal_places))[0,currency.decimal_places].to_i
359
- elsif minor.size > currency.decimal_places
360
- if minor[currency.decimal_places,1].to_i >= 5
361
- minor[0,currency.decimal_places].to_i+1
362
- else
363
- minor[0,currency.decimal_places].to_i
364
- end
365
- else
366
- minor.to_i
367
- end
368
-
369
- cents += minor
370
-
371
- # if negative, multiply by -1; otherwise, return positive cents
372
- negative ? cents * -1 : cents
41
+ Money.deprecate ".extract_cents is deprecated and will be removed in 6.1.0. Please use the `monetize` gem."
42
+ Monetize.extract_cents(input, currency)
373
43
  end
374
44
  end
375
45
  end
@@ -0,0 +1,3 @@
1
+ class Money
2
+ VERSION = "6.0.1.beta1"
3
+ end
data/money.gemspec CHANGED
@@ -1,16 +1,20 @@
1
1
  # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "money/version"
5
+
2
6
  Gem::Specification.new do |s|
3
7
  s.name = "money"
4
- s.version = "6.0.0"
8
+ s.version = Money::VERSION
5
9
  s.platform = Gem::Platform::RUBY
6
- s.authors = ["Tobias Luetke", "Hongli Lai", "Jeremy McNevin",
7
- "Shane Emmons", "Simone Carletti"]
8
- s.email = ["semmons99+RubyMoney@gmail.com"]
10
+ s.authors = ["Shane Emmons"]
11
+ s.email = ["shane@emmons.io"]
9
12
  s.homepage = "http://rubymoney.github.com/money"
10
13
  s.summary = "Money and currency exchange support library."
11
14
  s.description = "This library aids one in handling money and different currencies."
15
+ s.license = "MIT"
12
16
 
13
- s.post_install_message = '''
17
+ s.post_install_message = <<MSG
14
18
  Please note the following API changes in Money version 6
15
19
 
16
20
  - Money#amount, Money#dollars methods now return instances of BigDecimal (rather than Float).
@@ -19,21 +23,19 @@ Please read the migration notes at https://github.com/RubyMoney/money#migration-
19
23
  and choose the migration that best suits your application.
20
24
 
21
25
  Test responsibly :-)
22
- '''
23
-
24
- s.required_ruby_version = ">= 1.8.7"
25
-
26
- s.add_dependency "i18n", "~> 0.6.4"
27
-
28
- s.add_development_dependency "rspec", "~> 2.14"
29
- s.add_development_dependency "yard", "~> 0.8"
30
- s.add_development_dependency "kramdown", "~> 1.1"
26
+ MSG
31
27
 
32
- s.license = "MIT"
28
+ s.add_dependency "i18n", "~> 0.6.4"
29
+ s.add_dependency "monetize", "~> 0.1.3"
33
30
 
34
- s.files = Dir.glob("{config,lib,spec}/**/*")
35
- s.files += %w(CHANGELOG.md LICENSE README.md)
36
- s.files += %w(Rakefile money.gemspec)
31
+ s.add_development_dependency "bundler", "~> 1.3"
32
+ s.add_development_dependency "rake"
33
+ s.add_development_dependency "rspec", "~> 2.14"
34
+ s.add_development_dependency "yard", "~> 0.8"
35
+ s.add_development_dependency "kramdown", "~> 1.1"
37
36
 
38
- s.require_path = "lib"
37
+ s.files = `git ls-files`.split($/)
38
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
39
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
40
+ s.require_paths = ["lib"]
39
41
  end