Customizing the promotion code manager

You can customize how the promotion engine resolves promotion codes to promotions. In addition, you can customize how promotion codes are applied so that a single field in a shopping cart accepts only one promotion code. This means that when multiple promotion codes exist for an order, only the promotion code entered most recently will be applied to the order while all others will be deleted. Without customization, all the promotion codes will be accumulated and will be applied in total.

About this task

HCL Commerce currently provides a simple promotion code feature. A single code can be assigned to a promotion. Customers who want to redeem this promotion must enter the same code to qualify. In reality, many sites have sophisticated promotion code applications. For example, promotion codes can carry more information than simple promotion identification. A code can carry additional information such as channel information, entitlement, and pricing information.

Promotion codes are managed by the PromotionCodeManager component of the promotion engine. This is a configurable component. The default promotion code manager, WCSPromotionCodeManager, simply records promotion codes entered for an order in the ORDPROMOCD table. All promotion code managers must implement the com.ibm.commerce.marketing.promotion.code.PromotionCodeManager interface, which is a subclass of XMLizable.

Usually, this portion of the PromotionCodeManager does not require customization. The WCSPromotionCodeManager relies on another configurable component to resolve promotion codes to promotions. This configurable component is a PromotionCodeResolver. The default implementation looks up the promotion code specified for promotions and tries to find a match. This is the most commonly configured aspect when supporting a sophisticated promotion code application.

Procedure

  1. Implement your promotion code manager.
    All PromotionCodeResolvers must implement the com.ibm.commerce.marketing.promotion.code.PromotionCodeResolver interface, which is also a subclass of XMLizable. The following sample illustrates the interface definition:
    
    public interface PromotionCodeResolver extends XMLizable {
       /**
        * IBM Copyright
        */
        public static final String COPYRIGHT = IBMCopyright.SHORT_COPYRIGHT;
    
       /**
        * Resolves a promotion code to a promotion.
        * @param code the code
        * @param context the context within which the resolution is performed.
        * @return the key to the promotion which is identified by this
        * promotion code.
        */
    
       PromotionKey resolve(String code, PromotionContext context)
          throws PromotionApplicationException;
    
       /**
        * Resolves a promotion code to a promotion. A name-value pair style
        * parameter can be passed in.
        * The implementor is responsible for checking whether the required 
        * parameters are provided.
        * This is for customization purposes. This method is often used when
        * promotion codes are evaluated.
        * The reason the other resolve method is not used is because it needs a
        * PromotionContext object, which may not be available at the time
        * codes are validated.
        * @param code the code
        * @param custoProp custom properties passed to the resolver for promotion
        * resolution.
        * @return the key to the promotion which is identified by this promotion 
        * code.
        */
        
        PromotionKey resolve(String code, Hashtable NVP)
           throws PromotionApplicationException;
    }
    

    The two key methods are the two resolve methods. The first one takes a String which is a promotion code and a PromotionContext. This method is usually called when the Promotion Engine has been invoked. The second resolve takes a String parameter which is the promotion code and a Hashtable name-value pair parameter. This usually is called when a new promotion code is added to an order to validate the promotion code. By convention, the key to the store is saved on this name-value pair using the name "StoreKey".

    Custom promotion code application developers must provide their implementation of the resolve method to decipher a string promotion code to match a key to a promotion. This is generally a site specific issue and needs to be addressed on a case by case basis.

    Note that, as the promotion code is being resolved, the resolver can record the fact that a particular code has been used, for analysis purposes. Also, when an order is confirmed and submitted, a PromotionAppliedEvent is raised, so a promotion code application developer might need to create a listener to listen for this event and record the promotion codes that actually trigger purchases.

  2. Register the custom promotion resolver in the promotion engine configuration.
    The following XML fragment in the promotion configuration XML configures the PromotionCodeManager.
    
    <PromotionCodeManager = impl
          "com.ibm.commerce.marketing.promotion.code.WCSPromotionCodeManager">
       <PromotionCodeResolver impl = 
             "com.ibm.commerce.marketing.promotion.code.DefaultPromotionCodeResolver">
    </PromotionCodeManager>
    
  3. Customize how promotion codes are applied.

    You can customize the promotion codes so that a single field in a shopping cart accepts only one promotion code. This means that when multiple promotion codes exist for an order, only the promotion code entered most recently will be applied to the order while all others will be deleted. In a non-customized method, all the promotion codes will be accumulated and will be applied in total. This can be affected by the following steps:

    1. Overwrite PromotionCodeAddRemoveControllerCmdImpl
    2. Use the static method removeOrderPromotionCode
    3. Replace the addPromoCodeToOrder method
    To remove all the existing promotion codes from an order, there is another method in the class PromotionCodeCentral. This method needs only the ordersId as a parameter, which makes it easier to perform and hence it is simpler and has higher performance.
    
     /**
     * This method removes all the Promotion Codes from the specified order.
     * @param orderID The order id of the order from which the promotion codes 
     * are to be removed.
     * @throws Exception The exception.
     */ 
    
     public static void removeAllCodesForOrder(Long ordersID) throws 
     ECSystemException
    
  4. Restart HCL Commerce.

    A restart of HCL Commerce is required after any change to either the PromotionCodeManager or the PromotionCodeResolver.