Class: Money::Collection

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/money/collection.rb,
lib/money/collection/version.rb

Constant Summary collapse

VERSION =
"1.0.0"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(array = nil) ⇒ Collection

Returns a new instance of Collection.



8
9
10
11
# File 'lib/money/collection.rb', line 8

def initialize(array = nil)
  @collection = array.to_a.dup
  @group_by_currency = @collection.group_by(&:currency)
end

Class Method Details

.sum_basic(moneys) ⇒ Money

Sums up Money objects using built-in :+ method.

Parameters:

  • moneys (Enumerable<Money>)

    list of Moneys.

Returns:

  • (Money)

    sum of Money collection.



100
101
102
# File 'lib/money/collection.rb', line 100

def self.sum_basic(moneys)
  moneys.reduce{|total, money| total + money }
end

.sum_single_currency(moneys) ⇒ Money

Sums up Money objects of the same currency. Number of object creation is minimized.

Parameters:

  • moneys (Enumerable<Money>)

    list of Moneys. There is no validation so caller must ensure all Moneys belong to the same currency.

Returns:

  • (Money)

    sum of Money collection.



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

def self.sum_single_currency(moneys)
  total_fractional = moneys.reduce(0){|fractional, money| fractional += money.fractional }
  Money.new(total_fractional, moneys[0].currency)
end

Instance Method Details

#<<(obj) ⇒ Object



68
69
70
71
72
73
74
75
76
# File 'lib/money/collection.rb', line 68

def <<(obj)
  @collection << obj
  if @group_by_currency[obj.currency].nil?
    @group_by_currency[obj.currency] = [obj]
  else
    @group_by_currency[obj.currency] << obj
  end
  self
end

#concat(other_ary) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/money/collection.rb', line 78

def concat(other_ary)
  @collection.concat(other_ary)

  other_ary.group_by(&:currency).each do |currency, ary|
    if @group_by_currency[currency].nil?
      @group_by_currency[currency] = ary
    else
      @group_by_currency[currency].concat(ary)
    end
  end
  self
end

#eachObject

delegations



59
60
61
62
63
64
65
66
# File 'lib/money/collection.rb', line 59

def each
  if block_given?
    @collection.each{|x| yield(x)}
    return self
  else
    return @collection.each
  end
end

#maxObject



45
46
47
48
49
# File 'lib/money/collection.rb', line 45

def max
  @group_by_currency.values.map{|moneys|
    moneys.max_by{|money| money.fractional}
  }.max
end

#minObject



51
52
53
54
55
# File 'lib/money/collection.rb', line 51

def min
  @group_by_currency.values.map{|moneys|
    moneys.min_by{|money| money.fractional}
  }.min
end

#sizeObject



91
92
93
# File 'lib/money/collection.rb', line 91

def size
  @collection.size
end

#sum(target_currency = nil) ⇒ Money

Sums up Money objects in collection.

Parameters:

  • target_currency (Currency, String, Symbol) (defaults to: nil)
    • currency of the returning money object.

Returns:

  • (Money)

    sum of Money collection.



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/money/collection.rb', line 16

def sum(target_currency = nil)
  if @collection.empty?
    return Money.new(0, target_currency)
  end

  if @group_by_currency.size == 1
    sum = self.class.sum_single_currency(@collection)
    if target_currency
      sum = sum.exchange_to(target_currency)
    end
  else
    sums_per_currency = @group_by_currency.values.map{|moneys|
      self.class.sum_single_currency(moneys)
    }

    # Convert to target_currency if specified
    if target_currency
      target_currency = Money::Currency.wrap(target_currency)
      sums_per_currency.map!{|s|
        s.exchange_to(target_currency)
      }
    end

    sum = self.class.sum_basic(sums_per_currency)
  end

  sum
end