money_helper 0.0.4 → 0.0.5

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.
Files changed (3) hide show
  1. checksums.yaml +8 -8
  2. data/lib/money_helper.rb +3 -200
  3. metadata +4 -4
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NjA5MGU2NTI2YjJiNzZhMWFmZjFmYjMwNjI5ZjNmMzc1NzgyM2E1OQ==
4
+ MWZjMTgyNzQwNTY2ZjQzOTEzNzQxYTQyMmIxYjk1Yjc5ZjU2OWQ5Yg==
5
5
  data.tar.gz: !binary |-
6
- Y2M0OGZhYjlhYjZiZDc4NGRlN2ZhM2YxZjAzYjY4N2ZiYzU5MDNmMQ==
6
+ ZWRhNjgyOTJiN2ViZjdkMTExMDkwZGJmYTU2ZTI4NDc1NjY0NzczMQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NTUxMWNlNTZiNjc1ZWJkZWYyODc5MTMzMzRiMDI0NWRjNGRmZDNmN2Y4MTY1
10
- MmY5M2QxZWM4ZTdhZjQ2MmVkYzk5ZWVkMzAwNzdlNGEyOGFlYmYyZjNlODlh
11
- NWM4OWY4MTlmMDMwYjI4MDIxYTNjZjg4MWI5N2I4ODM4NjcwNjc=
9
+ OThjNWYzNjBmNjA5MGJjNjEzNWE3ZGJkOTBiMTdiZWVlZmQ1ODkyZGI0OTFk
10
+ Yzg5YTdkZjA2YjY1NGMwODNmYTIzMDIyOGRmNDdmMDMxNTBiZWNiNWNjYmVi
11
+ N2MyNjNlZThlYTEzOGQxOTg3MDAxNWI0N2Q5NjQwNWU1MGZhOTQ=
12
12
  data.tar.gz: !binary |-
13
- ZDhiNDFmMmJkMzhkMzdmOGMwNDZmZTdiNTRmMTY3MzI3M2RhMzhlYTM5MjUx
14
- OWQzYmU5ZjM4NjQ2YTg0NjZkM2UzY2Q2MTczZDg0NTkyM2NjMGRkNGFiZTgw
15
- ODkwMDM3NjQ2N2U5ZjhiYTRlYjY5ZDM4YWUxMDk1YmQ4MTgwYzQ=
13
+ MjUyMTE5NzY0MjA1NWY3MDVhNmYwNDk5NDg4YzRkZTBjMTgxOGE2MmIyOGUx
14
+ NzNhMWZmNmJkOTEzZTc2MTViOTBlNmMzMmYxMjJmYTQ0NTc1NDRkZTYwODc1
15
+ M2M5MWU1ZmExYTllMmQ2YzlhNDU1MGIwNDIyZWQxNDkzZWRmM2M=
data/lib/money_helper.rb CHANGED
@@ -27,215 +27,18 @@ module MoneyHelper
27
27
  def self.money_to_text(amount, currency, number_only = false)
28
28
  return nil unless amount.present?
29
29
  currency = "USD" if currency.blank?
30
+ valid_currency = code_valid?(currency) ? currency : "USD"
30
31
  symbol = symbol_for_code(currency)
31
32
  include_symbol = !number_only && symbol.present? && OK_SYMBOLS.include?(symbol)
32
- valid_currency = currency if code_valid?(currency)
33
+ subunit_factor = Money::Currency.new(valid_currency).subunit_to_unit
33
34
  (number_only || SYMBOL_ONLY.include?(currency) ? "" : currency + " ") +
