@@ -51,11 +51,7 @@ def parse
5151
5252 negative , num = extract_sign ( num )
5353
54- num . chop! if num =~ /[\. |,]$/
55-
56- major , minor = extract_major_minor ( num )
57-
58- amount = to_big_decimal ( [ major , minor ] . join ( DEFAULT_DECIMAL_MARK ) )
54+ amount = to_big_decimal ( normalize_number ( num ) )
5955 amount = apply_multiplier ( multiplier_exp , amount )
6056 amount = apply_sign ( negative , amount )
6157
@@ -64,6 +60,12 @@ def parse
6460
6561 private
6662
63+ def normalize_number ( num )
64+ clean_num = num . sub ( /[\. |,]$/ , "" )
65+
66+ extract_major_minor ( clean_num ) . join ( DEFAULT_DECIMAL_MARK )
67+ end
68+
6769 def to_big_decimal ( value )
6870 BigDecimal ( value )
6971 rescue ::ArgumentError => err
@@ -108,64 +110,65 @@ def compute_currency
108110 CURRENCY_SYMBOLS [ match . to_s ] if match
109111 end
110112
113+ def remove_separator ( num , separator )
114+ num . gsub ( separator , "" )
115+ end
116+
111117 def extract_major_minor ( num )
112118 used_delimiters = num . scan ( /[^\d ]/ ) . uniq
113119
114120 case used_delimiters . length
115121 when 0
116122 [ num , DEFAULT_MINOR ]
117- when 2
118- thousands_separator , decimal_mark = used_delimiters
119- split_major_minor ( num . gsub ( thousands_separator , '' ) , decimal_mark )
120123 when 1
121124 extract_major_minor_with_single_delimiter ( num , used_delimiters . first )
125+ when 2
126+ thousands_separator , decimal_mark = used_delimiters
127+ num = remove_separator ( num , thousands_separator )
128+
129+ split_major_minor ( num , decimal_mark )
122130 else
123131 fail ParseError , 'Invalid amount'
124132 end
125133 end
126134
127- def minor_has_correct_dp_for_currency_subunit ?( minor )
128- minor . length == currency . subunit_to_unit . to_s . length - 1
135+ def minor_has_correct_decimal_places_for_currency ?( minor )
136+ minor . length == currency . decimal_places
129137 end
130138
131139 def extract_major_minor_with_single_delimiter ( num , delimiter )
132140 if expect_whole_subunits?
133- _possible_major , possible_minor = split_major_minor ( num , delimiter )
134- if minor_has_correct_dp_for_currency_subunit? ( possible_minor )
135- split_major_minor ( num , delimiter )
136- else
137- extract_major_minor_with_tentative_delimiter ( num , delimiter )
138- end
139- else
140- if delimiter == currency . decimal_mark
141- split_major_minor ( num , delimiter )
142- elsif Monetize . enforce_currency_delimiters && delimiter == currency . thousands_separator
143- [ num . gsub ( delimiter , '' ) , DEFAULT_MINOR ]
144- else
145- extract_major_minor_with_tentative_delimiter ( num , delimiter )
141+ possible_major , possible_minor = split_major_minor ( num , delimiter )
142+
143+ if minor_has_correct_decimal_places_for_currency? ( possible_minor )
144+ return [ possible_major , possible_minor ]
146145 end
146+ elsif delimiter == currency . decimal_mark
147+ return split_major_minor ( num , delimiter )
148+ elsif Monetize . enforce_currency_delimiters && delimiter == currency . thousands_separator
149+ return [ remove_separator ( num , delimiter ) , DEFAULT_MINOR ]
147150 end
151+
152+ extract_major_minor_with_tentative_delimiter ( num , delimiter )
148153 end
149154
150155 def extract_major_minor_with_tentative_delimiter ( num , delimiter )
151156 if num . scan ( delimiter ) . length > 1
152157 # Multiple matches; treat as thousands separator
153- [ num . gsub ( delimiter , '' ) , DEFAULT_MINOR ]
154- else
155- possible_major , possible_minor = split_major_minor ( num , delimiter )
158+ return [ remove_separator ( num , delimiter ) , DEFAULT_MINOR ]
159+ end
156160
157- # Doesn't look like thousands separator
158- is_decimal_mark = possible_minor . length != 3 ||
159- possible_major . length > 3 ||
160- possible_major . to_i == 0 ||
161- ( !expect_whole_subunits? && delimiter == '.' )
161+ possible_major , possible_minor = split_major_minor ( num , delimiter )
162162
163- if is_decimal_mark
164- [ possible_major , possible_minor ]
165- else
166- [ "#{ possible_major } #{ possible_minor } " , DEFAULT_MINOR ]
167- end
168- end
163+ # Doesn't look like thousands separator
164+ is_decimal_mark = possible_minor . length != 3 ||
165+ possible_major . length > 3 ||
166+ possible_major . to_i == 0 ||
167+ ( !expect_whole_subunits? && delimiter == "." )
168+
169+ return [ possible_major , possible_minor ] if is_decimal_mark
170+
171+ [ "#{ possible_major } #{ possible_minor } " , DEFAULT_MINOR ]
169172 end
170173
171174 def extract_multiplier
0 commit comments