Class: Moolah::Money

Inherits:
Object
  • Object
show all
Includes:
Anemic::Model, Comparable
Defined in:
lib/moolah/money.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ Money

Returns a new instance of Money.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/moolah/money.rb', line 16

def initialize(args = {})
  args = args.transform_keys(&:to_sym) unless args.is_a?(Money)

  args[:currency] = 'AUD' if args[:currency].blank?
  args[:fx_rate] = '1.0000' if args[:currency] == 'AUD'

  if args[:fx_rate].nil?
    # So fx_rate appears as nil as part of the error message
    args[:fx_rate] = nil
    raise ArgumentError, "missing keyword: :fx_rate in #{self.class.name} (#{args.sort.to_h})"
  end

  super(args)
end

Class Method Details

.in_aud(amount) ⇒ Object



31
32
33
# File 'lib/moolah/money.rb', line 31

def self.in_aud(amount)
  new(amount: amount)
end

.zero(currency = 'AUD', fx_rate = nil) ⇒ Object



35
36
37
# File 'lib/moolah/money.rb', line 35

def self.zero(currency = 'AUD', fx_rate = nil)
  new(currency: currency, amount: 0, fx_rate: fx_rate)
end

Instance Method Details

#*(_other) ⇒ Object

Raises:

  • (ArgumentError)


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

def *(_other)
  raise ArgumentError, 'Cannot multiply Money objects due to rounding issues'
end

#+(other) ⇒ Object

Raises:

  • (ArgumentError)


89
90
91
92
93
94
95
96
97
# File 'lib/moolah/money.rb', line 89

def +(other)
  return self if other.nil?

  money = other.is_a?(Money) ? other : Money.new(other)
  raise ArgumentError, "Cannot add currency: #{currency} with given currency: #{money.currency}" if currency != money.currency
  raise ArgumentError, "Cannot add fx rate: #{formatter.format_fx_rate} with given fx rate: #{money.formatted_fx_rate}" if fx_rate != money.fx_rate

  Money.new(amount: amount + money.amount, currency: currency, fx_rate: fx_rate)
end

#-(other) ⇒ Object

Raises:

  • (ArgumentError)


99
100
101
102
103
104
105
106
107
# File 'lib/moolah/money.rb', line 99

def -(other)
  return self if other.nil?

  money = other.is_a?(Money) ? other : Money.new(other)
  raise ArgumentError, "Cannot subtract currency: #{currency} with given currency: #{money.currency}" if currency != money.currency
  raise ArgumentError, "Cannot subtract fx rate: #{formatter.format_fx_rate} with given fx rate: #{money.formatted_fx_rate}" if fx_rate != money.fx_rate

  Money.new(amount: amount - money.amount, currency: currency, fx_rate: fx_rate)
end

#-@Object



117
118
119
# File 'lib/moolah/money.rb', line 117

def -@
  Money.new(amount: -amount, currency: currency, fx_rate: fx_rate)
end

#/(_other) ⇒ Object

Raises:

  • (ArgumentError)


113
114
115
# File 'lib/moolah/money.rb', line 113

def /(_other)
  raise ArgumentError, 'Cannot divide Money objects due to rounding issues'
end

#<=>(other) ⇒ Object



121
122
123
124
# File 'lib/moolah/money.rb', line 121

def <=>(other)
  money = other.is_a?(Money) ? other : Money.new(other)
  to_aud.amount <=> money.to_aud.amount
end

#absObject



136
137
138
# File 'lib/moolah/money.rb', line 136

def abs
  Money.new(amount: amount.abs, currency: currency, fx_rate: fx_rate)
end

#amount_in_centsObject



69
70
71
# File 'lib/moolah/money.rb', line 69

def amount_in_cents
  (bankers_rounded.amount * 100).to_i
end

#as_json(*_args) ⇒ Object



73
74
75
76
77
78
79
# File 'lib/moolah/money.rb', line 73

def as_json(*_args)
  {
    'amount' => formatted_amount,
    'currency' => currency,
    'fx_rate' => formatter.format_fx_rate
  }.compact
end

#bankers_roundedObject



126
127
128
# File 'lib/moolah/money.rb', line 126

def bankers_rounded
  Rounder.new(self).bankers_rounded
end

#convert_to(other) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
# File 'lib/moolah/money.rb', line 45

def convert_to(other)
  money = other.is_a?(Money) ? other : Money.new(other)

  converted = Money.new(
    amount: to_aud.amount * money.fx_rate,
    currency: money.currency,
    fx_rate: money.fx_rate
  )

  converted.bankers_rounded
end

#formatted(symbol: true, delimit: true) ⇒ Object



57
58
59
# File 'lib/moolah/money.rb', line 57

def formatted(symbol: true, delimit: true)
  formatter.format(symbol: symbol, delimit: delimit)
end

#formatted_amountObject



61
62
63
# File 'lib/moolah/money.rb', line 61

def formatted_amount
  formatter.format(symbol: false, delimit: false)
end

#formatted_fx_rateObject



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

def formatted_fx_rate
  formatter.format_fx_rate
end

#inspectObject



85
86
87
# File 'lib/moolah/money.rb', line 85

def inspect
  "#{self.class.name} (#{as_json})"
end

#negateObject



130
131
132
133
134
# File 'lib/moolah/money.rb', line 130

def negate
  negated_amount = amount * -1
  negated_amount = 0 if negated_amount.to_s == '-0.0'
  Money.new(amount: negated_amount, currency: currency, fx_rate: fx_rate)
end

#to_audObject



39
40
41
42
43
# File 'lib/moolah/money.rb', line 39

def to_aud
  return Money.new if fx_rate.zero?

  Money.new(amount: amount / fx_rate)
end

#totalObject



81
82
83
# File 'lib/moolah/money.rb', line 81

def total
  self
end