Class: Money::Allocator
- Inherits:
-
SimpleDelegator
- Object
- SimpleDelegator
- Money::Allocator
- Defined in:
- lib/money/allocator.rb
Constant Summary collapse
- ONE =
BigDecimal("1")
Instance Method Summary collapse
- #allocate(splits, strategy = :roundrobin) ⇒ Object
-
#allocate_max_amounts(maximums) ⇒ Object
Allocates money between different parties up to the maximum amounts specified.
-
#initialize(money) ⇒ Allocator
constructor
A new instance of Allocator.
Constructor Details
#initialize(money) ⇒ Allocator
Returns a new instance of Allocator.
6 7 8 |
# File 'lib/money/allocator.rb', line 6 def initialize(money) super end |
Instance Method Details
#allocate(splits, strategy = :roundrobin) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/money/allocator.rb', line 44 def allocate(splits, strategy = :roundrobin) splits.map!(&:to_r) allocations = splits.inject(0, :+) if (allocations - ONE) > Float::EPSILON raise ArgumentError, "splits add to more than 100%" end amounts, left_over = amounts_from_splits(allocations, splits) left_over.to_i.times do |i| amounts[allocation_index_for(strategy, amounts.length, i)] += 1 end amounts.collect { |subunits| Money.from_subunits(subunits, currency) } end |
#allocate_max_amounts(maximums) ⇒ Object
Allocates money between different parties up to the maximum amounts specified. Left over pennies will be assigned round-robin up to the maximum specified. Pennies are dropped when the maximums are attained.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/money/allocator.rb', line 80 def allocate_max_amounts(maximums) allocation_currency = extract_currency(maximums + [self.__getobj__]) maximums = maximums.map { |max| max.to_money(allocation_currency) } maximums_total = maximums.reduce(Money.new(0, allocation_currency), :+) splits = maximums.map do |max_amount| next(Rational(0)) if maximums_total.zero? Money.rational(max_amount, maximums_total) end total_allocatable = [maximums_total.subunits, self.subunits].min subunits_amounts, left_over = amounts_from_splits(1, splits, total_allocatable) subunits_amounts.each_with_index do |amount, index| break unless left_over > 0 max_amount = maximums[index].value * allocation_currency.subunit_to_unit next unless amount < max_amount left_over -= 1 subunits_amounts[index] += 1 end subunits_amounts.map { |cents| Money.from_subunits(cents, allocation_currency) } end |