class SpookAndPuff::Money
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.
Constants
- NUMBER_OF_CENTS
Attributes
Stores the raw BigDecimal instance that a Money
instance wraps.
Public Class Methods
Initialize a money instance by providing an number of cents
@return SpookAndPuff::Money
# 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
Initializes the money class from a BigDecimal instance.
@param [BigDecimal, String, SpookAndPuff::Money
] value
@return self
@raise TypeError
# 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
A convenience method which returns an instance initalized to zero.
@return SpookAndPuff::Money
# File lib/spook_and_puff/money.rb, line 44 def self.zero new("0") end
Public Instance Methods
Multiplication. Numerics and strings only.
@param [Integer, Fixnum, String] other
@return Money
@raise ArgumentError
# File lib/spook_and_puff/money.rb, line 76 def *(other) Money.new(@raw * coerce(other)) end
Add.
@param [Money, Numeric, String] other
@return Money
@raise ArgumentError
# File lib/spook_and_puff/money.rb, line 109 def +(other) Money.new(@raw + for_operation(other, 'addition')) end
Unary plus. Just returns the reciever.
@return Money
# File lib/spook_and_puff/money.rb, line 123 def +@ self end
Minus.
@param [Money, Numeric, String] other
@return Money
@raise ArgumentError
# File lib/spook_and_puff/money.rb, line 98 def -(other) Money.new(@raw - for_operation(other, 'subtraction')) end
Unary minus. This negates the money value
@return Money
# File lib/spook_and_puff/money.rb, line 116 def -@ Money.new(-@raw) end
Division. Numerics and strings only.
@param [Integer, Fixnum, String] other
@return Money
@raise ArgumentError
# File lib/spook_and_puff/money.rb, line 87 def /(other) Money.new(@raw / coerce(other)) end
@param [Money, Numeric, String] other
@return Money
@raise ArgumentError
# File lib/spook_and_puff/money.rb, line 65 def <=>(other) @raw <=> for_comparison(other) end
Value comparison.
@param [Money, Numeric, String] other
@return Money
# File lib/spook_and_puff/money.rb, line 53 def ==(other) case other when Money then @raw == other.raw else false end end
Returns a BigDecimal representation of the value in cents.
@return BigDecimal
# File lib/spook_and_puff/money.rb, line 137 def cents @raw * BigDecimal('100') end
Checks to see if the value is less than zero.
@return [true, false]
# File lib/spook_and_puff/money.rb, line 172 def negative? @raw < 0 end
Checks to see if the value is positive.
@return [true, false]
# File lib/spook_and_puff/money.rb, line 165 def non_negative? @raw > -1 end
Calculates an amount based on the provided percentage.
@param [Numeric, String] percentage
@return Money
@raise TypeError
# File lib/spook_and_puff/money.rb, line 183 def percent(percentage) Money.new(@raw * (coerce(percentage) / BigDecimal('100'))) end
Checks to see if the value is positive i.e. non-negative, non-zero.
@return [true, false]
# File lib/spook_and_puff/money.rb, line 158 def positive? @raw > 0 end
Calculates the proportion of the provided amount as a percentage.
@param SpookAndPuff::Money
amount
@return BigDecimal
@raise TypeError
# File lib/spook_and_puff/money.rb, line 194 def proportion(amount) amount.raw / @raw * BigDecimal('100') end
Rounds to the specified places; defaults to two.
@param Integer places
@return Money
# File lib/spook_and_puff/money.rb, line 203 def round(places = 2) Money.new(@raw.round(places)) end
Returns the raw BigDecimal value.
@return BigDecimal
# File lib/spook_and_puff/money.rb, line 144 def to_big_decimal @raw end
Returns a currency formatted string, set to two decimal places.
@param Hash opts @option opts [true, false] :prefix @return String
# 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
Checks for zero value.
@return [true, false]
# File lib/spook_and_puff/money.rb, line 151 def zero? @raw == 0 end
Private Instance Methods
Coerces the provided value into a BigDecimal. It will handle any Numeric or string.
@param [Numeric, String] other
@return BigDecimal
@raise TypeError
# File lib/spook_and_puff/money.rb, line 263 def coerce(other) case other when BigDecimal then other when String then BigDecimal(other) when Integer, Fixnum, Bignum then BigDecimal(other.to_s) else raise TypeError end end
Grabs the raw value of a Money
instance, erroring with a message about comparison if it’s the wrong type.
@param SpookAndPuff::Money
other
@return BigDecimal
@raise ArgumentError
# File lib/spook_and_puff/money.rb, line 230 def for_comparison(other) unless other.is_a?(Money) raise ArgumentError.new("#{other.class} cannot be compared with SpookAndPuff::Money") end other.raw end
Grabs the raw value of a Money
instance, erroring with a message about comparison if it’s the wrong type.
@param SpookAndPuff::Money
other @param String op
@return BigDecimal
@raise ArgumentError
# File lib/spook_and_puff/money.rb, line 247 def for_operation(other, op) unless other.is_a?(Money) raise ArgumentError.new("Cannot perform #{op} on SpookAndPuff::Money with #{other.class}") end other.raw end