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

Parameters:

  • arg (Symbol, String)

    The argument to assert

Returns:

  • (Symbol)

    The matching currency as a symbol

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>

Parameters:

  • amount (BigDecimal, Fixed, Float, String)

    The amount of money you want to ceil

  • currency (String, Symbol)

    The currency you want to ceil the money in

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

Returns:

  • (Hash)

    The ISO3166 (1 and 2) country codes matched to a currency

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

Returns:

  • (Array)

    An Array of currency symbols

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

Parameters:

  • currency (Symbol)

    the downcased currency symbol

Returns:

  • (Boolean)

    true if the symbol matches a currency, false if not

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

Returns:

  • (Hash)

    The iso4217 Definitions with the currency code as keys

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>

Parameters:

  • amount (BigDecimal, Fixed, Float, String)

    The amount of money you want to floor

  • currency (String, Symbol)

    The currency you want to floor the money in

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>

Parameters:

  • amount (BigDecimal, Fixed, Float, String)

    The amount of money you want to instantiate

  • currency (String, Symbol)

    The currency you want to instantiate the money in

Returns:

  • (BigDecimal)

    The instantiated currency

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>

Parameters:

  • amount (BigDecimal, Fixed, Float, String)

    The amount of money you want to round

  • currency (String, Symbol)

    The currency you want to round the money in

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"

Parameters:

  • amount (BigDecimal, Fixed, Float)

    The amount of currency you want to stringify

  • currency (String, Symbol)

    The currency you want to stringify

  • opts (Hash) (defaults to: {})

    The options for formatting

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

Returns:

  • (String)

    The formatted string

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

Parameters:

  • currency

    The currency to return the symbol for

Returns:

  • (String, NilClass)

    The symbol or nil

Since:

  • 0.3


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

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