Class: Money::Allocator
- Inherits:
-
SimpleDelegator
- Object
- SimpleDelegator
- Money::Allocator
- Defined in:
- lib/money/allocator.rb
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.
3 4 5 |
# File 'lib/money/allocator.rb', line 3 def initialize(money) super end |
Instance Method Details
#allocate(splits, strategy = :roundrobin) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/money/allocator.rb', line 39 def allocate(splits, strategy = :roundrobin) if all_rational?(splits) allocations = splits.inject(0) { |sum, n| sum + n } else allocations = splits.inject(0) { |sum, n| sum + Helpers.value_to_decimal(n) } end if (allocations - BigDecimal("1")) > 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.
78 79 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 106 |
# File 'lib/money/allocator.rb', line 78 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(0) if maximums_total.zero? Money.rational(max_amount, maximums_total) end total_allocatable = [ value * allocation_currency.subunit_to_unit, maximums_total.value * allocation_currency.subunit_to_unit ].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 |