class Attio::Util::CurrencyFormatter

Utility class for formatting currency amounts

def decimal_places_for(currency_code)

Returns:
  • (Integer) - Number of decimal places

Parameters:
  • currency_code (String) -- The ISO 4217 currency code
def decimal_places_for(currency_code)
  currency_code = currency_code.to_s.upcase
  NO_DECIMAL_CURRENCIES.include?(currency_code) ? 0 : 2
end

def format(amount, currency_code = "USD", options = {})

Returns:
  • (String) - The formatted currency string

Options Hash: (**options)
  • :decimal_separator (String) -- Character for decimal separation (default: ".")
  • :thousands_separator (String) -- Character for thousands separation (default: ",")
  • :decimal_places (Integer) -- Number of decimal places (auto-determined by default)

Parameters:
  • options (Hash) -- Formatting options
  • currency_code (String) -- The ISO 4217 currency code
  • amount (Numeric) -- The amount to format
def format(amount, currency_code = "USD", options = {})
  currency_code = currency_code.to_s.upcase
  symbol = symbol_for(currency_code)
  
  # Determine decimal places
  decimal_places = options[:decimal_places] || decimal_places_for(currency_code)
  thousands_sep = options[:thousands_separator] || ","
  decimal_sep = options[:decimal_separator] || "."
  
  # Handle zero amounts
  if amount == 0
    if decimal_places > 0
      return "#{symbol}0#{decimal_sep}#{"0" * decimal_places}"
    else
      return "#{symbol}0"
    end
  end
  
  # Handle negative amounts
  negative = amount < 0
  abs_amount = amount.abs
  
  # Format the amount
  if decimal_places == 0
    # No decimal places
    formatted = format_with_separators(abs_amount.to_i, thousands_sep)
    formatted = "-#{formatted}" if negative
    "#{symbol}#{formatted}"
  else
    # With decimal places
    whole = abs_amount.to_i
    decimal = ((abs_amount - whole) * (10 ** decimal_places)).round
    formatted_whole = format_with_separators(whole, thousands_sep)
    formatted_whole = "-#{formatted_whole}" if negative
    formatted_decimal = decimal.to_s.rjust(decimal_places, "0")
    "#{symbol}#{formatted_whole}#{decimal_sep}#{formatted_decimal}"
  end
end

def format_number(amount, currency_code = "USD", options = {})

Returns:
  • (String) - The formatted number without currency symbol

Parameters:
  • options (Hash) -- Formatting options (same as format method)
  • currency_code (String) -- The ISO 4217 currency code
  • amount (Numeric) -- The amount to format
def format_number(amount, currency_code = "USD", options = {})
  result = format(amount, currency_code, options)
  symbol = symbol_for(currency_code)
  result.sub(/^#{Regexp.escape(symbol)}/, "")
end

def format_with_separators(number, separator)

Returns:
  • (String) - The formatted number

Parameters:
  • separator (String) -- The separator character
  • number (Integer) -- The number to format
def format_with_separators(number, separator)
  number.to_s.reverse.gsub(/(\d{3})(?=\d)/, "\\1#{separator}").reverse
end

def symbol_for(currency_code)

Returns:
  • (String) - The currency symbol or code with space

Parameters:
  • currency_code (String) -- The ISO 4217 currency code
def symbol_for(currency_code)
  currency_code = currency_code.to_s.upcase
  CURRENCY_SYMBOLS[currency_code] || "#{currency_code} "
end

def uses_decimals?(currency_code)

Returns:
  • (Boolean) - True if the currency uses decimals

Parameters:
  • currency_code (String) -- The ISO 4217 currency code
def uses_decimals?(currency_code)
  decimal_places_for(currency_code) > 0
end