Class: SpookAndPuff::Money

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/spook_and_puff/money.rb

Overview

The money class represents monetary values with a precision of up to seven digits. When used as part of a comparison or mathmatical operation it always ensures the other operand is coerced into a BigDecimal. This ensures the precision is maintained.

Constant Summary collapse

NUMBER_OF_CENTS =
100.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value) ⇒ Object

Initializes the money class from a BigDecimal instance.

Parameters:

Raises:

  • TypeError



24
25
26
27
28
29
30
31
# File 'lib/spook_and_puff/money.rb', line 24

def initialize(value)
  @raw = case value
  when SpookAndPuff::Money then value.raw
  when BigDecimal then value
  when String     then BigDecimal(value.gsub(/\$/, ''))
  else raise TypeError.new("Money can only be initalized with a BigDecimal or String not #{value.class}.")
  end
end

Instance Attribute Details

#rawObject (readonly)

Stores the raw BigDecimal instance that a Money instance wraps.



15
16
17
# File 'lib/spook_and_puff/money.rb', line 15

def raw
  @raw
end

Class Method Details

.cents(cents) ⇒ Object

Initialize a money instance by providing an number of cents

Returns:

  • SpookAndPuff::Money

Raises:

  • (TypeError)


36
37
38
39
# File 'lib/spook_and_puff/money.rb', line 36

def self.cents(cents)
  raise TypeError.new('SpookAndPuff::Money#cents expects a number of cents') unless cents.is_a? Numeric
  new((cents / NUMBER_OF_CENTS).to_s)
end

.zeroObject

A convenience method which returns an instance initalized to zero.

Returns:

  • SpookAndPuff::Money



44
45
46
# File 'lib/spook_and_puff/money.rb', line 44

def self.zero
  new("0")
end

Instance Method Details

#*(other) ⇒ Object

Multiplication. Numerics and strings only.

Parameters:

  • other (Integer, Fixnum, String)

Returns:

  • Money

Raises:

  • ArgumentError



76
77
78
# File 'lib/spook_and_puff/money.rb', line 76

def *(other)
  Money.new(@raw * coerce(other))
end

#+(other) ⇒ Object

Add.

Parameters:

  • other (Money, Numeric, String)

Returns:

  • Money

Raises:

  • ArgumentError



109
110
111
# File 'lib/spook_and_puff/money.rb', line 109

def +(other)
  Money.new(@raw + for_operation(other, 'addition'))
end

#+@Object

Unary plus. Just returns the reciever.

Returns:

  • Money



123
124
125
# File 'lib/spook_and_puff/money.rb', line 123

def +@
  self
end

#-(other) ⇒ Object

Minus.

Parameters:

  • other (Money, Numeric, String)

Returns:

  • Money

Raises:

  • ArgumentError



98
99
100
# File 'lib/spook_and_puff/money.rb', line 98

def -(other)
  Money.new(@raw - for_operation(other, 'subtraction'))
end

#-@Object

Unary minus. This negates the money value

Returns:

  • Money



116
117
118
# File 'lib/spook_and_puff/money.rb', line 116

def -@
  Money.new(-@raw)
end

#/(other) ⇒ Object

Division. Numerics and strings only.

Parameters:

  • other (Integer, Fixnum, String)

Returns:

  • Money

Raises:

  • ArgumentError



87
88
89
# File 'lib/spook_and_puff/money.rb', line 87

def /(other)
  Money.new(@raw / coerce(other))
end

#<=>(other) ⇒ Object

Returns Money.

Parameters:

  • other (Money, Numeric, String)

Returns:

  • Money

Raises:

  • ArgumentError



65
66
67
# File 'lib/spook_and_puff/money.rb', line 65

def <=>(other)
  @raw <=> for_comparison(other)
end

#==(other) ⇒ Object

Value comparison.

Parameters:

  • other (Money, Numeric, String)

Returns:

  • Money



53
54
55
56
57
58
# File 'lib/spook_and_puff/money.rb', line 53

def ==(other)
  case other
  when Money then @raw == other.raw
  else false
  end
end

#absObject

Returns a new Money instance with the absolute value.

Returns:

  • Money



130
131
132
# File 'lib/spook_and_puff/money.rb', line 130

def abs
  Money.new(@raw.abs)
end

#centsObject

Returns a BigDecimal representation of the value in cents.

Returns:

  • BigDecimal



137
138
139
# File 'lib/spook_and_puff/money.rb', line 137

def cents
  @raw * BigDecimal('100')
end

#negative?true, false

Checks to see if the value is less than zero.

Returns:

  • (true, false)


172
173
174
# File 'lib/spook_and_puff/money.rb', line 172

def negative?
  @raw < 0
end

#non_negative?true, false

Checks to see if the value is positive.

Returns:

  • (true, false)


165
166
167
# File 'lib/spook_and_puff/money.rb', line 165

def non_negative?
  @raw > -1
end

#percent(percentage) ⇒ Object

Calculates an amount based on the provided percentage.

Parameters:

  • percentage (Numeric, String)

Returns:

  • Money

Raises:

  • TypeError



183
184
185
# File 'lib/spook_and_puff/money.rb', line 183

def percent(percentage)
  Money.new(@raw * (coerce(percentage) / BigDecimal('100')))
end

#positive?true, false

Checks to see if the value is positive i.e. non-negative, non-zero.

Returns:

  • (true, false)


158
159
160
# File 'lib/spook_and_puff/money.rb', line 158

def positive?
  @raw > 0
end

#proportion(amount) ⇒ Object

Calculates the proportion of the provided amount as a percentage.

Parameters:

  • SpookAndPuff::Money

    amount

Returns:

  • BigDecimal

Raises:

  • TypeError



194
195
196
# File 'lib/spook_and_puff/money.rb', line 194

def proportion(amount)
  amount.raw / @raw * BigDecimal('100')
end

#round(places = 2) ⇒ Object

Rounds to the specified places; defaults to two.

Parameters:

  • Integer

    places

Returns:

  • Money



203
204
205
# File 'lib/spook_and_puff/money.rb', line 203

def round(places = 2)
  Money.new(@raw.round(places))
end

#to_big_decimalObject

Returns the raw BigDecimal value.

Returns:

  • BigDecimal



144
145
146
# File 'lib/spook_and_puff/money.rb', line 144

def to_big_decimal
  @raw
end

#to_s(opts = {}) ⇒ Object

Returns a currency formatted string, set to two decimal places.

Parameters:

  • Hash

    opts

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

    a customizable set of options

Options Hash (opts):

  • :prefix (true, false)

Returns:

  • String



212
213
214
215
216
217
218
# File 'lib/spook_and_puff/money.rb', line 212

def to_s(opts = {})
  rounded = @raw.round(2)
  prefix = opts[:prefix] == false ? '' : '$'
  format = (opts[:drop_cents] and rounded == @raw.round) ? "%i" : "%.2f"

  "#{prefix}#{format}" % rounded
end

#zero?true, false

Checks for zero value.

Returns:

  • (true, false)


151
152
153
# File 'lib/spook_and_puff/money.rb', line 151

def zero?
  @raw == 0
end