34
- parse_money(amount.ceil, valid_currency).format({
35
+ Money.new(amount*subunit_factor.ceil, valid_currency).format({
35
36
  no_cents: true,
36
37
  symbol_position: :before,
37
38
  symbol: include_symbol
38
39
  }).delete(' ')
39
40
  end
40
41
 
41
- # Parses the current string and converts it to a +Money+ object.
42
- # Excess characters will be discarded.
43
- #
44
- # @param [String, #to_s] input The input to parse.
45
- # @param [Currency, String, Symbol] currency The currency format.
46
- # The currency to set the resulting +Money+ object to.
47
- #
48
- # @return [Money]
49
- #
50
- # @raise [ArgumentError] If any +currency+ is supplied and
51
- # given value doesn't match the one extracted from
52
- # the +input+ string.
53
- #
54
- # @example
55
- # '100'.to_money #=> #<Money @fractional=10000>
56
- # '100.37'.to_money #=> #<Money @fractional=10037>
57
- # '100 USD'.to_money #=> #<Money @fractional=10000, @currency=#<Money::Currency id: usd>>
58
- # 'USD 100'.to_money #=> #<Money @fractional=10000, @currency=#<Money::Currency id: usd>>
59
- # '$100 USD'.to_money #=> #<Money @fractional=10000, @currency=#<Money::Currency id: usd>>
60
- # 'hello 2000 world'.to_money #=> #<Money @fractional=200000 @currency=#<Money::Currency id: usd>>
61
- #
62
- # @example Mismatching currencies
63
- # 'USD 2000'.to_money("EUR") #=> ArgumentError
64
- #
65
- # @see #from_string
66
- #
67
- def self.parse_money(input, currency = nil)
68
- i = input.to_s.strip
69
-
70
- # raise Money::Currency.table.collect{|c| c[1][:symbol]}.inspect
71
-
72
- # Check the first character for a currency symbol, alternatively get it
73
- # from the stated currency string
74
- c = if Money.assume_from_symbol && i =~ /^(\$|€|£)/
75
- case i
76
- when /^\$/ then "USD"
77
- when /^€/ then "EUR"
78
- when /^£/ then "GBP"
79
- end
80
- else
81
- i[/[A-Z]{2,3}/]
82
- end
83
-
84
- # check that currency passed and embedded currency are the same,
85
- # and negotiate the final currency
86
- if currency.nil? and c.nil?
87
- currency = Money.default_currency
88
- elsif currency.nil?
89
- currency = c
90
- elsif c.nil?
91
- currency = currency
92
- elsif currency != c
93
- # TODO: ParseError
94
- raise ArgumentError, "Mismatching Currencies"
95
- end
96
- currency = Money::Currency.wrap(currency)
97
-
98
- fractional = extract_cents(i, currency)
99
- Money.new(fractional, currency)
100
- end
101
-
102
- # Takes a number string and attempts to massage out the number.
103
- #
104
- # @param [String] input The string containing a potential number.
105
- #
106
- # @return [Integer]
107
- #
108
- def self.extract_cents(input, currency = Money.default_currency)
109
- # remove anything that's not a number, potential thousands_separator, or minus sign
110
- num = input.gsub(/[^\d.,'-]/, '')
111
-
112
- # set a boolean flag for if the number is negative or not
113
- negative = num =~ /^-|-$/ ? true : false
114
-
115
- # decimal mark character
116
- decimal_char = currency.decimal_mark
117
-
118
- # if negative, remove the minus sign from the number
119
- # if it's not negative, the hyphen makes the value invalid
120
- if negative
121
- num = num.sub(/^-|-$/, '')
122
- end
123
-
124
- raise ArgumentError, "Invalid currency amount (hyphen)" if num.include?('-')
125
-
126
- #if the number ends with punctuation, just throw it out. If it means decimal,
127
- #it won't hurt anything. If it means a literal period or comma, this will
128
- #save it from being mis-interpreted as a decimal.
129
- num.chop! if num.match(/[\.|,]$/)
130
-
131
- # gather all decimal_marks within the result number
132
- used_delimiters = num.scan(/[^\d]/)
133
-
134
- # determine the number of unique decimal_marks within the number
135
- #
136
- # e.g.
137
- # $1,234,567.89 would return 2 (, and .)
138
- # $125,00 would return 1
139
- # $199 would return 0
140
- # $1 234,567.89 would raise an error (decimal_marks are space, comma, and period)
141
- case used_delimiters.uniq.length
142
- # no decimal_mark or thousands_separator; major (dollars) is the number, and minor (cents) is 0
143
- when 0 then major, minor = num, 0
144
-
145
- # two decimal_marks, so we know the last item in this array is the
146
- # major/minor thousands_separator and the rest are decimal_marks
147
- when 2
148
- thousands_separator, decimal_mark = used_delimiters.uniq
149
-
150
- # remove all thousands_separator, split on the decimal_mark
151
- major, minor = num.gsub(thousands_separator, '').split(decimal_mark)
152
- min = 0 unless min
153
- when 1
154
- # we can't determine if the comma or period is supposed to be a decimal_mark or a thousands_separator
155
- # e.g.
156
- # 1,00 - comma is a thousands_separator
157
- # 1.000 - period is a thousands_separator
158
- # 1,000 - comma is a decimal_mark
159
- # 1,000,000 - comma is a decimal_mark
160
- # 10000,00 - comma is a thousands_separator
161
- # 1000,000 - comma is a thousands_separator
162
-
163
- # assign first decimal_mark for reusability
164
- decimal_mark = used_delimiters.first
165
-
166
- # When we have identified the decimal mark character
167
- if decimal_char == decimal_mark
168
- major, minor = num.split(decimal_char)
169
-
170
- else
171
- # decimal_mark is used as a decimal_mark when there are multiple instances, always
172
- if num.scan(decimal_mark).length > 1 # multiple matches; treat as decimal_mark
173
- major, minor = num.gsub(decimal_mark, ''), 0
174
- else
175
- # ex: 1,000 - 1.0000 - 10001.000
176
- # split number into possible major (dollars) and minor (cents) values
177
- possible_major, possible_minor = num.split(decimal_mark)
178
- possible_major ||= "0"
179
- possible_minor ||= "00"
180
-
181
- # if the minor (cents) length isn't 3, assign major/minor from the possibles
182
- # e.g.
183
- # 1,00 => 1.00
184
- # 1.0000 => 1.00
185
- # 1.2 => 1.20
186
- if possible_minor.length != 3 # thousands_separator
187
- major, minor = possible_major, possible_minor
188
- else
189
- # minor length is three
190
- # let's try to figure out intent of the thousands_separator
191
-
192
- # the major length is greater than three, which means
193
- # the comma or period is used as a thousands_separator
194
- # e.g.
195
- # 1000,000
196
- # 100000,000
197
- if possible_major.length > 3
198
- major, minor = possible_major, possible_minor
199
- else
200
- # number is in format ###{sep}### or ##{sep}### or #{sep}###
201
- # handle as , is sep, . is thousands_separator
202
- if decimal_mark == '.'
203
- major, minor = possible_major, possible_minor
204
- else
205
- major, minor = "#{possible_major}#{possible_minor}", 0
206
- end
207
- end
208
- end
209
- end
210
- end
211
- else
212
- # TODO: ParseError
213
- raise ArgumentError, "Invalid currency amount"
214
- end
215
-
216
- # build the string based on major/minor since decimal_mark/thousands_separator have been removed
217
- # avoiding floating point arithmetic here to ensure accuracy
218
- cents = (major.to_i * currency.subunit_to_unit)
219
- # Because of an bug in JRuby, we can't just call #floor
220
- minor = minor.to_s
221
- minor = if minor.size < currency.decimal_places
222
- (minor + ("0" * currency.decimal_places))[0,currency.decimal_places].to_i
223
- elsif minor.size > currency.decimal_places
224
- if minor[currency.decimal_places,1].to_i >= 5
225
- minor[0,currency.decimal_places].to_i+1
226
- else
227
- minor[0,currency.decimal_places].to_i
228
- end
229
- else
230
- minor.to_i
231
- end
232
-
233
- cents += minor
234
-
235
- # if negative, multiply by -1; otherwise, return positive cents
236
- negative ? cents * -1 : cents
237
- end
238
-
239
42
  ##
240
43
  # Formats a low and high amount in the given currency into a price string
241
44
  #
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: money_helper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sahil Yakhmi
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-01-08 00:00:00.000000000 Z
12
+ date: 2014-04-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: money
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - ! '>='
19
19
  - !ruby/object:Gem::Version
20
- version: '5.1'
20
+ version: '6.0'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - ! '>='
26
26
  - !ruby/object:Gem::Version
27
- version: '5.1'
27
+ version: '6.0'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: activesupport
30
30
  requirement: !ruby/object:Gem::Requirement