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