/// <summary> /// Allocates the sum of money 'fairly', discarding the remainder of an uneven allocation. /// </summary> /// <remarks> /// <para> /// A sum of money that can be allocated to each recipient exactly evenly is inherently 'fair'. For example, a US /// Dollar split four (4) ways leaves each recipient with 25 cents and everything is allocated.</para> /// <para> /// A US Dollar split three (3) ways cannot be distributed evenly and is therefore inherently 'unfair'. What will be done /// is allocate the maximum fair amount and leave the remainding amount for the caller to decide.</para> /// </remarks> /// <param name="numberOfRecipients">The number of times to split up the total.</param> /// <returns> /// The results of the even allocation with a length equal to <paramref name="numberOfRecipients"/>. /// <para>In the case of an even allocation, the allocation will be complete.<see cref="Allocation.IsComplete"/>, having a zero <see cref="Allocation.Remainder"/>.</para> /// <para>In the case of an uneven allocation, the allocation will not be complete <see cref="EvenAllocator(Money)"/>, having a non-zero <see cref="Allocation.Remainder"/>.</para> /// </returns> /// <seealso cref="EvenAllocator(Money)"/> public Allocation Allocate(int numberOfRecipients) { // if amount to allocate is too 'scarce' to allocate something to all // then effectively go into remainder allocation mode if (notEnoughToAllocateEvenly(numberOfRecipients)) { return(Allocation.Zero(_toAllocate, numberOfRecipients)); } decimal each = amountforEachRecipient(numberOfRecipients); Money[] results = Money.Some(each, _currency, numberOfRecipients); return(new Allocation(_toAllocate, results)); }
public static Allocation Allocate(this Money money, int numberOfRecipients, IRemainderAllocator allocator) { EvenAllocator.AssertNumberOfRecipients(nameof(numberOfRecipients), numberOfRecipients); if (money.notEnoughToAllocate()) { return(Allocation.Zero(money, numberOfRecipients)); } Allocation allocated = new EvenAllocator(money) .Allocate(numberOfRecipients); allocated = money.allocateRemainderIfNeeded(allocator, allocated); return(allocated); }
public static Allocation Allocate(this Money money, RatioCollection ratios, IRemainderAllocator allocator) { Guard.AgainstNullArgument(nameof(ratios), ratios); if (money.notEnoughToAllocate()) { return(Allocation.Zero(money, ratios.Count)); } Allocation allocated = new ProRataAllocator(money) .Allocate(ratios); allocated = money.allocateRemainderIfNeeded(allocator, allocated); return(allocated); }