money 6.0.0 → 6.0.1.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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