Custom adjustments

Custom adjustments must implement the com.ibm.commerce.marketing.promotion.reward.Adjustment interface. Here is its definition:


package com.ibm.commerce.marketing.promotion.reward;

import java.math.BigDecimal;
import java.util.Vector;

import com.ibm.commerce.marketing.promotion.runtime.LineItemSet;
import com.ibm.commerce.marketing.promotion.runtime.PromotionContext;
import com.ibm.commerce.marketing.promotion.runtime.PromotionRuntimeException;
import com.ibm.commerce.marketing.promotion.xml.XMLizable;

/**
 * <code>Adjustment</code> interface contains the methods common to
 * all adjustments.
 * This interface extends <code>XMLizable</code> and <code>Cloneable</code> 
 * interfaces. 
 * All the adjustments should implement this interface.
 */

public interface Adjustment extends XMLizable, Cloneable {
   /**
    * IBM copyright notice field.
    */
    public static final String COPYRIGHT =
          com.ibm.commerce.copyright.IBMCopyright.SHORT_COPYRIGHT;
       /**
        * Indicates Whole Order.
        */
        
    public static final Integer WHOLE_ORDER = new Integer(1);
       /**
        * Indicates all Affected Items.
        */

    public static final Integer ALL_AFFECTED_ITEMS = new Integer(2);
       /**
        * Indicates Individual Affected Items.
        */

    public static final Integer INDIVIDUAL_AFFECTED_ITEMS = new Integer(3);
       /**
        * This method gets the type of Adjustment. Adjustment can be one of the 
        * following types for whole Order, for All Affected Items, and for 
        * Individual Affected Items.
        * @return Integer  <code>1 </code> Order as a whole
        *                   <code>2 </code> All Affected Items
        *                   <code>3 </code> Individual Affected Items 
        */

    Integer getAdjustmentType();

       /**
        * This method sets the promotion level.
        * @return Integer <code>1 </code> Order as a whole
        *                   <code>2 </code> All Affected Items
        *                   <code>3 </code> Individual Affecte Items 
        */

    void setAdjustmentType(Integer adjustmentType);

       /**
        * Applies adjustment to affected order items
        * @param targeted targeted order items
        * @param affected affected order items
        * @param context PromotionExecutionContext
        * @return the actual adjustment
        * @throws PromotionRuntimeException when the computation 
        * encounters a problem
        */

    boolean apply(
          LineItemSet targeted, 
          BigDecimal targetedAmount,
          int targetedAmountTypes,
          LineItemSet affected,
          Vector affectedVector,
          Vector adjustmentVector,
          PromotionContext context)
          throws PromotionRuntimeException;
}

Again, this interface is a subclass of XMLizable. The three constants declared on the interface represent three different ways an Adjustment is attached to affected items. Examine the apply method, which takes the following parameters:

LineItemSet targeted
This input parameter is the set of order items (or portions of order items) that are used to qualify for the promotion of which this adjustment is a part.
BigDecimal targetedAmount
Currently, this input parameter is not used, and a null value will always be passed to Adjustments.
int targetedAmountType
Currently, this input parameter is not used.
LineItemSet affected
This output parameter is the set of order items, identified by the promotion, to which the adjustment will be attached.
Vector affectedVector
This is an output parameter. Normally, when the apply method finishes, this vector grows by 1. The affected parameter is appended to the end of this vector. However, in certain situations, the apply method may split the LineItemSet and apply different Adjustments to different subsets. In that case, all resulting subsets will be appended to this vector
Vector adjustmentVector
This is an output parameter. Normally, when the apply method finishes, this vector grows by 1. The Adjustment is appended to the end of this vector. However, in certain situations, the apply method may split the LineItemSet and apply different Adjustments to different subsets. In this case, each resulting Adjustment is appended to this vector. The elements on the affectedVector and this parameter, have a one-to-one relationship based on their index in the vector.
PromotionContext context
Provides a context in which the adjustment executes.

There is a special type of adjustments, called MonetaryAdjustments. Currently, in an online retail environment, there are four different types of monetary values associated with a purchase. They are: price, shipping and handling, taxes, and taxes on shipping and handling. Promotions that change these values attach a MonetaryAdjustment to any affected items. MonetaryAdjustment is a subclass of the Adjustment interface. Therefore, all of the details about adjustments apply to MonetaryAdjustment. In addition to adjustment, there are a number of extensions in MonetaryAdjustment. Here is the interface definition:


package com.ibm.commerce.marketing.promotion.reward;

import java.math.BigDecimal;
import com.ibm.commerce.marketing.promotion.runtime.AssociatedOrderItem;
import com.ibm.commerce.marketing.promotion.runtime.PromotionContext;

public interface MonetaryAdjustment extends Adjustment {
       /**
        * IBM copyright notice field.
        */
       public static final String COPYRIGHT =
             com.ibm.commerce.copyright.IBMCopyright.SHORT_COPYRIGHT;

       /**
        * Adjustment is on the sub total of an order or a subset of an order.
        */
       public static final int PRICE = 1;
       
       /**
        * Adjustment is on the shipping charges of an order or a subset of an order.
        */
       public static final int SHIPPING = 2;

       /**
        * Adjustment is on the tax levied on the shipping charges of an order or a
        * subset of an order.
        */
       public static final int SHIPPING_TAX = 4;
       /**
        * Adjustment is on the tax levied on an order or a subset of an order
        */
       public static final int TAX = 8;

       /**
        * A simple BigDecimal constant value of 0.
        */
       public static final BigDecimal ZERO = new BigDecimal("0");

       /**
        * Returns the target of a monetary adjustmennt. Possible values are:
        * SUBTOTAL=1, SHIPPING=2, SHIPPING_TAX=4, TAX=8. 
        * @return target of a monetary adjustment
        */
       int getTheTypeOfMonetaryValueToBeAdjusted();

       /**
        * Returns the monetary adjustment that need to be apply to each unit of an order
        * item or a portion of an order item (as identified by the AssociationOrderItem).
        * It is guaranteed that all units in <code>one</code> have been adjusted by
        * exactly the same set of monetary adjustments.
        * @param one the order item or portion of an order item for which a per unit 
        * adjustment amount needs to be calculated.
        * @param all all of the AssociatedOrderItems to which this 
        * adjustment applies.
        * @param context PromotionContext
        * @return a perUnit value, value could be positive which means a discount, 
        * negative which means a markup, or zero which means no change is needed.
        */
       BigDecimal getPerUnitAdjustment(
              AssociatedOrderItem one,
              AssociatedOrderItem all[],
              PromotionContext context);
}

As compared to the Adjustment interface there are two additional methods defined. First, the getTheTypeOfMonetaryValueToBeAdjusted method, which returns a bit map of values representing the monetary values to which this adjustment is applied. MonetaryAdjustment can be applied to multiple monetary values if the bit map returned by this method has more than 1 bit set to 1. Second, the BigDecimal method, which performs the logic of distributing the monetary adjustments as defined by a MonetaryAdjustment to individual affected items. The comments in the interface definition should be sufficient to explain the behavior of this method.

All monetary adjustments must implement the MonetaryAdjustment interface.

Note: All custom adjustment implementations must be thread safe and re-entrant.

Once you have implemented the promotion adjustment, you must ensure that the adjustment is supported by the order subsystem. By default, the following adjustment application methods are supported:

  • WHOLE_ORDER
  • INDIVIDUAL_AFFECTED_ITEMS
  • ALL_AFFECTED_ITEMS