Class: Exchange::ISO

Inherits:
Object
  • Object
show all
Extended by:
SingleForwardable
Includes:
Singleton
Defined in:
lib/exchange/iso.rb

Overview

This class handles everything that has to do with certified formatting of the different currencies. The standard is stored in the iso4217 YAML file.

Author:

  • Beat Richartz

Since:

  • 0.3

Version:

  • 0.6

Instance Method Summary collapse

Instance Method Details

#assert_currency!(arg) ⇒ Symbol

Asserts a given argument is a currency. Tries to match with a country code if the argument is not a currency

Since:

  • 0.3


77
78
79
# File 'lib/exchange/iso.rb', line 77

def assert_currency! arg
  defines?(arg) ? (country_map[arg] || arg) : raise(Exchange::NoCurrencyError.new("#{arg} is not a currency nor a country code matchable to a currency"))
end

#ceilObject

Use this to ceil a currency amount. This allows us to ceil exactly to the number of minors the currency has in the iso definition

Examples:

Ceil a currency with 2 minors

Exchange::ISO.ceil("4523.456", "usd") #=> #<Bigdecimal 4523.46>

Since:

  • 0.3


153
# File 'lib/exchange/iso.rb', line 153

install_operation :ceil

#country_mapHash

A map of country abbreviations to currency codes. Makes an instantiation of currency codes via a country code possible

Since:

  • 0.3


54
55
56
# File 'lib/exchange/iso.rb', line 54

def country_map
  @country_map ||= symbolize_keys(YAML.load_file(File.join(ROOT_PATH, 'iso4217_country_map.yml')))
end

#currenciesArray

All currencies defined by ISO 4217 as an array of symbols for inclusion testing

Since:

  • 0.3


61
62
63
# File 'lib/exchange/iso.rb', line 61

def currencies
  @currencies  ||= definitions.keys.sort_by(&:to_s)
end

#defines?(currency) ⇒ Boolean

Check if a currency is defined by ISO 4217 standards

Since:

  • 0.3


69
70
71
# File 'lib/exchange/iso.rb', line 69

def defines? currency
  currencies.include?(country_map[currency] ? country_map[currency] : currency)
end

#definitionsHash

The ISO 4217 that have to be loaded. Use this method to get to the definitions They are static, so they can be stored in a class variable without many worries

Since:

  • 0.3


46
47
48
# File 'lib/exchange/iso.rb', line 46

def definitions
  @definitions ||= symbolize_keys(YAML.load_file(File.join(ROOT_PATH, 'iso4217.yml')))
end

#floorObject

Use this to floor a currency amount. This allows us to floor exactly to the number of minors the currency has in the iso definition

Examples:

Floor a currency with 2 minors

Exchange::ISO.floor("4523.456", "usd") #=> #<Bigdecimal 4523.46>

Since:

  • 0.3


162
# File 'lib/exchange/iso.rb', line 162

install_operation :floor

#instantiate(amount, currency) ⇒ BigDecimal

Note:

Reinstantiation is not needed in case the amount is already a big decimal. In this case, the maximum precision is already given.

Use this to instantiate a currency amount. For one, it is important that we use BigDecimal here so nothing gets lost because of floating point errors. For the other, This allows us to set the precision exactly according to the iso definition

Examples:

instantiate a currency from a string

Exchange::ISO.instantiate("4523", "usd") #=> #<Bigdecimal 4523.00>

Since:

  • 0.3


90
91
92
93
94
95
96
# File 'lib/exchange/iso.rb', line 90

def instantiate amount, currency
  if amount.is_a?(BigDecimal)
    amount
  else
    BigDecimal.new(amount.to_s, precision_for(amount, currency))
  end
end

#roundObject

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

Examples:

Round a currency with 2 minors

Exchange::ISO.round("4523.456", "usd") #=> #<Bigdecimal 4523.46>

Since:

  • 0.3


144
# File 'lib/exchange/iso.rb', line 144

install_operation :round

#stringify(amount, currency, opts = {}) ⇒ String

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.

Examples:

Convert a currency to a string

Exchange::ISO.stringify(49.567, :usd) #=> "USD 49.57"

Convert a currency without minor to a string

Exchange::ISO.stringif(45, :jpy) #=> "JPY 45"

Convert a currency with a three decimal minor to a string

Exchange::ISO.stringif(34.34, :omr) #=> "OMR 34.340"

Convert a currency to a string without the currency

Exchange::ISO.stringif(34.34, :omr, :amount_only => true) #=> "34.340"

Options Hash (opts):

  • :format (Boolean)

    The format to put the string out in: :amount for only the amount, :symbol for a string with a currency symbol

Since:

  • 0.3


114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/exchange/iso.rb', line 114

def stringify amount, currency, opts={}
  definition    = definitions[currency]
  separators    = definition[:separators] || {}
  format        = "%.#{definition[:minor_unit]}f"
  string        = format % amount
  major, minor  = string.split('.')

  major.gsub!(/(\d)(?=(\d\d\d)+(?!\d))/) { $1 + separators[:major] } if separators[:major] && opts[:format] != :plain
  
  string      = minor ? major + (opts[:format] == :plain || !separators[:minor] ? '.' : separators[:minor]) + minor : major
  pre         = [[:amount, :plain].include?(opts[:format]) && '', opts[:format] == :symbol && definition[:symbol], currency.to_s.upcase + ' '].detect{|a| a.is_a?(String)}
  
  "#{pre}#{string}"
end

#symbol(currency) ⇒ String, NilClass

Returns the symbol for a given currency. Returns nil if no symbol is present

Since:

  • 0.3


133
134
135
# File 'lib/exchange/iso.rb', line 133

def symbol currency
  definitions[currency][:symbol]
end