Class SplitTotalRounder

java.lang.Object
com.broadleafcommerce.orderoperation.service.split.SplitTotalRounder

public class SplitTotalRounder extends Object
Can be used for handling rounding of amounts which need to add up to different totals.

This tracks targeted totals in two different directions to allow rounding component amounts while still summing to those totals.

For example, when splitting items between multiple fulfillments, this rounding method ensures that:

  1. The split versions of a particular item still sum to the original item price after rounding
  2. All the items in a particular split fulfillment sum to that split fulfillment's designated item subtotal
  • Constructor Details

    • SplitTotalRounder

      public SplitTotalRounder(List<List<javax.money.MonetaryAmount>> amountsOfSplits, List<javax.money.MonetaryAmount> splitTargetTotals, javax.money.MonetaryAmount unitAmount, @Nullable com.broadleafcommerce.order.client.domain.OrderFulfillment originalFulfillment)
      Create a new SplitTotalRounder to round amounts which have been split.
      Parameters:
      amountsOfSplits - a list where each element represents one part of a split, each of which contains a list of amounts containing the split portion of the original amount which was assigned to that part
      splitTargetTotals - the target total for each split part
      unitAmount - the smallest unit of the currency
      originalFulfillment - the original fulfillment which was split, if splitting a fulfillment
  • Method Details

    • roundAmounts

      public void roundAmounts()
      Rounds the contained amounts so that each split side sums to the target totals, and each split amount sums to its original value.

      All amounts are first rounded to floor, and then units are distributed for each side of the split.

    • distributeAmountUnits

      protected void distributeAmountUnits(int splitIndex)
      Distributes units to one split part, indicated by the given splitIndex into one of the parts of each element of amounts.
      Parameters:
      splitIndex - the index into the SplitTotalRounder.SplitAmount.splitAmounts, indicating which part of the split to distribute units to
    • distributeUnitsForAmounts

      protected void distributeUnitsForAmounts(Function<SplitTotalRounder.SplitAmount,javax.money.MonetaryAmount> getAmount, Function<SplitTotalRounder.SplitAmount,javax.money.MonetaryAmount> getRemainder, Consumer<SplitTotalRounder.SplitAmount> incrementAmount, javax.money.MonetaryAmount targetTotal)
      Distributes units to amounts on one part of the split until the given targetTotal is reached. An amount will only be incremented if it has not already reached the correct total across that amount.

      This implementation only handles unit-rounding, and will never distribute more than one unit to each amount. This should always be sufficient to reach the target total. If some erroneous case occurs where the target total cannot be reached, extra units will not be distributed, and the amounts will not add up to the target total.

      Parameters:
      getAmount - getter for the amount on this side of the split
      getRemainder - getter for the remainder on this side of the split
      incrementAmount - method to increment the amount on this side of the split
      targetTotal - the total which the amounts on this side of the split should sum to
    • getAmountsForSplit

      public List<javax.money.MonetaryAmount> getAmountsForSplit(int splitIndex)
      Retrieve the amounts for one split part.
      Parameters:
      splitIndex - the index of the part which was split to retrieve
      Returns:
      a list of all the amounts for a specific split part
    • getOriginalFulfillment

      @Nullable protected com.broadleafcommerce.order.client.domain.OrderFulfillment getOriginalFulfillment()
      The original fulfillment which was split.
    • getAmounts

      protected List<SplitTotalRounder.SplitAmount> getAmounts()
      The amounts which have been split.
    • getSplitTargetTotals

      protected List<javax.money.MonetaryAmount> getSplitTargetTotals()
      The amounts which all of the amounts for a specific split part should sum to.
    • getUnitAmount

      protected javax.money.MonetaryAmount getUnitAmount()
      The smallest unit of the currency.
    • getScale

      protected Integer getScale()
    • setSplitTargetTotals

      protected void setSplitTargetTotals(List<javax.money.MonetaryAmount> splitTargetTotals)
      The amounts which all of the amounts for a specific split part should sum to.
    • setUnitAmount

      protected void setUnitAmount(javax.money.MonetaryAmount unitAmount)
      The smallest unit of the currency.
    • setScale

      protected void setScale(Integer scale)