lib/exchange/iso.rb in exchange-0.12.0 vs lib/exchange/iso.rb in exchange-1.0.0

- old
+ new

@@ -1,5 +1,6 @@ +# -*- encoding : utf-8 -*- require 'singleton' require 'forwardable' require 'yaml' module Exchange @@ -20,13 +21,20 @@ # @private # @macro [attach] install_operations def install_operation op self.class_eval <<-EOV - def #{op}(amount, currency, precision=nil) + def #{op}(amount, currency, precision=nil, opts={}) minor = definitions[currency][:minor_unit] - (amount.is_a?(BigDecimal) ? amount : BigDecimal.new(amount.to_s, precision_for(amount, currency))).#{op}(precision || minor) + money = amount.is_a?(BigDecimal) ? amount : BigDecimal.new(amount.to_s, precision_for(amount, currency)) + if opts[:psych] && minor > 0 + money.#{op}(0) - BigDecimal.new((1.0/(10**minor)).to_s) + elsif opts[:psych] + (((money.#{op}(0) / BigDecimal.new("10.0")).#{op}(0)) - BigDecimal.new("0.1")) * BigDecimal.new("10") + else + money.#{op}(precision || minor) + end end EOV end end @@ -90,11 +98,11 @@ # Converts the currency to a string in ISO 4217 standardized format, either with or without the currency. This leaves you # with no worries how to display the currency. # @param [BigDecimal, Fixed, Float] amount The amount of currency you want to stringify # @param [String, Symbol] currency The currency you want to stringify # @param [Hash] opts The options for formatting - # @option opts [Boolean] :amount_only Whether you want to have the currency in the string or not + # @option opts [Boolean] :format The format to put the string out in: :amount for only the amount, :symbol for a string with a currency symbol # @return [String] The formatted string # @example Convert a currency to a string # Exchange::ISO.stringify(49.567, :usd) #=> "USD 49.57" # @example Convert a currency without minor to a string # Exchange::ISO.stringif(45, :jpy) #=> "JPY 45" @@ -102,13 +110,26 @@ # Exchange::ISO.stringif(34.34, :omr) #=> "OMR 34.340" # @example Convert a currency to a string without the currency # Exchange::ISO.stringif(34.34, :omr, :amount_only => true) #=> "34.340" # def stringify(amount, currency, opts={}) - format = "%.#{definitions[currency][:minor_unit]}f" - pre = [opts[:amount_only] && '', opts[:symbol] && (definitions[currency][:symbol] || currency.to_s.upcase), currency.to_s.upcase + ' '].detect{|a| a.is_a?(String)} - "#{pre}#{format % amount}" + definition = definitions[currency] + separators = definition[:separators] || {} + format = "%.#{definition[:minor_unit]}f" + string = format % amount + major, minor = string.split('.') + + if separators[:major] + major.reverse! + major.gsub!(/(\d{3})(?=.)/) { $1 + separators[:major] } + major.reverse! + end + + string = minor ? major + (separators[:minor] || '.') + minor : major + pre = [opts[:format] == :amount && '', opts[:format] == :symbol && definition[:symbol], currency.to_s.upcase + ' '].detect{|a| a.is_a?(String)} + + "#{pre}#{string}" end # Use this to round a currency amount. This allows us to round exactly to the number of minors the currency has in the # iso definition # @param [BigDecimal, Fixed, Float, String] amount The amount of money you want to round @@ -146,16 +167,11 @@ # def symbolize_keys hsh new_hsh = Hash.new hsh.each_pair do |k,v| - if v.is_a?(Hash) - v.keys.each do |key| - v[key.to_sym] = v.delete(key) - end - end - + v = symbolize_keys v if v.is_a?(Hash) new_hsh[k.downcase.to_sym] = v end new_hsh end @@ -170,6 +186,6 @@ given_major_precision + [defined_minor_precision, given_minor_precision].max end end -end \ No newline at end of file +end