Module: FormattedMoney

Defined in:
lib/formatted-money.rb

Overview

Author:

  • Josef Strzibny

Defined Under Namespace

Modules: American, European Classes: NumberNotInFloatFormat, NumberNotInIntegerFormat

Constant Summary collapse

@@omit_cents =
false
@@round =
true
@@delimiter =
FormattedMoney::European::DELIMITER
@@cents_separator =
FormattedMoney::European::CENTS_SEPARATOR
@@escape_chars =
['.', '^', '$', '*']

Class Method Summary collapse

Class Method Details

.add_zero_cents(n) ⇒ Object



131
132
133
# File 'lib/formatted-money.rb', line 131

def self.add_zero_cents(n)
  Integer(sprintf('%d00', n))
end

.amount(amount, omit_cents = @@omit_cents, delimiter = @@delimiter, cents_separator = @@cents_separator) ⇒ String

Format Integer to float number with cents

Returns:

  • (String)

    amount in human-readable format



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/formatted-money.rb', line 68

def self.amount(amount, omit_cents = @@omit_cents, delimiter = @@delimiter, cents_separator = @@cents_separator)
  check_integer(amount) unless amount.is_a? Integer

  amount = amount.to_s
  cents = amount[-2, 2]
  cents ||= '00'
  units = amount[0..-3]

  if units.empty?
    return '0' if omit_cents

    return String('0' + cents_separator + cents)
  end

  return String(number_with_delimiter(units, delimiter)) if omit_cents

  String(number_with_delimiter(units, delimiter) + cents_separator + cents)
end

.cents(amount, round = @@round, delimiter = @@delimiter, cents_separator = @@cents_separator) ⇒ Integer

Format the float-formatted input to Integer for saving or for calculation

Returns:

  • (Integer)

    money as cents



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/formatted-money.rb', line 89

def self.cents(amount, round = @@round, delimiter = @@delimiter, cents_separator = @@cents_separator)
  delimiter_regex = self.separator_regex(delimiter)
  cents_separator_regex = self.separator_regex(cents_separator)

  # Only zeros
  return 0 if self.only_zeros?(amount, delimiter_regex, cents_separator_regex)

  # Already integer
  return add_zero_cents amount if amount.is_a? Integer

  check_float(amount)
  if amount[0] == '-'
    amount[0] = ''
    negative = true
  else
    negative = false
  end

  # No cents
  amount = amount.delete(delimiter)
  return add_zero_cents amount if /^\d+$/.match amount

  # With cents
  units = amount.gsub(/#{cents_separator_regex}\d+/, '')
  cents = amount.gsub(/#{units}#{cents_separator_regex}/, '')

  # Round the last cent
  unless cents[2].nil? && round
    last_cent = cents[1]

    last_cent = Integer(last_cent) + 1 if Integer(cents[2]) >= 5

    return Integer(units + cents[0] + String(last_cent))
  end

  if negative
    Integer('-' + units + cents)
  else
    Integer(units + cents)
  end
end

.cents_separator=(cents_separator) ⇒ Object



62
63
64
# File 'lib/formatted-money.rb', line 62

def self.cents_separator=(cents_separator)
  @@cents_separator = cents_separator
end

.check_float(n) ⇒ Object

Check if the given number is formatted as a float - numbers should contain only digits, commas or dots. Only numbers like 1.000.000.000,2056 or 2,150.3 are accepted



138
139
140
141
142
# File 'lib/formatted-money.rb', line 138

def self.check_float(n)
  unless /^(-){0,1}[\d\.\,]*$/.match(n.to_s)
    throw NumberNotInFloatFormat, 'Float numbers can only be made out of digits, commas (,) or dots (.). Dash (-) is accepted at the beginning for negative numbers'
  end
end

.check_integer(n) ⇒ Object



144
145
146
147
148
# File 'lib/formatted-money.rb', line 144

def self.check_integer(n)
  unless /^(-){0,1}\d*$/.match(n.to_s)
    throw NumberNotInIntegerFormat, 'Integer numbers can only be made out of digits. Dash (-) is accepted at the beginning for negative numbers'
  end
end

.delimiter=(delimiter) ⇒ Object



58
59
60
# File 'lib/formatted-money.rb', line 58

def self.delimiter=(delimiter)
  @@delimiter = delimiter
end

.escape_chars=(chars) ⇒ Object



46
47
48
# File 'lib/formatted-money.rb', line 46

def self.escape_chars=(chars)
  @@escape_chars = chars
end

.number_with_delimiter(number, delimiter) ⇒ Object



150
151
152
# File 'lib/formatted-money.rb', line 150

def self.number_with_delimiter(number, delimiter)
  number.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
end

.omit_cents=(bool) ⇒ Object



50
51
52
# File 'lib/formatted-money.rb', line 50

def self.omit_cents=(bool)
  @@omit_cents = bool
end

.only_zeros?(number, delimiter, cents_separator) ⇒ Boolean

Returns:

  • (Boolean)


167
168
169
170
171
# File 'lib/formatted-money.rb', line 167

def self.only_zeros?(number, delimiter, cents_separator)
  return false unless /^[0#{delimiter}#{cents_separator}]*$/.match(number)

  true
end

.round=(bool) ⇒ Object



54
55
56
# File 'lib/formatted-money.rb', line 54

def self.round=(bool)
  @@round = bool
end

.separator_regex(separator) ⇒ Object



161
162
163
164
165
# File 'lib/formatted-money.rb', line 161

def self.separator_regex(separator)
  return '\\' + "#{separator}" if @@escape_chars.include? separator

  "#{separator}"
end

.trim_leading_zeros(number) ⇒ Object



154
155
156
157
158
159
# File 'lib/formatted-money.rb', line 154

def self.trim_leading_zeros(number)
  string = number.to_s.gsub(/^[0]*(.*)/, '\\1')
  string = '0' if string.empty?

  string
end