module Smerp module Common module CurrencyConversion class CurrencyConversionError < StandardError; end class ConversionContext include TR::CondUtils attr_accessor :from_currency, :to_currency def initialize(value) @value = value end def from(bc) @from_currency = bc self end def to(tc) @to_currency = tc @from_currency = CConverter.instance.home_currency if is_empty?(@from_currency) if CConverter.instance.is_home_currency?(@from_currency) rate = CConverter.instance.rate(@to_currency) @value * rate elsif CConverter.instance.is_home_currency?(@to_currency) rate = CConverter.instance.rate(@from_currency) @value / rate else raise CurrencyConversionError, "From currency '#{@from_currency}' rate is not defined" if not CConverter.instance.is_rate_defined?(@from_currency) raise CurrencyConversionError, "To currency '#{@to_currency}' rate is not defined" if not CConverter.instance.is_rate_defined?(@to_currency) # both from and to is not home currency # use local currency as intermediary hc = CConverter.instance.home_currency fcc = ConversionContext.new(@value) mv = fcc.from(@from_currency).to(hc) tcc = ConversionContext.new(mv) tcc.from(hc).to(@to_currency) end end end class CConverter include Singleton include TR::CondUtils attr_accessor :home_currency def conversion=(val) raise CurrencyConversionError, "Home currency must set first" if is_empty?(@home_currency) raise CurrencyConversionError, "Hash is expected" if not val.is_a?(Hash) val.each do |k,v| v = 1 if is_empty?(v) rate_table[k] = v.to_f end end def rate(currency) rate = rate_table[currency] rate = 1.0 if is_empty?(rate) rate end def is_rate_defined?(currency) not_empty?(rate_table[currency]) end def set_rate_table(hash) @rate = hash if not hash.nil? end def is_home_currency?(sym) @home_currency == sym end private def rate_table if @rate.nil? @rate = {} end @rate end end # Cconverter module CurrencyUtils def cconvert ConversionContext.new(self.to_f) end def to_other_currency(country) self * CurrencyConversion::CConverter.instance.rate(country) end def to_home_currency(country) self / CurrencyConversion::CConverter.instance.rate(country) end end end end end class Integer include Smerp::Common::CurrencyConversion::CurrencyUtils end class Float include Smerp::Common::CurrencyConversion::CurrencyUtils end