Exemple : Ajout du support d'un type de promotion personnalisé

Ce scénario ajoute une prise en charge pour un type de promotion personnalisé.

  1. Définissez un nouveau modèle XML pour le type de promotion personnalisé.
  2. Analysez les nouveaux attributs nécessaires pour la promotion personnalisée afin de définir une condition d'achat et une récompense. Si un client achète un article de la catégorie cadeau personnalisé, affichez une publicité sur une promotion offrant une bougie de fêtes parfumée (SKU unique) pour 5 dollars. Il s'agit d'une promotion appartenant au niveau de catégorie Coût fixe.
    Les informations nécessaires pour la condition d'achat et la récompense sont définies comme suit :
    1. ID de catégorie (par exemple : nom)
    2. Quantité requise pour un achat dans cette catégorie.
    3. Produit en promotion (par exemple : SKU bougie de fêtes)
    4. Quantité du produit en promotion (par défaut : 1)
    5. Coût fixe affecté au produit en promotion.
  3. Créez une interface java qui définit toutes les constantes associées au nouveau type de remise et aux nouveaux attributs de l'interface utilisateur pour les promotions, dont les fichiers JSP et les beans de données. Pour créer cette interface :
    1. Ouvrez l'environnement de développement HCL Commerce (Démarrer > Programmes > HCL CommerceEnvironnement de développement)
    2. Accédez au projet WebSphereCommerceServerExtensionsLogic.
    3. Cliquez avec le bouton droit de la souris sur le projet et sélectionnez Nouveau, puis Package.
    4. Dans la zone Nom de la boîte de dialogue Nouveau package Java, entrez com.myCompany.epromotion.logic, où myCompany représente le nom de répertoire personnalisé. Les packages créés par IBM et inclus dans HCL Commerce suivent une convention de dénomination : ils commencent par com.ibm...
    5. Cliquez sur Terminer pour créer le package.
    6. Cliquez avec le bouton droit de la souris sur le nouveau package et sélectionnez Nouveau puis Interface.
    7. Dans la zone Nom, entrez ExtendedPromotionConstants.
    8. Cliquez sur Terminer. Le fichier s'ouvre dans l'éditeur.
    9. Mettez à jour le fichier pour qu'il corresponde à l'exemple suivant :
      
      package com.myCompany.epromotion.logic; 
      
      public interface ExtendedPromotionConstants extends com.ibm.commerce.tools.epromotion.RLConstants {
           // The new promotion types below are used for the promotion factory to identify 
           // each new promotion object.
           // These new types have to be registered in the RLPromotion.xml in order to be picked up
           // by Promotion Component Configuration
      
              public static final String PROMOTION_CATEGORYLEVELPWP = "CategoryLevelPurchaseWithPurchase";
              public static final String PROMOTION_PRODUCTLEVELPWP = "ProductLevelPurchaseWithPurchase";
              public static final String PROMOTION_ITEMLEVELPWP = "ItemLevelPurchaseWithPurchase";
           // The attributes below are for CategoryLevelPurchaseWithPurchase UI element naming convention,
           // the name should be matching with the one in UI databean in order to allow Tools FrameWork Java
           // Script object to pick up.
           // These attributes could also be reused by other types if the promotion condition is similar.
           
              public static final String PROMOTION_REQUIREDITEMQTY = "rlRequiredItemQty";
              public static final String PROMOTION_PROMOTEDITEMQTY = "rlPromotedItemQty";
              public static final String PROMOTION_PROMOTEDPRODUCTID = "rlPromotedProductId";
              public static final String PROMOTION_FIXCOST = "rlFixCost";
      }    
      
    10. Sauvegardez le fichier, mais ne fermez pas l'environnement de développement.
  4. Créez un objet Java qui représente le type de promotion personnalisé. Cet objet présente la nouvelle condition d'achat et la récompense associée, ainsi que gérer les entrées et sorties XML. Cet objet implémente l'interface générée à l'étape 3. Pour le créer :
    1. Accédez au projet WebSphereCommerceServerExtensionsLogic.
    2. Accédez au dossier src.
    3. Cliquez avec le bouton droit de la souris sur le dossier src et sélectionnez Nouveau, puis Package.
    4. Dans la zone Nom de la boîte de dialogue Nouveau package Java, entrez un nom unique. Pour les besoins de ce scénario, entrez com.myCompany.epromotion.implementations, où myCompany présente un nom de répertoire personnalisé.
    5. Cliquez sur Terminer pour créer le package.
    6. Cliquez avec le bouton droit de la souris sur le package com.myCompany.epromotion.implementations et sélectionnez Nouveau puis Classe.
    7. Dans la zone Nom de la boîte de dialogue Nouvelle classe Java, entrez CategoryLevelPurchaseWithPurchase.
    8. Dans le champ Superclass de la boîte de dialogue Nouvel objet Java, entrez com.ibm.commerce.tools.epromotion.RLCategoryLevelPromotion.
    9. Cliquez sur Terminer. Le fichier s'ouvre dans l'éditeur.
    10. Mettez à jour le fichier pour qu'il corresponde à l'exemple suivant :
      
      package com.myCompany.epromotion.implementations;
      
      /**
       * The puchase condition in this sample is based on the category, therefore, this
       * Class extends {@link RLCategoryLevelPromotion}.
       * 
       * 
       * This XML will be generated in the {@link #toSpecificXML} method.
       * Also, all the fields in this class should be able to populate based on this XML through
       * {@link #populatePromotionSpecificDataFrom(String)}
       */
      
      import java.util.*;
      import java.text.Collator;
      import com.ibm.commerce.ras.*;
      import com.ibm.commerce.tools.epromotion.*;
      import com.ibm.commerce.tools.epromotion.util.*;
      import com.ibm.commerce.exception.*;
      
      import javax.xml.parsers.*;
      import org.xml.sax.InputSource;
      import org.w3c.dom.*;
      
      public class CategoryLevelPurchaseWithPurchase
         extends com.ibm.commerce.tools.epromotion.RLCategoryLevelPromotion
         implements com.myCompany.epromotion.logic.ExtendedPromotionConstants {
      
         /**
          * Customization: Define all the promotion purchase condition and reward attributes.
          * 1. The methods to retrieve the required item identification is in the parent class.
          * @see RLCategoryLevelPromotion#setCatalogGroupIDs(Vector)
          * 2. Terminology: based on the sample promotion: giving B a discount if purchase a number of A
          * A is the required item.
          * B is the promoted item.
          * 3. In this class, A is a category entity, B is a product/item based on user input.
          * The customized JSP, needs to support both search functions to allow choose product/item.
          */
      
         // The quantity required for the purchased item in order to get discount on promoted item.
         private int requiredItemQty;
        
         // The quantity of promoted item this promotion rule will give for a fixed cost.
         // default is 1 (option): which means fixed cost for each promoted item.
         // 2 means fixed cost for every 2 items...
         private int promotedItemQty=1;
      
         // The catalog entry identification of the promoted item
         private String promotedProductId;
       
         // The fix cost for the promoted items,
         // This value should be a String representation of Decimal
         private String fixCost;
       
         /**
          * This default promotion constructor.
          * There is no need to customized this constructor unless you have your own attributes
          * for new promotions, which should be initialized during object creation.
          */
         public CategoryLevelPurchaseWithPurchase() {
            super();
         }
       
         /**
          * It should always return the toSpecificXML(), there is no need customize it.
          */
         public String generatePromotionSpecificRuleXML() {
            return toSpecificXML();
         }
       
         /**
          * This method should be customized according to the new promotion purchase condition.
          * This method should generate the portion of the promotion XML, which fully describes
          * the purchase condition and reward relationship.
          */
         public String toSpecificXML() {
            final String methodName = "toSpecificXML()";
            // XmlHelper provides some utility function for XML String generation.
            XmlHelper helper = new XmlHelper();
            StringBuffer buffer = new StringBuffer();
            buffer
               .append("<PurchaseCondition impl=\"com.ibm.commerce.marketing.promotion.condition.PurchaseCondition\">")
               .append("<Pattern impl=\"com.ibm.commerce.marketing.promotion.condition.Pattern\">")
               .append("<Constraint impl=\"com.ibm.commerce.marketing.promotion.condition.Constraint\">")
               .append("<WeightedRange impl=\"com.ibm.commerce.marketing.promotion.condition.WeightedRange\">")
               .append("<LowerBound>")
               .append(this.getRequiredItemQty())
               .append("</LowerBound>")
               .append("<UpperBound>")
               .append(this.getRequiredItemQty())
               .append("</UpperBound>")
               .append("<Weight>1</Weight>")
               .append("</WeightedRange>")
               .append("<FilterChain impl=\"com.ibm.commerce.marketing.promotion.condition.FilterChain\">")
               .append(this.getRequiredItemFilter())
               .append("</FilterChain>")
               .append("</Constraint>")
               .append("<Constraint impl=\"com.ibm.commerce.marketing.promotion.condition.Constraint\">")
               .append("<WeightedRange impl=\"com.ibm.commerce.marketing.promotion.condition.WeightedRange\">")
               .append("<LowerBound>")
               .append(this.getPromotedItemQty())
               .append("</LowerBound>")
               .append("<UpperBound>")
               .append(this.getPromotedItemQty())
               .append("</UpperBound>")
               .append("<Weight>1</Weight>")
               .append("</WeightedRange>")
               .append("<FilterChain impl=\"com.ibm.commerce.marketing.promotion.condition.FilterChain\">")
               .append(this.getPromotedItemFilter())
               .append("</FilterChain>")
               .append("</Constraint>")
               .append("</Pattern>")
               .append("<Distribution impl=\"com.ibm.commerce.marketing.promotion.reward.Distribution\">")
               .append("<Type>Volume</Type>")
               .append("<Base>Quantity</Base>")
               .append("<Currency/>")
               .append("<Range impl=\"com.ibm.commerce.marketing.promotion.reward.DistributionRange\">")
               .append("<UpperBound>-1</UpperBound>")
               .append("<LowerBound>1</LowerBound>")
               .append("<RewardChoice>")
               .append("<Reward impl=\"com.ibm.commerce.marketing.promotion.reward.DefaultReward\">")
               .append("<AdjustmentFunction impl=\"com.ibm.commerce.marketing.promotion.reward.AdjustmentFunction\">")
               .append("<FilterChain impl=\"com.ibm.commerce.marketing.promotion.condition.FilterChain\">")
               .append(this.getPromotedItemFilter())
               .append("</FilterChain>")
               .append("<Adjustment impl=\"com.ibm.commerce.marketing.promotion.reward.FixedCostAdjustment\">")
               .append("<FixedCost>")
               .append(this.getFixCost())
               .append("</FixedCost>")
               .append("<Currency>")
               .append(this.getCurrency())
               .append("</Currency>")
               .append("<AdjustmentType>IndividualAffectedItems</AdjustmentType>")
               .append("</Adjustment>")
               .append("</AdjustmentFunction>")
               .append("</Reward>")
               .append("</RewardChoice>")
               .append("</Range>")
               .append("<PatternFilter impl=\"com.ibm.commerce.marketing.promotion.condition.DummyPatternFilter\" />")
               .append("</Distribution>")
               .append("</PurchaseCondition>");
              
               return buffer.toString();
            }
          
            public void fromSpecificXML(String xml) {
               final String methodName = "fromSpecificXML()";
         
               EproUtil util = new EproUtil();
               Collator collator = Collator.getInstance();
               // Get the promoted item from reward 
               String tempPromotedSKU =
                  XmlHelper
                     .getElementTextValueInNode(
                        XmlHelper.getXMLDocument(xml),
                        "Reward",
                        "SKU")
                     .firstElement()
                     .toString();
               String tempPromotedDN =
                  XmlHelper
                     .getElementTextValueInNode(
                        XmlHelper.getXMLDocument(xml),
                        "Reward",
                        "DN")
                     .firstElement()
                     .toString();
               try {
                  promotedProductId =
                     util.getCatEntryId(tempPromotedSKU, tempPromotedDN);
               } catch (ECException e) {
                  ECTrace.trace(
                     ECTraceIdentifiers.COMPONENT_MERCHANDISING,
                     getClass().getName(),
                     methodName,
                     e.toString());
                  // exception is handled inside the util class 
               }
               // Get the promoted item cost from the reward adjustment
               fixCost =
                  XmlHelper
                     .getElementTextValueInNode(
                        XmlHelper.getXMLDocument(xml),
                        "Adjustment",
                        "FixedCost")
                     .firstElement()
                     .toString();
               this.setCurrency(
                  XmlHelper
                     .getElementTextValueInNode(
                        XmlHelper.getXMLDocument(xml),
                        "Adjustment",
                        "Currency")
                     .firstElement()
                     .toString());
       
            // Get information from Pattern -- Constraint Node List
            NodeList nodeList =
               XmlHelper.getXMLDocument(xml).getElementsByTagName("Constraint");
            int size = nodeList.getLength();
            for (int i = 0; i < size; i++) {
               if (nodeList.item(i).hasChildNodes()
                  && (nodeList.item(i).getNodeType() == Node.ELEMENT_NODE)) {
                  Element element = (Element) nodeList.item(i);
                  NodeList catentryKeys =
                     element.getElementsByTagName("IncludeCatEntryKey");
                  if (catentryKeys.getLength() > 0) {
                     // this is the promoted item filter since it is the SKU Filter in this sample XML.
                     promotedItemQty =
                        Integer.parseInt(
                           element
                              .getElementsByTagName("LowerBound")
                              .item(0)
                              .getFirstChild()
                              .getNodeValue());
                  } 
                  NodeList categoryKeys =
                     element.getElementsByTagName("IncludeCategory");
                  if (categoryKeys.getLength() > 0) {
                     // This is the required category filter since it is the category Filter in the sample XML.
                     // The section below populates the required item quantity from XML.
                     requiredItemQty =
                        Integer.parseInt(
                           element
                              .getElementsByTagName("LowerBound")
                              .item(0)
                              .getFirstChild()
                              .getNodeValue());
                     // The section below populates the catalog group IDs
                     NodeList names = element.getElementsByTagName("Name");
                     NodeList dns = element.getElementsByTagName("DN");
                     Vector cgpIdentifiers = new Vector();
                     Vector cgpIds = new Vector();
                     for (int j = 0; j < names.getLength(); j++) {
                        try {
                           String tempCatGrpId =
                              util.getCatGroupId(
                                 names
                                    .item(j)
                                    .getFirstChild()
                                    .getNodeValue(),
                                 dns.item(j).getFirstChild().getNodeValue());
                           if (tempCatGrpId != null
                              && (collator.compare(tempCatGrpId.trim(), "")
                                 != 0)) {
                              cgpIds.addElement(tempCatGrpId);
                              cgpIdentifiers.addElement(
                                 names
                                    .item(j)
                                    .getFirstChild()
                                    .getNodeValue());
                           } 
                        } catch (ECException e) {
                           ECTrace.trace(
                              ECTraceIdentifiers.COMPONENT_MERCHANDISING,
                              getClass().getName(),
                              methodName,
                              e.toString());
                        } 
                     }
                     this.setCatalogGroupIDs(cgpIds);
                     this.setCatgpIdentifiers(cgpIdentifiers);
                  }   
               }
            } 
         } 
       
         public void populatePromotionSpecificDataFrom(Map h)
            throws com.ibm.commerce.exception.ParameterNotFoundException {
            requiredItemQty =
               EproUtil.toInt(
                  EproUtil.doCheckParameterFound(h, PROMOTION_REQUIREDITEMQTY));
            promotedItemQty =
               EproUtil.toInt(
                  EproUtil.doCheckParameterFound(h, PROMOTION_PROMOTEDITEMQTY));
            promotedProductId =
               EproUtil
                  .doCheckParameterFound(h, PROMOTION_PROMOTEDPRODUCTID)
                  .toString();
            fixCost =
               EproUtil.doCheckParameterFound(h, PROMOTION_FIXCOST).toString();
         } 
      
         public void populatePromotionSpecificDataFrom(String s) {
            // This method always call fromSpecificXML(xml) internally.
            this.fromSpecificXML(s);
         }
      
         /**
          * Set the quantity required for the purchased item in order to get discount on promoted item.
          * @param newRequiredItemQty the required item quantity passed by user.
          */
         public void setRequiredItemQty(int newRequiredItemQty) {
            this.requiredItemQty = newRequiredItemQty;
         } 
      
         /**
          * Get the quantity required for the purchased item in order to get discount on promoted item.
          * @return requiredItemQty
          */
         public int getRequiredItemQty() {
           return this.requiredItemQty;
         }
         
         /**
          * Set the quantity of promoted item this promotion rule will give.
          * @param newPromotedItemQty
          */
         public void setPromotedItemQty(int newPromotedItemQty) {
            this.promotedItemQty = newPromotedItemQty;
         }
         
         /**
          * Get the quantity of promoted item this promotion rule will give.
          * @return promotedItemQty
          */
         public int getPromotedItemQty() {
            return this.promotedItemQty;
         }
        
         /**
          * Set the catalog entry identification of the promoted item.
          * @param newPromotedProductId
          */
         public void setPromotedProductId(String newPromotedProductId) {
            this.promotedProductId = newPromotedProductId;
         }
        
         /**
          * Get the catalog entry identification of the promoted item.
          * @return promotedProductId
          */
         public String getPromotedProductId() {
            return this.promotedProductId;
         }
      
         /**
          * Set the fix cost for the promoted item.
          * @param newFixCost
          */
         public void setFixCost(String newFixCost) {
            this.fixCost = newFixCost;
         }
        
         /**
          * Get the fix cost for the promoted item,
          * @return fixCost
          */
         public String getFixCost() {
           return this.fixCost;
         }
       
         /**
          * This method is generating the Filter XML object for the promoted item.
          * @return promotedItemFilter the XML String
          */
         protected String getPromotedItemFilter() {
            final String methodName = "getPromotedItemFilter()";
            XmlHelper helper = new XmlHelper();
            StringBuffer buffer = new StringBuffer();
            buffer
               .append("<Filter impl=\"com.ibm.commerce.marketing.promotion.condition.MultiSKUFilter\">")
               .append("<IncludeCatEntryKey>")
               .append("<CatalogEntryKey>");
            try {
               buffer.append(
                  helper.generateProductXMLStringByCatentryId(
                     "SKU",
                     "DN",
                     this.getPromotedProductId()));
            } catch (ECException e) {
               ECTrace.trace(
                  ECTraceIdentifiers.COMPONENT_MERCHANDISING,
                  getClass().getName(),
                  methodName,
                  "CatalogEntryKey Generation Error "
                  + this.getPromotedProductId()
                  + e.toString());
            }
            buffer.append(";</CatalogEntryKey>").append(
               "</IncludeCatEntryKey>").append(
               "</Filter>");
            return buffer.toString();
         }
         protected String getRequiredItemFilter() {
            final String methodName = "getRequiredItemFilter()";
            XmlHelper helper = new XmlHelper();
            StringBuffer buffer = new StringBuffer();
            // The parent class is actually getting the targetted category identification for this promotion.
            buffer.append(
               "<Filter impl=\"com.ibm.commerce.marketing.promotion.condition.CategoryFilter\">");
            for (int i = 0; i < this.getCatalogGroupIDs().size(); i++) {
               buffer.append("<IncludeCategory>").append("<CategoryKey>");
               try {
                  buffer.append(
                     helper.generateCategoryXMLStringByCatgroupId(
                        "Name",
                        "DN",
                        this.getCatalogGroupIDs().elementAt(i).toString()));
               } catch (ECException e) {
                  ECTrace.trace(
                     ECTraceIdentifiers.COMPONENT_MERCHANDISING,
                     getClass().getName(),
                     methodName,
                     "Category Key Generation Error "
                        + this.getCatalogGroupIDs().elementAt(i).toString()
                        + e.toString());
               }
               buffer.append("</CategoryKey>").append("</IncludeCategory>");
           }
           buffer.append("</Filter>");
           return buffer.toString();
         }
      }
      
    11. Sauvegardez le fichier, mais ne fermez pas l'environnement de développement.
  5. Etendez le bean de données RLProductDiscountDataBean qui prend en charge le nouveau type de promotion. Ce nouveau bean de données remplit les nouveaux attributs dans le bloc-notes et les pages de récapitulatif. Pour mettre à jour ce bean de données :
    1. Dans l'environnement de développement HCL Commerce, accédez au projet WebSphereCommerceServerExtensionsLogic.
    2. Cliquez avec le bouton droit de la souris sur le dossier src et sélectionnez Nouveau, puis Package.
    3. Dans la zone Nom de la boîte de dialogue Nouveau package Java, entrez com.myCompany.epromotion.databeans, où myCompany représente le nom de répertoire personnalisé.
    4. Cliquez avec le bouton droit de la souris sur le nouveau package et sélectionnez Nouveau, puis Classe.
    5. Dans la zone Nom, entrez ExtendedPromotionDataBean.
    6. Dans le champ Superclass, entrez ce qui suit : com.ibm.commerce.tools.epromotion.databeans.RLProductDiscountDataBean.
    7. Cliquez sur Terminer. Le fichier s'ouvre dans l'éditeur.
    8. Mettez à jour le bean de données en entrant le code suivant :
      
      package com.myCompany.epromotion.databeans;
      
      import com.ibm.commerce.ras.*;
      import com.ibm.commerce.tools.epromotion.util.*;
      import com.ibm.commerce.tools.epromotion.*;
      import com.ibm.commerce.tools.epromotion.implementations.*;
      import com.ibm.commerce.fulfillment.objects.*;
      import com.myCompany.epromotion.implementations.*;
      import com.myCompany.epromotion.logic.*;
      import com.ibm.commerce.tools.epromotion.databeans.*;
      
      public class ExtendedPromotionDataBean extends com.ibm.commerce.tools.epromotion.databeans.RLProductDiscountDataBean
         implements com.myCompany.epromotion.logic.ExtendedPromotionConstants {
      
            public ExtendedPromotionDataBean() {
               super();
            }
      
            private int rlRequiredItemQty;
            private int rlPromotedItemQty;
            private String rlPromotedProductId;
            private String rlFixCost;
        
            public void setRlRequiredItemQty(int newRlRequiredItemQty) {
               this.rlRequiredItemQty = newRlRequiredItemQty;
            }
            public void setRlPromotedItemQty(int newRlPromotedItemQty) {
               this.rlPromotedItemQty = newRlPromotedItemQty;
            }
            public void setRlPromotedProductId(String newRlPromotedProductId) {
               this.rlPromotedProductId = newRlPromotedProductId;
            }
            public void setRlFixCost(String newRlFixCost) {
               this.rlFixCost = newRlFixCost;
            }
            public int getRlRequiredItemQty() {
               return this.rlRequiredItemQty;
            }
            public int getRlPromotedItemQty() {
               return this.rlPromotedItemQty;
            }
            public String getRlPromotedProductId() {
               return this.rlPromotedProductId;
            }
            public String getRlFixCost() {
               return this.rlFixCost;
            }
            /**
             * Populate method should be implemented based on the new attributes and type.
             * This populate method will handled by TFW parent frame once it is specified
             * in the Notebook.xml configuration.
             */
            public void populate() throws Exception {
               final String methodName = "populate";
               // call super.populate() to get all the RLPromotion object atributes
               super.populate();
               ECTrace.entry(
                  ECTraceIdentifiers.COMPONENT_MERCHANDISING,
                     getClass().getName(),
                     methodName);
               if (this.getCalcodeId() != null) {
                  EproUtil util = new EproUtil();
                  RLPromotionBean rlPromotionBean = new RLPromotionBean();
                  rlPromotionBean.setCalCodeId(this.getCalcodeId());
                  rlPromotionBean.setCommandContext(this.commandContext);
                  rlPromotionBean.setRequestProperties(this.requestProperties);
                  rlPromotionBean.populate();
       
                  // populate the ExtendedPromotionDataBean with RLPromotionBean values
                  RLPromotion rlPromotion = rlPromotionBean.getRLPromotion();
         
                  // The part below is customized for each extended type
                  if (this
                     .getRlPromotionType()
                     .equalsIgnoreCase(PROMOTION_CATEGORYLEVELPWP)) {
                     if (rlPromotion instanceof CategoryLevelPurchaseWithPurchase) {
                        CategoryLevelPurchaseWithPurchase obj =
                        (CategoryLevelPurchaseWithPurchase) rlPromotion;
                        if (obj != null) {
                           this.setRlPromotionCatEntryType("Category");
                           this.setRlPromotionMerchandiseType("Category");
                              if (obj.getCatgpIdentifiers() != null) {
                                 int numOfCatGrps = obj.getCatgpIdentifiers().size();
                                 String[] tempArry = new String[numOfCatGrps];
                                 obj.getCatgpIdentifiers().copyInto(tempArry);
                                 this.setRlPromotionCatGroupCode(tempArry);
                              }
                              if (obj.getCatalogGroupIDs() != null) {
                                 int numOfCatGrps = obj.getCatalogGroupIDs().size();
                                 String[] tempArry = new String[numOfCatGrps];
                                 obj.getCatalogGroupIDs().copyInto(tempArry);
                                 this.setRlPromotionCatGroupID(tempArry);
                              }
                              this.setRlRequiredItemQty(obj.getRequiredItemQty());
                              this.setRlPromotedItemQty(obj.getPromotedItemQty());
                              this.setRlFixCost(obj.getFixCost());
                              this.setRlPromotedProductId(obj.getPromotedProductId());
                              // RLDiscountItemSku is using to retrieve the sku for displaying.
                              this.setRlDiscountItemSku(util.getSKU(obj.getPromotedProductId()));
                        }
                     }
                  }
                  // other customized types will be added here.
               }
            }
         }
      
    9. Sauvegardez le fichier, mais ne fermez pas l'environnement de développement.
  6. Mettez à jour le fichier de définition XML de bloc-notes Promotion en fonction du type de promotion personnalisé. De nouveau, pour la protection de vos données personnalisées, ce fichier doit être créé dans un emplacement sûr, séparé des ressources WebSphere Commerce. La procédure ci-après crée un fichier de définition XML de bloc-notes Promotion. Cette opération ne s'effectue pas dans l'environnement de développement. Pour mettre à jour ce bloc-notes :
    1. Créez un répertoire. Pour les besoins de ce scénario, nommez le répertoire WCDE_installdir/xml/myCustomXML/, où myCustomXML représente un nom de répertoire personnalisé.
    2. Répétez ce processus jusqu'à la création du chemin d'accès suivant :
      
      WCDE_installdir/xml/myCustomXML/tools/epromotion/
      
    3. Copiez le fichier WCDE_installdir/xml/tools/epromotion/RLPromotionNotebook.xml et déplacez le fichier vers le répertoire WCDE_installdir/xml/myCustomXML/tools/epromotion/. Ne changez pas le nom de fichier.
    4. Ouvrez le fichier RLPromotionNotebook.xml dans un éditeur.
    5. Mettez à jour la définition XML pour charger le bean de données personnalisé. Faites défiler le fichier jusqu'à l'élément <databean>. Modifiez le code pour qu'il corresponde à l'exemple suivant :
      
      <databean name="rlpromotion"
      >myCompany.promotions.databeans.ExtendedPromotionDataBean" 
         stoplevel="2" />
      

      Notez qu'un nouvel attribut, Add stoplevel = "2", a également été ajouté. Cet attribut indique que l'objet JavaScript doit également remplir les attributs du bean de données parent de ce bean de données.

    6. Sauvegardez le fichier.
  7. Pour créer un fichier XML personnalisé dans un répertoire personnalisé, vous devez mettre à jour le paramètre XMLPath d'instance. Ce paramètre régit les emplacements dans lesquels l'application va tenter de localiser les fichiers XML. Il fonctionne d'une manière similaire à celle d'un paramètre de chemin de classes Java. Cette opération ne s'effectue pas dans l'environnement de développement. Pour mettre à jour le paramètre XMLPath :
    1. Placez-vous dans le répertoire WCDE_installdir/xml/config.
    2. Ouvrez le fichier wc-server.xml dans un éditeur.
    3. Faites défiler le fichier jusqu'à la section <ToolsGeneralConfig> et redéfinissez XMLPath sur le nom du répertoire personnalisé. Par exemple, si XMLPath a initialement pour valeur :
      
      XMLPath="tools;tools/devtools;WEB-INF/xml/tools;WEB_INF"
      
      et que le répertoire personnalisé est myCustomXML, remplacez la valeur de XMLPath par :
      
      XMLPath="myCustomXML;myCustomXML/tools;tools;tools/devtools;WEB-INF/xml/tools;WEB_INF"
      
    4. Sauvegardez le fichier.

    La modification du paramètre XMLPath dans le fichier de configuration d'instance ne permet cette personnalisation que pour l'instance unique. Toutes les autres instances ne vont pas inclure ce nouveau bouton. Si vous souhaitez appliquer la personnalisation à plusieurs instances, vous devez répéter cette étape pour chacune d'elles.

    Attention

    L'application de groupes de correctifs ou l'exécution d'une migration peuvent écraser les modifications apportées à ce fichier.

  8. Créez un fichier JSP qui permet aux utilisateurs finaux de créer ou de modifier le nouveau type de promotion personnalisé, y compris la condition d'achat et la récompense. Pour créer ce fichier JSP :
    1. Dans l'environnement de développement HCL Commerce, accédez au répertoire CommerceAccelerator/Web Content/tools.
    2. Cliquez avec le bouton droit de la souris sur le dossier et sélectionnez Nouveau, puis Dossier. Dans la zone Nom de dossier, entrez custom.
    3. Cliquez avec le bouton droit de la souris sur le dossier Web Content/tools/custom et sélectionnez Nouveau puis Fichier JSP.
    4. Dans la zone Nom de fichier de la boîte de dialogue Nouveau fichier JSP, entrez CustomizedPWP.jsp.
    5. Accédez au dossier Web Content/tools/custom.
    6. Cliquez deux fois sur le nouveau fichier pour l'ouvrir dans un éditeur.
    7. Mettez à jour le fichier JSP avec le contenu suivant :
      
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <%@ page import="com.ibm.commerce.catalog.beans.CatalogEntryDataBean" %>
      <%@ page import="com.ibm.commerce.tools.epromotion.databeans.RLCatEntrySearchListDataBean" %>
      <%@ page import="com.myCompany.epromotion.databeans.ExtendedPromotionDataBean" %>
      <%@ page import="com.myCompany.epromotion.logic.ExtendedPromotionConstants" %>
      
      <%@include file="../epromotion/epromotionCommon.jsp" %>
      
      <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
      <title>Category Level Purchase with Purchase</title>
      <jsp:useBean id="catBean" scope="page" class="com.ibm.commerce.catalog.beans.CatalogEntryDataBean" />
      <jsp:setProperty property="*" name="catBean" />
      <script>
      var needValidation = false;
      
      </script>
      <%= fPromoHeader%>
      <%
         CommandContext commandContext = (CommandContext) request.getAttribute(ECConstants.EC_COMMANDCONTEXT);
         String storeId = commandContext.getStoreId().toString();
         String catEntryType = null;
         String catEntryId = null;
      
         // ### this javaFlagNotFound is used for javascript validation method to check if the user input is valid or not.
         boolean javaFlagNotFound = true;
         // ### this discountSKU is used to store the user manually input and for SKU validation.
         String discountSKU = request.getParameter("discountSKU");
         String calCodeId = request.getParameter("calCodeId");
         String gotoPanelName = request.getParameter("gotoPanelName");
      
         if ((discountSKU != null) && !(discountSKU.trim().equals("")) )
         {
            RLCatEntrySearchListDataBean searchBean = new RLCatEntrySearchListDataBean();
            searchBean.setCommandContext(commandContext);
      
            searchBean.setSku(discountSKU);
            searchBean.setSkuCaseSensitive("yes");
            searchBean.setSkuOperator("EQUAL");
      
            com.ibm.commerce.beans.DataBeanManager.activate(searchBean, request);
      
            int resultCount =  0;
      
            // Get results from the search query
            CatalogEntryDataBean catalogEntries[] = null;
            catalogEntries = searchBean.getResultList();
            if (catalogEntries != null) {
               resultCount = catalogEntries.length;
            }
            if (resultCount > 0){
               catBean = catalogEntries[0];
               catBean.setCommandContext(searchBean.getCommandContext());
               javaFlagNotFound = false;
               catEntryType = catBean.getType();
               catEntryId = catBean.getCatalogEntryID();
               // This result could be any SKU, including Item/Product/Package
            }
            else {
               javaFlagNotFound = true;
            }
         }
      %>
      
      <script src="/wcs/javascript/tools/common/Util.js">
      </script>
      
      <script language="JavaScript">
      
      var calCodeId = null;
      needValidation = <%= javaFlagNotFound%>;
      
      function initializeState() {
         var cType = '<%=UIUtil.toJavaScript(catEntryType)%>';
         var cId = '<%=UIUtil.toJavaScript(catEntryId)%>';
         var discountSku = '<%=UIUtil.toJavaScript(discountSKU)%>';
         var nextPanel = '<%=UIUtil.toJavaScript(gotoPanelName)%>'
        
         var rlPromo = top.getData("RLPromotion");
         if (rlPromo != null) {
            calCodeId = rlPromo.<%= RLConstants.EC_CALCODE_ID %>;
            parent.put("<%= RLConstants.RLPROMOTION %>",rlPromo);
      
            var pgArray =top.getData("RLPWPPageArray",0);
            if(pgArray != null){
               parent.pageArray = pgArray;
            }
              
         }
         else { 
            if (parent.get) {
               var o = parent.get("<%= RLConstants.RLPROMOTION %>", null);
               calCodeId = o.<%= RLConstants.EC_CALCODE_ID %>;
            }
         }
      
         // Check the calcode_id to see if it's Creation Wizard or Modification Notebook:
         if( calCodeId == null || trim(calCodeId) == ''){
            if(parent.getPanelAttribute("CustomizedPromotionPWPType","hasTab")=="NO") {
               parent.setPanelAccess("CustomizedPromotionPWPType", true);
               parent.setPanelAttribute( "CustomizedPromotionPWPType", "hasTab", "YES" );
               parent.setPanelAccess("RLProdPromoWhat", true);
               parent.setPanelAttribute( "RLProdPromoWhat", "hasTab", "YES" );
               parent.TABS.location.reload();
               parent.setPreviousPanel("RLProdPromoWhat");
            }
            // disable the range panel since we don't use it in this PWP sample.
            parent.setPanelAttribute( "RLProdPromoWizardRanges", "hasTab", "NO" );
            parent.TABS.location.reload();         
         } 
         else {
            parent.setPanelAttribute( "CustomizedPromotionPWPType", "hasTab", "YES" );
            parent.TABS.location.reload();   
         }
       
         if (parent.get) {
            var o = parent.get("<%= RLConstants.RLPROMOTION %>", null);
            var hasMax = false;
            if (o != null) {
               // ### initialize all the form elements by existing object:
               with (document.customizedPWPForm) { 
                  promotedSku.value = o.<%= RLConstants.RLPROMOTION_DISCOUNT_ITEM_SKU %>;
                  fixedCost.value = o.<%= ExtendedPromotionConstants.PROMOTION_FIXCOST %>;
                  if(!isNaN(o.<%= ExtendedPromotionConstants.PROMOTION_PROMOTEDITEMQTY %>))
                  promotedQty.value = o.<%= ExtendedPromotionConstants.PROMOTION_PROMOTEDITEMQTY %>;
                  if(o.<%= ExtendedPromotionConstants.PROMOTION_REQUIREDITEMQTY %> == '1' || 
            o.<%= ExtendedPromotionConstants.PROMOTION_REQUIREDITEMQTY %> == null || 
                     o.<%= ExtendedPromotionConstants.PROMOTION_REQUIREDITEMQTY %> == "")
                     {
                        hasMax = false;
                        maxRad[0].checked=true;
                  }else {
                     if(!isNaN(o.<%= ExtendedPromotionConstants.PROMOTION_REQUIREDITEMQTY %>)) {
                        hasMax = true;
                        maxRad[1].checked=true;
                        minProdPurchaseQty.value = o.<%= ExtendedPromotionConstants.PROMOTION_REQUIREDITEMQTY %>;
                     } 
                  }
                  checkMaxArea(hasMax);
               }
            }  
         }
       
         if (trim(cType) != '' && trim(cId) != '') {
            if (parent.get) {
               var o = parent.get("<%= RLConstants.RLPROMOTION %>", null);
               if (o != null) {
                  o.<%= ExtendedPromotionConstants.PROMOTION_PROMOTEDPRODUCTID %> = "<%=UIUtil.toJavaScript(catEntryId)%>";
               }
            }
            if (calCodeId == null || trim(calCodeId) == '') {
               parent.finish();
            } 
            else {
               if (nextPanel == null || trim(nextPanel) == '' || nextPanel == 'undefined') {
                  parent.finish();
               }
               else {
                  parent.gotoPanel(nextPanel);     
               }
            }
         }
         else {
            if ( (!needValidation && trim(discountSku) != '') && (trim(cType) == null || trim(cType) == '' || trim(cId) == '' || trim(cId) == null)) {
               needValidation = true;
               alertDialog("<%= UIUtil.toJavaScript(RLPromotionNLS.get("RLInvalidItemSKU").toString())%>");      
            }
            else if (needValidation && trim(discountSku) != '') {
               alertDialog("<%= UIUtil.toJavaScript(RLPromotionNLS.get("RLInvalidSKU").toString())%>");
            }
         }
      
         parent.setContentFrameLoaded(true);
      
         if (parent.get("prodQtyTooLong", false)) {
            parent.remove("prodQtyTooLong");
            reprompt(document.customizedPWPForm.promotedQty,"<%= UIUtil.toJavaScript(RLPromotionNLS.get("prodQtyNumberTooLong").toString())%>");
            return;
         }
         if (parent.get("prodQtyNotNumber", false)) {
            parent.remove("prodQtyNotNumber");
            reprompt(document.customizedPWPForm.promotedQty,"<%= UIUtil.toJavaScript(RLPromotionNLS.get("prodMinNotNumber").toString())%>");
            return;
         }
         if (parent.get("reqProdQtyTooLong", false)) {
            parent.remove("reqProdQtyTooLong");
            reprompt(document.customizedPWPForm.minProdPurchaseQty,"<%= UIUtil.toJavaScript(RLPromotionNLS.get("prodQtyNumberTooLong").toString())%>");
            return;
         }
         if (parent.get("reqProdQtyNotNumber", false)) {
            parent.remove("reqProdQtyNotNumber");
            reprompt(document.customizedPWPForm.minProdPurchaseQty,"<%= UIUtil.toJavaScript(RLPromotionNLS.get("prodMinNotNumber").toString())%>");
            return;
         }
         if (parent.get("noSKUEntered", false)) {
            parent.remove("noSKUEntered");
            alertDialog("<%= UIUtil.toJavaScript(RLPromotionNLS.get("SKUNotEntered").toString())%>");
            return;
         }
      }
      function savePanelData() {
         if (parent.get) {
            var o = parent.get("<%= RLConstants.RLPROMOTION %>", null);
            if (o != null) {
               with (document.customizedPWPForm) {
                  o.<%= RLConstants.RLPROMOTION_DISCOUNT_ITEM_SKU %> = promotedSku.value;
                  o.<%= ExtendedPromotionConstants.PROMOTION_FIXCOST %> = fixedCost.value;
                  if (trim(promotedQty.value) != null && trim(promotedQty.value) != "") {
                     o.<%= ExtendedPromotionConstants.PROMOTION_PROMOTEDITEMQTY %> = parent.strToNumber(trim(promotedQty.value),"<%=fLanguageId%>");
                  } 
                  else {
                     o.<%= ExtendedPromotionConstants.PROMOTION_PROMOTEDITEMQTY %> = "";
                  } 
         if (maxRad[1].checked) {
                     if (trim(minProdPurchaseQty.value) != null && trim(minProdPurchaseQty.value) != "")
                     o.<%= ExtendedPromotionConstants.PROMOTION_REQUIREDITEMQTY %> = parent.strToNumber(trim(minProdPurchaseQty.value),"<%=fLanguageId%>");
                     else
                     o.<%= ExtendedPromotionConstants.PROMOTION_REQUIREDITEMQTY %> = "";
                  }
         else {
                     o.<%= ExtendedPromotionConstants.PROMOTION_REQUIREDITEMQTY %> = 1;
                  }
                  if(o.<%= RLConstants.RLPROMOTION_CATENTRY_TYPE %> == 'ProductBean')
                     o.<%= RLConstants.RLPROMOTION_TYPE %> = "<%= ExtendedPromotionConstants.PROMOTION_PRODUCTLEVELPWP %>";
                  else if(o.<%= RLConstants.RLPROMOTION_CATENTRY_TYPE %> == 'ItemBean')
           o.<%= RLConstants.RLPROMOTION_TYPE %> = "<%= ExtendedPromotionConstants.PROMOTION_ITEMLEVELPWP %>";
                  else if(o.<%= RLConstants.RLPROMOTION_CATENTRY_TYPE %> == 'PackageBean')
           o.<%= RLConstants.RLPROMOTION_TYPE %> = "<%= ExtendedPromotionConstants.PROMOTION_ITEMLEVELPWP %>";
                  else if(o.<%= RLConstants.RLPROMOTION_CATENTRY_TYPE %> == 'Category')
           o.<%= RLConstants.RLPROMOTION_TYPE %> = "<%= ExtendedPromotionConstants.PROMOTION_CATEGORYLEVELPWP %>";
               }
            }
         }
         return true;
      }
      
      function validatePanelData() {
         with (document.customizedPWPForm) {
            if(trim(promotedSku.value) == "" || trim(promotedSku.value) == null) {
               alertDialog("<%= UIUtil.toJavaScript(RLPromotionNLS.get("SKUNotEntered").toString())%>");
               return false;
            }
            if(trim(fixedCost.value) == "" || trim(fixedCost.value) == null) {
               alertDialog("The item cost for this promotion is required.");
               return false;
            } 
            else if (!validateCost(fixedCost)) return false;
      
            if (!validateQty(promotedQty)) return false;
            if (maxRad[1].checked) {
               if (!validateQty(minProdPurchaseQty)) return false;
            }
         }
         if (needValidation) {
            this.location.replace("/webapp/wcs/tools/servlet/CustomizedPromotionPWPView?discountSKU=" + document.customizedPWPForm.promotedSku.value);
            return false; // this will force to stay in the same panel
         } else {
            return true; // go to next panel
         } 
      }
      
      function validateNoteBookPanel(gotoPanelName){
         with (document.customizedPWPForm) {
            if(trim(promotedSku.value) == "" || trim(promotedSku.value) == null) {
               alertDialog("<%= UIUtil.toJavaScript(RLPromotionNLS.get("SKUNotEntered").toString())%>");
               return false;
            } 
            if(trim(fixedCost.value) == "" || trim(fixedCost.value) == null) {
               alertDialog("The item cost for this promotion is required.");
               return false;
            } 
            else if (!validateCost(fixedCost)) return false;
      
            if (!validateQty(promotedQty)) return false;
            if (maxRad[1].checked) {
               if (!validateQty(minProdPurchaseQty)) return false;
            }
         }
         if (needValidation) {
            this.location.replace("/webapp/wcs/tools/servlet/CustomizedPromotionPWPView?discountSKU=" + document.customizedPWPForm.promotedSku.value + "&calCodeId=" + calCodeId + "&gotoPanelName="+ gotoPanelName);
            return false; // this will force to stay in the same panel
         } else {
            return true; // go to next panel
         } 
      }
      
      function validateCost(cost) {
         if ( !parent.isValidInteger(trim(cost.value), "<%=fLanguageId%>")) || 
               (!parent.isValidDouble(trim(cost.value), "<%=fLanguageId%>")))  {
            reprompt(cost,"The fixed cost value is not a number.");
            return false;
         } 
         else if (!(eval(parent.strToNumber(trim(cost.value),"<%=fLanguageId%>")) >= 0)) {
            reprompt(cost,"The fixed cost has to be greater than or equals to zero.");
            return false;
         }
         return true;
      }
      
      function validateQty(qtyField) {
         if(parent.strToNumber(trim(qtyField.value),"<%=fLanguageId%>").toString().length > 14) {
            reprompt(qtyField,"<%= UIUtil.toJavaScript(RLPromotionNLS.get("prodQtyNumberTooLong").toString())%>");
            return false;
         }
         else if ( !parent.isValidInteger(trim(qtyField.value), "<%=fLanguageId%>")) {
            reprompt(qtyField,"<%= UIUtil.toJavaScript(RLPromotionNLS.get("prodMinNotNumber").toString())%>");
            return false;
         }
         else if (!(eval(parent.strToNumber(trim(qtyField.value),"<%=fLanguageId%>")) >= 1)) {
            reprompt(qtyField,"<%= UIUtil.toJavaScript(RLPromotionNLS.get("prodMinNotNumber").toString())%>");
            return false;
         }
         return true; 
      }
      
      function checkMaxArea(hasMax) {
         if (hasMax) {
            document.all["maxArea"].style.display = "block";
         }
         else {
            document.all["maxArea"].style.display = "none";
         }
      }
      
      function callSearch() {
         var rlpagename = "CustomizedPromotionPWP";
         savePanelData();
         var productSKU = document.customizedPWPForm.promotedSku.value;
         top.saveModel(parent.model);
         top.saveData(parent.pageArray, "RLPWPPageArray");
         if (parent.get) {
            var o = parent.get("<%= RLConstants.RLPROMOTION %>", null);
            if (o != null) {   
               top.saveData(o,"RLPromotion");
            }
         }
         top.put("inputsku",productSKU);
         // This variable will and value will be used to distinguish which search 
         // function the search page should provide.
         top.put("<%= RLConstants.RLPROMOTION_PROD_SEARCH_PAGE %>",rlpagename);
         top.saveData(productSKU, "inputsku");
         top.setReturningPanel("CustomizedPromotionPWPType");
         top.setContent("<%= RLPromotionNLS.get("ProductSearchBrowserTitle") %>","/webapp/wcs/tools/servlet/RLSearchDialogView?ActionXMLFile=RLPromotion.RLSearchDialog",true);
      }
      
      function setValidationFlag() {
         if(trim(document.customizedPWPForm.promotedSku.value) != '') {
            needValidation = true;
         }
      }
      
      </script>
      <meta name="GENERATOR" content="IBM WebSphere Studio" />
      </head>
      
      <body class="content" onload="initializeState();">
      
      <form name="customizedPWPForm" id="customizedPWPForm">
      
      <h1>Purchase With Purchase</h1>
      <br />
      
      <label for="promotedSkuLabel">Product SKU selected as promoted (required)</label><br />
      <table border="0" cellpadding="0" cellspacing="0" id="customizedPWP_Table_1">
      <tr>
      <td id="customizedPWP_TableCell_1"> 
        <input name="promotedSku" type="text" size="15" maxlength="50" onchange="setValidationFlag()" id="promotedSkuLabel" /> 
      </td>
      <td id="customizedPWP_TableCell_2"> 
        <button type="button" value='Find' name="rlSearchProduct" class="enabled" style="width:auto;text-align:center" onclick="javascript:callSearch();"> Find</button> 
      </td>
      </tr>
      </table>
      
      
      <p><label for="promotedQtyLabel">Number of items to be given for a fixed cost based on purchase (required)</label><br />
      <input name="promotedQty" type="text" size="10" maxlength="14" id="promotedQtyLabel" />
          Items</p>
      <p><label for="fixCostLabel">Fixed cost for each unit of promoted items (required)</label><br />
      <input name="fixedCost" type="text" size="10" maxlength="14" id="fixCostLabel" />
      <script language="JavaScript">
      document.write(parent.getCurrency());
      </script></p>
      
      Minimum qualification<br />
      <input type="radio" name="maxRad" onclick="javascript:checkMaxArea(false);" checked ="checked" id="None" /><label for="None">None</label><br />
      <input type="radio" name="maxRad" onclick="javascript:checkMaxArea(true);" id="MinQty" /><label for="MinQty">Specify a minimum qualification for the promotion</label>
      <div id="maxArea" style="display:none">
       <blockquote>
       <p><label for="purchaseAmount">Required quantity</label><br />
       <input name="minProdPurchaseQty" type="text" size="10" maxlength="14" id="purchaseAmount" />
          Items
       </p>   
       </blockquote>
      </div>
      
      </form>
      </body>
      </html>
      
    8. Sauvegardez le fichier, mais ne fermez pas l'environnement de développement.
  9. Créez une vue correspondant à la nouvelle page du fichier de configuration Struts afin de mapper le nouveau fichier JSP à la vue associée.
    • Dans HCL Commerce version 9.0.0.x: Ajoutez les entrées au fichier struts-config-ext.xml pour pointer vers la page JSP personnalisée. Toutes les modifications de personnalisation doivent être apportées dans struts-config-ext.xml, et non pas dans struts-config.xml. Pour enregistrer la nouvelle vue, procédez comme suit :
      1. Dans l'environnement de développement HCL Commerce, accédez au dossier CommerceAccelerator/Web Content/WEB-INF.
      2. Dans le menu en incrustation du fichier struts-config-ext.xml, sélectionnez Ouvrir.
      3. Ajoutez le code suivant :
      
      <global-forwards>
         <forward name="CustomizedPromotionPWPView" path="/tools/custom/CustomizedPWP.jsp" 
            className="com.ibm.commerce.struts.ECActionForward" /> 
      </global-forwards>
      <!-- Action Mappings --> 
      <action-mappings type="com.ibm.commerce.struts.ECActionMapping">
         <action path="/CustomizedPromotionPWPView"
            type="com.ibm.commerce.struts.BaseAction" />
      </action-mappings>
      
    • Ajoutez les entrées au fichier struts-wcs-accelerator-custom.xml pour pointer vers la page JSP personnalisée. Pour enregistrer la nouvelle vue, accédez au dossier CommerceAccelerator/src dans l'environnement de développement HCL Commerce. Dans le menu en incrustation du fichier struts-wcs-accelerator-custom.xml, sélectionnez Ouvrir. Ajoutez le code suivant :
      <action class="com.ibm.commerce.struts.v2.BaseAction" name="CustomizedPromotionPWPView">
      <param name="https">0:1</param>
      <result name="CustomizedPromotionPWPView">
      <param name="location">/tools/custom/CustomizedPWP.jsp</param>
      <param name="resourceClassName">com.ibm.commerce.tools.command.ToolsForwardViewCommandImpl</param>
      </result>
      </action>
  10. Mettez à jour les fichiers XML d'assistant et de bloc-notes pour reconnaître le nouveau type de promotion. Pour la protection de vos données personnalisées, ces fichiers doivent être créés dans un emplacement sûr, séparé des ressources HCL Commerce. La procédure ci-après crée des fichiers XML de définition d'assistant et de bloc-notes Promotions dans un nouveau répertoire. Cette opération ne s'effectue pas dans l'environnement de développement. Pour ajouter le bouton :

    1. Copiez le fichier WCDE_installdir/xml/tools/epromotion/RLPromotionWizard.xml et déplacez le fichier vers le répertoire WCDE_installdir/xml/myCustomXML/tools/epromotion.
    2. Accédez au répertoire WCDE_installdir/xml/myCustomXML/tools/epromotion.
    3. Ouvrez le fichier RLPromotionWizard.xml dans un éditeur.
    4. Ajoutez le code suivant au nouveau fichier RLPromotionWizard.xml, immédiatement après la section du panneau RLDiscountGWPType :
      
      <panel name="CustomizedPromotionPWPType"
         url="CustomizedPromotionPWPView"
         helpKey=""
         hasTab="NO"
         hasNext="NO" 
         hasFinish="YES" />
      
    5. Enregistrez et fermez le fichier.
    6. Ouvrez dans un éditeur le fichier RLPromotionNotebook.xml modifié à l'étape 6.
    7. Ajoutez le code suivant au nouveau fichier RLPromotionNotebook, immédiatement après la section du panneau RLDiscountGWPType :
      
        <panel name="CustomizedPromotionPWPType"
         url="CustomizedPromotionPWPView"
         helpKey=""
         hasTab="NO" />
      
    8. Enregistrez et fermez le fichier.
  11. Enregistrez le nouveau type d'objet Java en vue de son utilisation par la fabrique de promotion. Pour mettre à jour le registre, ajoutez le code suivant au fichier workspace_dir\WC\xml\tools\epromotion\RLPromotion.xml.
    
      <type name="CategoryLevelPurchaseWithPurchase"
         className="com.myCompany.promotions.implementations.CategoryLevelPurchaseWithPurchase"
         mappingFileRelativePath="" />
    
  12. Modifiez le nouveau fichier CustomizedPWP.jsp pour le traitement correct du flux de panneaux de l'assistant et du bloc-notes.
    1. Ajoutez l'instruction import suivante au début du fichier JSP pour inclure l'objet de bean de données étendu :
      <%@ page import="com.ibm.commerce.tools.epromotion.ExtendedPromotionConstants" %>
    2. Créez un formulaire pour afficher et traiter les éléments de condition d'achat.
    3. Modifiez les méthodes suivantes :
      • initializeState(),
      • savePanelData(),
      • validatePanelData(),
      • validateNoteBookPanel().
      Si nécessaire, mettez à jour les méthodes connexes.
    4. Si le type de promotion le requiert, mettez à jour la méthode validateAllPanels dans le fichier suivant :

      Web Content/javascript/tools/epromotion/rlDiscountNotebook.js

    5. Sauvegardez le fichier, mais ne fermez pas l'environnement de développement.
  13. Mettez à jour le fichier RLPromotionProperties.jsp pour la prise en charge du nouveau type de promotion et de la vue associée. Pour mettre à jour ce fichier JSP :
    1. Dans l'environnement de développement HCL Commerce, accédez au fichier CommerceAccelerator/Web Content/tools/epromotion. Cliquez avec le bouton droit de la souris sur le fichier RLPromotionProperties.jsp, puis sélectionnez Copier.
    2. Cliquez avec le bouton droit de la souris sur le dossier Web Content/tools/custom et sélectionnez Coller.
    3. Accédez au dossier Web Content/tools/custom.
    4. Cliquez deux fois sur le nouveau fichier pour l'ouvrir dans un éditeur.
    5. Etant donné que le fichier personnalisé se trouve dans un autre emplacement, vous devez mettre à jour, dans le fichier JSP, le chemin suivant en fonction de l'emplacement d'origine. Recherchez l'instruction include suivante :
      
      <%@include file="epromotionCommon.jsp" %>
      

      et remplacez-la par :

      
      <%@include file="../epromotion/epromotionCommon.jsp" %>
      
    6. De même, vous devez ajouter une instruction include pour importer la logique personnalisée. Ajoutez ce qui suit au bloc include :
      
      <%@include file="com.myCompany.epromotion.logic.*" %>
      
    7. Mettez à jour l'initialisation du panneau dans la section supérieure de la page JSP. Localisez le code suivant :
      
               } else if (o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= RLConstants.RLPROMOTION_ITEMLEVELBUYXGETYFREE %>" 
                      || o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= RLConstants.RLPROMOTION_PRODUCTLEVELBUYXGETYFREE %>"
                      || o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= RLConstants.RLPROMOTION_CATEGORYLEVELBUYXGETYFREE %>"){
                   parent.setPanelAttribute( "RLProdPromoWhat", "hasTab", "YES");
                   parent.setPanelAttribute( "RLProdPromoGWPType", "hasTab", "YES" );
                   parent.reloadFrames();
               }
            }
            else {
               parent.setPanelAttribute( "RLProdPromoWizardRanges", "hasTab", "NO" );
               parent.setPanelAttribute( "RLDiscountWizardRanges", "hasTab", "NO" );
               parent.reloadFrames();
            }
         }
      }
      

      et mettez-le à jour pour qu'il corresponde au code suivant :

      
               } else if (o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= RLConstants.RLPROMOTION_ITEMLEVELBUYXGETYFREE %>"
                      || o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= RLConstants.RLPROMOTION_PRODUCTLEVELBUYXGETYFREE %>"
                      || o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= RLConstants.RLPROMOTION_CATEGORYLEVELBUYXGETYFREE %>"){
                    parent.setPanelAttribute( "RLProdPromoWhat", "hasTab", "YES");
                    parent.setPanelAttribute( "RLProdPromoGWPType", "hasTab", "YES" );
                    parent.reloadFrames();
               } else if (o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= ExtendedPromotionConstants.PROMOTION_ITEMLEVELPWP %>" 
                      || o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= ExtendedPromotionConstants.PROMOTION_PRODUCTLEVELPWP %>" 
                      || o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= ExtendedPromotionConstants.PROMOTION_CATEGORYLEVELPWP %>"){
                    parent.setPanelAttribute( "RLProdPromoWhat", "hasTab", "YES");
                    parent.setPanelAttribute( "CustomizedPromotionPWPType", "hasTab", "YES" );
                    parent.reloadFrames();
               }
            }
            else {
               parent.setPanelAttribute( "RLProdPromoWizardRanges", "hasTab", "NO" );
               parent.setPanelAttribute( "RLDiscountWizardRanges", "hasTab", "NO" );
               parent.reloadFrames();
            }
         }
      }
      
    8. Mettez à jour la fonction initializePromotionType pour ajouter le nouveau type de promotion dans la liste déroulante. La fonction mise à jour doit correspondre au code suivant (certaines lignes sont coupées ici pour l'affichage) :
      
      function initializePromotionType() {
         document.propertiesForm.rlPromotionType.options[0] = new Option("<%=RLPromotionNLS.get("percentOffPerItem")%>", 
            "<%= RLConstants.RLPROMOTION_PRODUCTLEVELPERCENTDISCOUNT %>", true, true);
         document.propertiesForm.rlPromotionType.options[1] = new Option("<%=RLPromotionNLS.get("fixedAmountOffPerItem")%>", 
            "<%= RLConstants.RLPROMOTION_PRODUCTLEVELPERITEMVALUEDISCOUNT %>", false, false);
         document.propertiesForm.rlPromotionType.options[2] = new Option("<%=RLPromotionNLS.get("fixedAmountOffAll")%>", 
            "<%= RLConstants.RLPROMOTION_PRODUCTLEVELVALUEDISCOUNT %>", false, false);
         document.propertiesForm.rlPromotionType.options[3] = new Option("<%=RLPromotionNLS.get("buyXGetY")%>",  
            "<%= RLConstants.RLPROMOTION_ITEMLEVELSAMEITEMPERCENTDISCOUNT %>", false, false);
         document.propertiesForm.rlPromotionType.options[4] = new Option("<%=RLPromotionNLS.get("freeGiftWithPurchase")%>", 
            "<%= RLConstants.RLPROMOTION_PRODUCTLEVELBUYXGETYFREE %>", false, false);
         document.propertiesForm.rlPromotionType.options[5] = new Option("Purchase with Purchase",
            "<%= ExtendedPromotionConstants.PROMOTION_CATEGORYLEVELPWP %>", false, false);
      }
      
    9. Mettez à jour la fonction initializeState pour initialiser le nouveau type de promotion. Localisez le code suivant :
      
       
      } else if (o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= RLConstants.RLPROMOTION_ITEMLEVELBUYXGETYFREE %>" 
            || o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= RLConstants.RLPROMOTION_PRODUCTLEVELBUYXGETYFREE %>" 
            || o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= RLConstants.RLPROMOTION_CATEGORYLEVELBUYXGETYFREE %>"){
         document.propertiesForm.rlPromotionGroup.options[0].selected = true;
         refreshPromoTypeAndCombinationFields(document.propertiesForm.rlPromotionGroup); 
         document.propertiesForm.rlPromotionType.options[4].selected = true;
         lastGroup = 0;
         lastType = 4;
      }
      

      Immédiatement après ce code, insérez le code suivant :

      
       
      else if (o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= ExtendedPromotionConstants.PROMOTION_CATEGORYLEVELPWP %>" 
            || o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= ExtendedPromotionConstants.PROMOTION_PRODUCTLEVELPWP %>" 
            || o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= ExtendedPromotionConstants.PROMOTION_ITEMLEVELPWP %>"){
         document.propertiesForm.rlPromotionGroup.options[0].selected = true;
         refreshPromoTypeAndCombinationFields(document.propertiesForm.rlPromotionGroup);       
         document.propertiesForm.rlPromotionType.options[5].selected = true;
         lastGroup = 0;
         lastType = 5;
      }
      
    10. Mettez à jour la fonction refreshPromoTypeAndCombinationFields(promGroup) pour le nouveau type. La fonction mise à jour doit correspondre au code suivant (certaines lignes sont coupées ici pour l'affichage). Le code mis à jour est mis en évidence en gras. Ceci est uniquement un exemple de code partiel illustrant le début de la fonction, contenant néanmoins toutes les modifications nécessaires :
      function refreshPromoTypeAndCombinationFields(promGroup) {
         var length = document.propertiesForm.rlPromotionType.options.length;
         for(var i=length-1; i>=0; i--) {
            document.propertiesForm.rlPromotionType.options[i] = null;
         }
      
         var length = document.propertiesForm.inCombination.options.length;
         for(var i=length-1; i>=0; i--) {
            document.propertiesForm.inCombination.options[i] = null;
         }
      
         if(promGroup.options[0].selected) {
            document.propertiesForm.rlPromotionType.options[0] = new Option("<%=RLPromotionNLS.get("percentOffPerItem")%>", 
                  "<%= RLConstants.RLPROMOTION_PRODUCTLEVELPERCENTDISCOUNT %>", true, true);
            document.propertiesForm.rlPromotionType.options[1] = new Option("<%=RLPromotionNLS.get("fixedAmountOffPerItem")%>", 
                  "<%= RLConstants.RLPROMOTION_PRODUCTLEVELPERITEMVALUEDISCOUNT %>", false, false);
            document.propertiesForm.rlPromotionType.options[2] = new Option("<%=RLPromotionNLS.get("fixedAmountOffAll")%>", 
                  "<%= RLConstants.RLPROMOTION_PRODUCTLEVELVALUEDISCOUNT %>", false, false);
            document.propertiesForm.rlPromotionType.options[3] = new Option("<%=RLPromotionNLS.get("buyXGetY")%>",  
                  "<%= RLConstants.RLPROMOTION_ITEMLEVELSAMEITEMPERCENTDISCOUNT %>", false, false);
            document.propertiesForm.rlPromotionType.options[4] = new Option("<%=RLPromotionNLS.get("freeGiftWithPurchase")%>", 
                  "<%= RLConstants.RLPROMOTION_PRODUCTLEVELBUYXGETYFREE %>", false, false);
            document.propertiesForm.rlPromotionType.options[5] = new Option("Purchase with Purchase", 
                  "<%= ExtendedPromotionConstants.PROMOTION_CATEGORYLEVELPWP %>", false, false);
        .
        .
        .
      
    11. Sauvegardez le fichier, mais ne fermez pas l'environnement de développement.
  14. Mettez à jour le fichier RLProdPromoWhat.jsp pour gérer correctement le flux de l'assistant et la nouvelle cible de promotion. Pour mettre à jour ce fichier JSP :
    1. Dans l'environnement de développement HCL Commerce, accédez au dossier CommerceAccelerator/Web Content/tools/epromotion. Cliquez avec le bouton droit de la souris sur le fichier RLProdPromoWhat.jsp et sélectionnez Copier.
    2. Cliquez avec le bouton droit de la souris sur le dossier Web Content/tools/custom et sélectionnez Coller.
    3. Accédez au dossier Web Content/tools/custom.
    4. Cliquez deux fois sur le nouveau fichier pour l'ouvrir dans un éditeur.
    5. Etant donné que le fichier personnalisé se trouve dans un autre emplacement, vous devez mettre à jour, dans le fichier JSP, le chemin suivant en fonction de l'emplacement d'origine. Recherchez l'instruction include suivante :
      
      <%@include file="epromotionCommon.jsp" %>
      

      et remplacez-la par :

      
      <%@include file="../epromotion/epromotionCommon.jsp" %>
      
    6. De même, vous devez ajouter une instruction include pour importer la logique personnalisée. Ajoutez ce qui suit au bloc include :
      
      <%@include file="com.myCompany.epromotion.logic.*" %>
      
    7. Mettez à jour la fonction initializeState qui nécessite plusieurs ajouts :
      1. Ceci est le début de la fonction mise à jour. Ceci est uniquement un exemple de code partiel illustrant le début de la fonction, contenant néanmoins toutes les modifications nécessaires, mises en évidence en gras :
        
        function initializeState() {
           var fromSearchPage = top.get("fromSearchPage");
           // If the user has returned from search page., get RLPromotion object 
           // from top and put it in parent
           if(fromSearchPage != 'undefined' && fromSearchPage == true) {
              top.put("fromSearchPage", false);
              var rlPromo = top.getData("RLPromotion");
              parent.put("<%= RLConstants.RLPROMOTION %>", rlPromo);   
           }
          
           var obj = parent.get("<%= RLConstants.RLPROMOTION %>", null); // Get the object from parent
           if (obj!= null)  { 
              calCodeId = obj.<%= RLConstants.EC_CALCODE_ID %>;
              // merchanType is using to store the type of targeted items: Category, ProductBean, ItemBean
              merchanType = obj.<%= RLConstants.RLPROMOTION_MERCHANDISE_TYPE %>;      
           }
           else {   
              merchanType = top.get("<%= RLConstants.RLPROMOTION_MERCHANDISE_TYPE%>"); 
           }
           if(parent.getPanelAttribute( "RLProdPromoWizardRanges", "hasTab") == "NO") {
              parent.setPanelAttribute( "RLProdPromoWhat", "hasTab", "YES" );
              parent.TABS.location.reload();
           }
            
           if ((merchanType != null) && (merchanType != '')) {
              // if Category already been selected before, do following initilzation:
              if(isPWPType()) {
                 merchanType = 'Category';
              }
              if(merchanType =='Category')
        .
        .
        . 
        
      2. Cette section désactive la sélection d'articles et de produit pour les promotions de nouveau type. Ceci est uniquement un exemple de code partiel. Toutes les modification sont mises en évidence en gras :
        
        .
        .
        .
        if(catList != null && catList.length > 0) {
           document.whatForm.merchandise[2].checked=true;
           document.whatForm.merchandise[2].focus();
           document.all["categorySelect"].style.display = "block";
           if (calCodeId != null && trim(calCodeId) != '' ) {
              document.whatForm.merchandise[0].disabled=true;
              document.whatForm.merchandise[1].disabled=true;
           }
           if (isPWPType()) {
              document.whatForm.merchandise[0].disabled=true;
              document.whatForm.merchandise[1].disabled=true;
           }
           
           for (var i=0; i<catList.length; i++) {
              var nextOptionIndex = document.whatForm.rlCgryList.options.length;
              var createOption = true;
              for (var j=0; j<badCgryArray.length; j++) {
                 if (catList[i] != 'undefined') {
                    if(catList[i] == badCgryArray[j]){
                       createOption = false; 
                       break;
                    }
                 }
              }
              if (createOption) {
                 document.whatForm.rlCgryList.options[nextOptionIndex] = new Option(
                 catList[i], // name
                 catList[i], // value
                 false,    // defaultSelected
                 false);   // selected 
              }
           }
        }
        else {
           document.whatForm.merchandise[2].checked=true;
           document.whatForm.merchandise[2].focus();
           document.all["categorySelect"].style.display = "block";
           if (isPWPType()) {
              document.whatForm.merchandise[0].disabled=true;
              document.whatForm.merchandise[1].disabled=true;
           }
        }
        document.whatForm.rlCgryName.value = "";
        .
        .
        .
        
      3. Enfin, deux autres endroits nécessitent une personnalisation, vers la fin de la fonction initializeState. Ceci est uniquement un exemple de code partiel, contenant néanmoins toutes les modifications nécessaires, mises en évidence en gras. Le fragment de code doit être inclus à la fin de la fonction :
        
           .
           .
           .
           else {
              if (parent.get) {
                 var o = parent.get("<%= RLConstants.RLPROMOTION %>", null);
                 if ((o != null) && (o.<%= RLConstants.RLPRODPROMO_TYPEALIAS %> == "<%= ExtendedPromotionConstants.PROMOTION_CATEGORYLEVELPWP %>")) {
                    document.whatForm.merchandise[2].checked=true;
                    document.whatForm.merchandise[2].focus();
                    showCategorySelectFields();
                    document.whatForm.merchandise[0].disabled=true;
                    document.whatForm.merchandise[1].disabled=true;
                 }   
                 else // In creation when the page is loaded first time, select Product promotion radio button by default
                    {
                    document.whatForm.merchandise[0].checked=true;
                    document.whatForm.merchandise[0].focus();
                    showProductSelectFields(); 
                 }
              }
              else {
                 document.whatForm.merchandise[0].checked=true;
                 document.whatForm.merchandise[0].focus();
                 showProductSelectFields(); 
              }
           }
         
           // initialize the notebook panel:  
              if (parent.get) {
              var o = parent.get("<%= RLConstants.RLPROMOTION %>", null);
              if (o != null) {
                 calCodeId = o.<%= RLConstants.EC_CALCODE_ID %>;
                 whichDiscountType = o.<%= RLConstants.RLPROMOTION_TYPE %>;
                 if( calCodeId != null && calCodeId != '') {
                    if( whichDiscountType != null || whichDiscountType != '') {
                       var pgArray = top.getData("RLProdPromoWhatPageArray");
                       if(pgArray != null) {
                          parent.pageArray = pgArray;
                       }
                       if (whichDiscountType == "<%= RLConstants.RLPROMOTION_ITEMLEVELPERCENTDISCOUNT %>" 
                             || o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= RLConstants.RLPROMOTION_PRODUCTLEVELPERCENTDISCOUNT %>" 
                             || whichDiscountType == "<%= RLConstants.RLPROMOTION_CATEGORYLEVELPERCENTDISCOUNT %>"
                             || whichDiscountType == "<%= RLConstants.RLPROMOTION_ITEMLEVELPERITEMVALUEDISCOUNT %>" 
                             || o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= RLConstants.RLPROMOTION_PRODUCTLEVELPERITEMVALUEDISCOUNT %>" 
                             || whichDiscountType == "<%=  RLConstants.RLPROMOTION_CATEGORYLEVELPERITEMVALUEDISCOUNT  %>"
                             || whichDiscountType == "<%= RLConstants.RLPROMOTION_ITEMLEVELVALUEDISCOUNT %>" 
                             || o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= RLConstants.RLPROMOTION_PRODUCTLEVELVALUEDISCOUNT %>" 
                             || whichDiscountType == "<%=  RLConstants.RLPROMOTION_CATEGORYLEVELVALUEDISCOUNT %>"){
                          parent.setPanelAttribute( "RLProdPromoWizardRanges", "hasTab", "YES" );
                          parent.TABS.location.reload();
                       }else if (whichDiscountType == "<%= RLConstants.RLPROMOTION_ITEMLEVELSAMEITEMPERCENTDISCOUNT %>" 
                             || whichDiscountType == "<%= RLConstants.RLPROMOTION_PRODUCTLEVELSAMEITEMPERCENTDISCOUNT %>" 
                             || whichDiscountType == "<%=  RLConstants.RLPROMOTION_CATEGORYLEVELSAMEITEMPERCENTDISCOUNT %>"){
                          parent.setPanelAttribute( "RLProdPromoBXGYType", "hasTab", "YES" );
                          parent.TABS.location.reload();
                       }else if (whichDiscountType == "<%= RLConstants.RLPROMOTION_ITEMLEVELBUYXGETYFREE %>" 
                             || o.<%= RLConstants.RLPROMOTION_TYPE %> == "<%= RLConstants.RLPROMOTION_PRODUCTLEVELBUYXGETYFREE %>" 
                             || whichDiscountType == "<%=  RLConstants.RLPROMOTION_CATEGORYLEVELBUYXGETYFREE %>"){
                          parent.setPanelAttribute( "RLProdPromoGWPType", "hasTab", "YES" );
                          parent.TABS.location.reload();
                       }
                       else if (whichDiscountType == "<%= ExtendedPromotionConstants.PROMOTION_ITEMLEVELPWP %>" 
                             || whichDiscountType == "<%= ExtendedPromotionConstants.PROMOTION_PRODUCTLEVELPWP %>" 
                             || whichDiscountType == "<%=  ExtendedPromotionConstants.PROMOTION_CATEGORYLEVELPWP %>"){
                          parent.setPanelAttribute( "CustomizedPromotionPWPType", "hasTab", "YES" );
                          parent.TABS.location.reload();
                       }
                    }  //end of if whichDiscountType.
                 }  // end of calcode!=null
              } // end if o!=null
           } // end if parent.get
        
           parent.setContentFrameLoaded(true);
        
           if (parent.get("CategoryNotEntered", false)) {
              parent.remove("CategoryNotEntered");
              alertDialog('<%= UIUtil.toJavaScript(RLPromotionNLS.get("CategoryNotEntered").toString())%>');
              return;
           }
        
           if (parent.get("PurchaseSKUNotEntered", false)) {
              parent.remove("PurchaseSKUNotEntered");
              alertDialog('<%= UIUtil.toJavaScript(RLPromotionNLS.get("PurchaseSKUNotEntered").toString())%>');
              return;
           }
           
           if (parent.get("cannotBeAProduct", false)) {
              parent.remove("cannotBeAProduct");
              alertDialog('<%= UIUtil.toJavaScript(RLPromotionNLS.get("cannotBeAProduct").toString())%>');
              return;
           }
        
        } // end Initialize state
        
    8. Pour que la fonction savePanelData gère correctement le flux de panneaux, mettez-la à jour afin d'ajouter le nouveau type de promotion. La fonction mise à jour doit correspondre au code suivant (certaines lignes sont coupées ici pour l'affichage). Ceci est uniquement un exemple de code partiel, contenant néanmoins toutes les modifications nécessaires. Le fragment de code doit être inclus à la fin de la fonction :
      
            .
            .
            .
                  o.<%= RLConstants.RLPROMOTION_CATGROUP_CODE %> = tempCgryList;     
                  if (calCodeId == null || trim(calCodeId) == '') { 
                     var ranges = o.<%= RLConstants.RLPROMOTION_RANGES %>;
                     var values = o.<%= RLConstants.RLPROMOTION_VALUES %>;
                     if(ranges.length > 2 || (ranges.length == 2 && eval(values[0]) != 0) ) {
                        parent.setNextBranch("RLProdPromoWizardRanges");
                     }
                     else if(o.<%= RLConstants.RLPRODPROMO_TYPEALIAS %> == "<%= RLConstants.RLPROMOTION_PRODUCTLEVELPERCENTDISCOUNT %>") {
                        o.<%= RLConstants.RLPROMOTION_TYPE %> = "<%= RLConstants.RLPROMOTION_CATEGORYLEVELPERCENTDISCOUNT %>";
                        parent.setNextBranch("RLProdPromoPercentType");
                     }
                     else if(o.<%= RLConstants.RLPRODPROMO_TYPEALIAS %> == "<%= RLConstants.RLPROMOTION_PRODUCTLEVELPERITEMVALUEDISCOUNT %>") {
                        o.<%= RLConstants.RLPROMOTION_TYPE %> = "<%= RLConstants.RLPROMOTION_CATEGORYLEVELPERITEMVALUEDISCOUNT %>";
                        parent.setNextBranch("RLProdPromoFixedType");
                     }
                     else if(o.<%= RLConstants.RLPRODPROMO_TYPEALIAS %> == "<%= RLConstants.RLPROMOTION_PRODUCTLEVELVALUEDISCOUNT %>") {
                        o.<%= RLConstants.RLPROMOTION_TYPE %> = "<%= RLConstants.RLPROMOTION_CATEGORYLEVELVALUEDISCOUNT %>";
                        parent.setNextBranch("RLProdPromoFixedType");
                     }
                     else if(o.<%= RLConstants.RLPRODPROMO_TYPEALIAS %> == "<%= RLConstants.RLPROMOTION_ITEMLEVELSAMEITEMPERCENTDISCOUNT %>") {
                        o.<%= RLConstants.RLPROMOTION_TYPE %> = "<%= RLConstants.RLPROMOTION_ITEMLEVELSAMEITEMPERCENTDISCOUNT %>";
                        parent.setNextBranch("RLProdPromoBXGYType");
                     }
                     else if(o.<%= RLConstants.RLPRODPROMO_TYPEALIAS %> == "<%= RLConstants.RLPROMOTION_PRODUCTLEVELBUYXGETYFREE %>") {
                        o.<%= RLConstants.RLPROMOTION_TYPE %> = "<%= RLConstants.RLPROMOTION_CATEGORYLEVELBUYXGETYFREE %>";
                        parent.setNextBranch("RLProdPromoGWPType");
                     }
                     else if(o.<%= RLConstants.RLPRODPROMO_TYPEALIAS %> == "<%= ExtendedPromotionConstants.PROMOTION_CATEGORYLEVELPWP %>") {
                        o.<%= RLConstants.RLPROMOTION_TYPE %> = "<%= ExtendedPromotionConstants.PROMOTION_CATEGORYLEVELPWP %>";
                        parent.setNextBranch("CustomizedPromotionPWPType");
                     }
                  } 
               }
               o.<%= RLConstants.RLPROMOTION_CATENTRY_TYPE %> = trim(skuType );  
            }
         }
      }  
      
    9. Créez une fonction isPWPType. Pour ajouter cette fonction, insérez le code suivant :
      
      function isPWPType() {
         if (parent.get) {    
            var o = parent.get("<%= RLConstants.RLPROMOTION %>", null);
            if ((o != null) && (o.<%= RLConstants.RLPRODPROMO_TYPEALIAS %> == 
                  "<%= ExtendedPromotionConstants.PROMOTION_CATEGORYLEVELPWP %>")) {
               return true;
            }
         else {
               return false;
            }
         }
         else {
            return false;
         }
      }
      
    10. Sauvegardez le fichier, mais ne fermez pas l'environnement de développement.
  15. Créez un libellé pour le panneau de l'assistant. La conception de HCL Commerce sépare la logique du programme des chaînes affichées et, par conséquent, les libellés des éléments d'interface comme les boutons sont stockés dans des fichiers de propriétés, également désignés "regroupements de ressources". Pour éviter l'écrasement de vos données personnalisées pendant la migration vers une version ultérieure, l'installation d'un groupe de correctifs ultérieur ou lors d'un événement similaire, ces fichiers doivent être créés dans un emplacement sûr, séparé des ressources HCL Commerce. La procédure ci-après crée un fichier de propriétés, dans un nouveau dossier, dans l'environnement de développement HCL Commerce :
    1. Dans l'environnement de développement HCL Commerce, accédez au projet WebSphereCommerceServerExtensionsLogic.
    2. Accédez au dossier src.
    3. Cliquez avec le bouton droit de la souris sur le dossier src et sélectionnez Nouveau, puis Package.
    4. Dans la zone Nom de la boîte de dialogue Nouveau package Java, entrez un nom unique. Pour les besoins de ce scénario, entrez com.myCompany.epromotion.properties, où myCompany présente un nom de répertoire personnalisé. Les packages créés par IBM et inclus dans HCL Commerce suivent une convention de dénomination : ils commencent par com.ibm...
    5. Cliquez sur Terminer pour créer le package.
    6. Cliquez avec le bouton droit de la souris sur le dossier com.myCompany.epromotion.properties et sélectionnez Nouveau, puis Autre. Dans la boîte de dialogue Nouveau, cliquez sur Simple, Fichier, puis Suivant.
    7. Dans la zone Nom de fichier, entrez un nom unique. Pour les besoins de ce scénario, entrez RLPromotionNLS_locale.properties, où locale représente l'environnement local à partir duquel les professionnels vont accéder à HCL Commerce Accelerator.
    8. Cliquez sur Terminer pour créer le fichier et l'ouvrir dans un éditeur.
    9. Pour simplifier la maintenance ultérieure, il est judicieux d'inclure des commentaires dans ce nouveau fichier. Cette zone est facultative mais fortement recommandée. Au début de ce fichier, incluez des commentaires similaires au suivant afin de clarifier l'objectif du fichier :
      
      #
      # Customized properties for Promotions
      #
      # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
      
    10. Faites défiler le fichier et créez une section contenant les "définitions de bouton" du fichier, puis insérez un libellé pour le nouveau bouton. Le code doit ressembler à l'exemple suivant :
      
      #
      # Wizard labels
      #
      
      CustomizedPromotionPWPType=Purchase Condition
      
    11. Sauvegardez le fichier, mais ne fermez pas l'environnement de développement.

    Il s'agit du libellé dans la langue de l'environnement local indiqué lors de la création du fichier. Si vous souhaitez entrer une chaîne dans plusieurs langues, vous devez effectuer cette étape pour chaque langue, en créant un fichier par environnement local correspondant.

    Si un professionnel tente d'accéder à cette page à partir d'un environnement local pour lequel il n'existe pas de prise en charge explicite, la structure d'outils utilise par défaut le fichier RLPromotionNLS.properties qui ne contient pas de chaîne correspondante. Veillez à créer une version du fichier de propriétés accessible à partir de chaque environnement local prévu.

  16. Pour rendre le nouveau fichier de propriétés personnalisé disponible pour les outils du composant, vous devez mettre à jour le fichier resources.xml approprié. Cette opération ne s'effectue pas dans l'environnement de développement. Pour effectuer cette mise à jour :
    1. Copiez le fichier WCDE_installdir/xml/tools/epromotion/resources.xml et déplacez le fichier vers le répertoire WCDE_installdir/xml/myCustomXML/tools/epromotion/.
    2. Ouvrez le fichier resources.xml dans un éditeur.
    3. Faites défiler le fichier jusqu'à la section du "regroupement de ressources" et mettez à jour le code pour qu'il corresponde à l'exemple suivant :
      
      <resourceBundle name="RLPromotionNLS">
          <bundle>com.ibm.commerce.tools.campaigns.properties.RLPromotionNLS</bundle>
          <bundle>com.myCompany.epromotions.properties.RLPromotionNLS</bundle> 
      </resourceBundle>
      
      myCompany représente le nom de répertoire personnalisé.
    4. Sauvegardez le fichier.

    Notez que le fichier de propriétés d'origine se trouve dans le package tools.campaigns.properties. Ceci provient d'une limitation de développement dans une version antérieure, et ne constitue pas une erreur.

  17. Mettez à jour le fichier RLProductSearchResult.jsp pour gérer le nouveau type de promotion. Pour mettre à jour ce fichier JSP :
    1. Dans l'environnement de développement HCL Commerce, accédez au dossier CommerceAccelerator/Web Content/tools/epromotion. Cliquez avec le bouton droit de la souris sur le fichier RLProductSearchResult.jsp et sélectionnez Copier.
    2. Cliquez avec le bouton droit de la souris sur le dossier Web Content/tools/custom et sélectionnez Coller.
    3. Accédez au dossier Web Content/tools/custom.
    4. Cliquez deux fois sur le nouveau fichier pour l'ouvrir dans un éditeur.
    5. Etant donné que le fichier personnalisé se trouve dans un autre emplacement, vous devez mettre à jour, dans le fichier JSP, le chemin suivant en fonction de l'emplacement d'origine. Recherchez l'instruction include suivante :
      
      <%@include file="epromotionCommon.jsp" %>
      

      et remplacez-la par :

      
      <%@include file="../epromotion/epromotionCommon.jsp" %>
      
    6. De même, vous devez ajouter une instruction include pour importer la logique personnalisée. Ajoutez ce qui suit au bloc include :
      
      <%@ page import="com.myCompany.epromotion.logic.ExtendedPromotionConstants" %>
      
    7. Mettez à jour l'initialisation pour gérer le nouveau type de promotion. Ce code définit les ressources de catalogue incluses dans la recherche telles que les articles, les produits ou les packages. Ceci est uniquement un exemple de code partiel illustrant le début de la fonction d'initialisation, contenant néanmoins toutes les modifications nécessaires, mises en évidence en gras :
      
        <body onload="onLoad();" class="content_list">
        
        <%
         catEntSearchListBean.setCommandContext(commandContext);
         try {
            // Execute the search bean
            if (fromPage.equals("RLProdPromoWhat")) {
               if (promoType.equalsIgnoreCase("ProductBean")) {
                  catEntSearchListBean.setIsItem(false);
                  catEntSearchListBean.setIsPackage(false);
                  catEntSearchListBean.setIsProduct(true);
                  catEntSearchListBean.setIsDynamicKit(false);
                  catEntSearchListBean.setIsBundle(false);            
               }  
               else if (promoType.equalsIgnoreCase("ItemBean") || promoType.equalsIgnoreCase("PackageBean")) {
                  catEntSearchListBean.setIsItem(true);
                  catEntSearchListBean.setIsPackage(true); // don't care whether item or package. consider it as item
                  catEntSearchListBean.setIsProduct(false);
                  catEntSearchListBean.setIsDynamicKit(false);
                  catEntSearchListBean.setIsBundle(false);
               }
            }
            else if ( fromPage.equals("RLProdPromoGWP") || fromPage.equals("RLDiscountGWP") ) {
               catEntSearchListBean.setIsItem(true);
               catEntSearchListBean.setIsPackage(false);
               catEntSearchListBean.setIsProduct(false);
               catEntSearchListBean.setIsDynamicKit(false);
               catEntSearchListBean.setIsBundle(false);
            }
            else if ( fromPage.equals("CustomizedPromotionPWP")) {
               catEntSearchListBean.setIsItem(true);
               catEntSearchListBean.setIsPackage(true);
               catEntSearchListBean.setIsProduct(true);
               catEntSearchListBean.setIsDynamicKit(false);
               catEntSearchListBean.setIsBundle(false);
            }
            .
            .
            .
      
    8. Mettez à jour la fonction myRefreshButtons. La fonction mise à jour doit correspondre au code suivant (certaines lignes sont coupées ici pour l'affichage).
      
      function myRefreshButtons() {
         var fromPage = '<%=fromPage%>';
         var checked = parent.getChecked();
         if(checked.length > 1 && (fromPage == "RLProdPromoGWP" || fromPage == "RLDiscountGWP")) {   
            if(defined(parent.buttons.buttonForm.ButtonAddButton)) {
               parent.buttons.buttonForm.ButtonAddButton.disabled=false;
               parent.buttons.buttonForm.ButtonAddButton.className='disabled';
               parent.buttons.buttonForm.ButtonAddButton.id='disabled';
            }
         }
         if(checked.length > 1 && (fromPage == "CustomizedPromotionPWP")) {   
            if(defined(parent.buttons.buttonForm.ButtonAddButton)) {
               parent.buttons.buttonForm.ButtonAddButton.disabled=false;
               parent.buttons.buttonForm.ButtonAddButton.className='disabled';
               parent.buttons.buttonForm.ButtonAddButton.id='disabled';
            }
         }  
      }
      
    9. Mettez à jour la fonction addAction pour le renvoi de page. Ceci est uniquement un exemple de code partiel illustrant la fin de la fonction addAction, contenant néanmoins toutes les modifications nécessaires, mises en évidence en gras :
      
           .
           .
           .
         else if (rlpagename == "RLDiscountGWP") {
            var calCodeId = null;
            var rlPromo = top.getData("RLPromotion", 1);
            if (rlPromo != null) {
               rlPromo.<%= RLConstants.RLPROMOTION_DISCOUNT_ITEM_SKU %> =  partNumber[0];
               rlPromo.<%= RLConstants.RLPROMOTION_GWP_CATENTRY_ID %> = catEntryID[0];
               calCodeId = rlPromo.<%= RLConstants.EC_CALCODE_ID %>;
               top.sendBackData(rlPromo,"RLPromotion");
            }
      
            if( (calCodeId == null) || (calCodeId == '') ) {
               top.goBack();
            }else  {
               top.goBack();
            }
         }
         else if (rlpagename == "CustomizedPromotionPWP") {
            var calCodeId = null;
            var rlPromo = top.getData("RLPromotion", 1);
            if (rlPromo != null) {
               rlPromo.<%= RLConstants.RLPROMOTION_DISCOUNT_ITEM_SKU %> = partNumber[0];
               rlPromo.<%= ExtendedPromotionConstants.PROMOTION_PROMOTEDPRODUCTID %> = catEntryID[0];
               calCodeId = rlPromo.<%= RLConstants.EC_CALCODE_ID %>;
               top.sendBackData(rlPromo,"RLPromotion");
            }
            if( (calCodeId == null) || (calCodeId == '') ) {
               top.goBack();               
            }
            else {
               top.goBack();                
            }
         }
      }
      
    10. Sauvegardez le fichier, mais ne fermez pas l'environnement de développement.
  18. Mettez à jour le fichier RLDiscountDetails.jsp pour gérer le nouveau type de promotion. Pour mettre à jour ce fichier JSP :
    1. Dans l'environnement de développement HCL Commerce, accédez au dossier CommerceAccelerator/Web Content/tools/epromotion. Cliquez avec le bouton droit de la souris sur le fichier RLDiscountDetails.jsp et sélectionnez Copier.
    2. Cliquez avec le bouton droit de la souris sur le dossier Web Content/tools/custom et sélectionnez Coller.
    3. Accédez au dossier Web Content/tools/custom.
    4. Cliquez deux fois sur le nouveau fichier pour l'ouvrir dans un éditeur.
    5. Etant donné que le fichier personnalisé se trouve dans un autre emplacement, vous devez mettre à jour, dans le fichier JSP, le chemin suivant en fonction de l'emplacement d'origine. Recherchez l'instruction include suivante :
      
      <%@include file="epromotionCommon.jsp" %>
      

      et remplacez-la par :

      
      <%@include file="../epromotion/epromotionCommon.jsp" %>
      
    6. De même, vous devez ajouter une instruction include pour importer la logique personnalisée. Ajoutez ce qui suit au bloc include :
      
      <%@ page import="com.myCompany.epromotion.implementations.*" %>
      
    7. Mettez à jour la fonction writeSpecificData. Ceci est uniquement un exemple de code partiel illustrant les modifications à apporter à la fonction writeSpecificData. Le fragment de code doit être inclus à la fin de la fonction :
      
           .
           .
           .
        <%
         if (rlDiscountDetails.getRLPromotionType().equalsIgnoreCase("CategoryLevelPurchaseWithPurchase")){
            if(rlDiscountDetails.getRLPromotion() instanceof CategoryLevelPurchaseWithPurchase) {
               CategoryLevelPurchaseWithPurchase obj = (CategoryLevelPurchaseWithPurchase) rlDiscountDetails.getRLPromotion();
         Vector cgryEntries = null;
         String promotedSkuString = "";
         String cgryString ="";
         String cgryName ="";  
         if (obj != null) {
                  cgryEntries = obj.getCatgpIdentifiers();   
         String catid = obj.getPromotedProductId();
         promotedSkuString = util.getSKU(catid);   
         %>       
                  document.write('<p><%=UIUtil.toJavaScript(RLPromotionNLS.get("RLCategoryDetails").toString())%> ' + '<br>');
                  <%= UIUtil.toJS("categories", cgryEntries)%>
         <%  
                  for (int i=0; i<cgryEntries.size(); i++) {
                     cgryString = cgryEntries.elementAt(i).toString();
                     cgryName = util.getCategoryName(storeId, langId, cgryString);
         %>     
                     document.write('<i><%=UIUtil.toJavaScript(cgryString ).toString()%></i>');
                     document.write(' (<i><%= UIUtil.toJavaScript(cgryName ).toString()%></i>)');  
                     document.write("<br>");
         <%
               } 
         %> 
                  document.write("</p>");      
         <%
                  if(obj.getRequiredItemQty() == -1 ) {   
         %>
                     document.write('<p>');
                     document.write('<i>Get '+'<%=obj.getPromotedItemQty()%>'+' items of '+'<%=promotedSkuString %>'+' at ' + 
                           '<%=obj.getCurrency()%> <%=obj.getFixCost()%>' + ' with any purchase of required category items.</i>');
                     document.write("</p>");      
         <%
                  }
                  else {
         %>
                     document.write('<p>');
                     document.write('<i>Get '+'<%=obj.getPromotedItemQty()%>'+' items of '+'<%=promotedSkuString %>'+' at ' + 
                           '<%=obj.getCurrency()%> <%=obj.getFixCost()%>' + ' with a minimum purchase of '+ '<%=obj.getRequiredItemQty()%>' + 
                           ' required category items.</i>');
                     document.write("</p>");      
         <%
                  }
               } // end of if (obj != null)
            } 
         }
         %>
      
    8. Sauvegardez le fichier, mais ne fermez pas l'environnement de développement.
  19. Pour afficher la description de promotion d'un produit, d'un article ou d'une catégorie sur la page d'accueil du magasin sans avoir recours à une initiative de campagne, vous devez remplir deux tables de relations CATENCALCD et CATGPCALCD. Par exemple, la promotion A (calcode 1001) s'applique lorsqu'un client achète un article de la catégorie B (catalogGroupId 200), pour accorder en récompense le produit C (catentryId 888) à 50 % du prix normal. Vous devez définir la relation entre les attributs CALCODE 1001 et catalogGroupId 200 dans la table CATGPCALCD, ainsi que la relation entre les attributs CALCODE 1001 et catentryId 888 dans la table CATENCALCD. Pour fournir une prise en charge de cette définition de relation dans HCL Commerce Accelerator, procédez comme suit :
    1. Etendez la commande CreateRLPromotionCmdImpl :
      
      public class CustomCreateRLPromotionCmdImpl extends 
          com.ibm.commerce.tools.epromotion.commands.CreateRLPromotionCmdImpl {
      
         /**
          * CustomCreateDiscountCmdImpl constructor.
          */    public CustomCreateRLPromotionCmdImpl() {
                    super();
        
      
      
         /**
          * Create catEntCalcode.
          * @exception com.ibm.commerce.exception.ECSystemException
          *
          */
          public void createCatEntCalCodeBean() throws ECSystemException
          {
              super();
                  if(rlPromotion.getRLPromotionType().equals(RLPROMOTION_CATEGORYLEVELPWP)) {
                  // RLPROMOTION_CATEGORYLEVELPWP is the custom type
                  // registered in the RLPromotion.xml.
                  // Another way to do this if custom type extends from RLItemLevelPromotion type :
                  // if (rlPromotion instanceof RLItemLevelPromotion) {
                  // Populate the CATENCALCD table for all of the products in this 
                  // promotion and calcode. If this type is related to a category, 
                  // then populate the table CATGPCALCD as well.
              }
          }
      
          public void performExecute() throws ECSystemException, ECException {
          try {
              super();
              createCatEntCalCodeBean();
          }   catch (ECException ex)
              {
              throw new ECSystemException(ECMessage._ERR_GENERIC, getClass().getName(),
                     methodName, ex);
              }
              catch (Exception ex)
              {
              throw new ECSystemException(ECMessage._ERR_GENERIC, getClass().getName(), 
                     methodName, ex);
              }}
      }
      
      
      
       
      
    2. De même, vous devez créer une commande personnalisée pour mettre à jour les promotions existantes du nouveau type à l'aide de HCL Commerce Accelerator. Pour fournir cette prise en charge, étendez la commande UpdateRLPromotionCmdImpl en cours :
      
      public class CustomUpdateRLPromotionCmdImpl extends 
         com.ibm.commerce.tools.epromotion.commands.UpdateRLPromotionCmdImpl {
            public CustomUpdateRLPromotionCmdImpl() {
               super();
            }
      
            public void performExecute() throws com.ibm.commerce.exception.ECException 
            {         
               try {            
                  super();
                  this.updateCatEntCalCode();
                  this.updateCatGpCalCode();
               }            
               catch (Exception e) {
                  throw new ECSystemException(ECMessage._ERR_GENERIC, getClass().getName(), 
                     methodName, e);
               }
            }
      
            public void updateCatEntCalCode() throws ECSystemException 
            {     // Remove the old entries, save the updated entries.
                  // Refer to the createCatEntCalCodeBean() method in 
                  // the CustomCreateRLPromotionCmdImpl command.
            }
      
            public void updateCatGpCalCode() throws ECSystemException 
            {     // Remove the old entries, save the updated entries.
                  // Refer to the createCatEntCalCodeBean() method in 
                  // the CustomCreateRLPromotionCmdImpl command.
            }
      }
      
  20. Mettez à jour les vues correspondant aux pages personnalisées du fichier de configuration Struts afin de mapper le nouveau fichier JSP à la vue associée. Les commandes doivent être remplacées dans le fichier de configuration.
    • Pour les installations de HCL Commerce version 9.0.0.x, ajoutez les entrées au fichier struts-config-ext.xml pour pointer vers votre page JSP personnalisée. Toute modification de la personnalisation doit être effectuée dans le fichier struts-config-ext.xml, et non dans le fichier struts-config.xml. Pour enregistrer les nouvelles vues, procédez comme suit :
      1. Dans l'environnement de développement HCL Commerce, accédez au dossier CommerceAccelerator/Web Content/WEB-INF.
      2. Dans le menu en incrustation du fichier struts-config-ext.xml, sélectionnez Ouvrir.
      3. Ajoutez le code suivant :
        
        <global-forwards>
           <forward name="RLPromotionPropertiesView" path="/tools/custom/RLPromotionProperties.jsp" 
              className="com.ibm.commerce.struts.ECActionForward" /> 
           <forward name="RLProdPromoWhatView" path="/tools/custom/RLProdPromoWhat.jsp" 
              className="com.ibm.commerce.struts.ECActionForward" /> 
           <forward name="RLPromotionProdSearchResultView" path="/tools/custom/RLProductSearchResult.jsp" 
              className="com.ibm.commerce.struts.ECActionForward" /> 
           <forward name="RLDiscountDetailsDialogView" path="/tools/custom/RLDiscountDetails.jsp" 
              className="com.ibm.commerce.struts.ECActionForward" /> 
        </global-forwards>
        <!-- Action Mappings --> 
        <action-mappings type="com.ibm.commerce.struts.ECActionMapping">
           <action path="/RLPromotionPropertiesView"
              type="com.ibm.commerce.struts.BaseAction" /> 
           <action path="/RLProdPromoWhatView" 
              type="com.ibm.commerce.struts.BaseAction" /> 
           <action path="/RLPromotionProdSearchResultView"
              type="com.ibm.commerce.struts.BaseAction" /> 
           <action path="/RLDiscountDetailsDialogView" 
              type="com.ibm.commerce.struts.BaseAction" /> 
        </action-mappings>
        
    • Ajoutez les entrées au fichier struts-wcs-accelerator-custom.xml pour pointer vers la page JSP personnalisée. Pour enregistrer les nouvelles vues, procédez comme suit : Dans l'environnement de développement HCL Commerce, accédez au dossier CommerceAccelerator/src. Dans le menu en incrustation du fichier struts-wcs-accelerator-custom.xml, sélectionnez Ouvrir.
      Ajoutez le code suivant :
      <action class="com.ibm.commerce.struts.v2.BaseAction" name="RLPromotionPropertiesView">
      <param name="https">0:1</param>
      <result name="RLPromotionPropertiesView">
      <param name="location">/tools/custom/RLPromotionProperties.jsp</param>
      <param name="resourceClassName">com.ibm.commerce.tools.command.ToolsForwardViewCommandImpl</param>
      </result>
      </action>
      <action class="com.ibm.commerce.struts.v2.BaseAction" name="RLProdPromoWhatView">
      <param name="https">0:1</param>
      <result name="RLProdPromoWhatView">
      <param name="location">/tools/custom/RLProdPromoWhat.jsp</param>
      <param name="resourceClassName">com.ibm.commerce.tools.command.ToolsForwardViewCommandImpl</param>
      </result>
      </action>
      <action class="com.ibm.commerce.struts.v2.BaseAction" name="RLPromotionProdSearchResultView">
      <param name="https">0:1</param>
      <result name="RLPromotionProdSearchResultView">
      <param name="location">/tools/custom/RLProductSearchResult.jsp</param>
      <param name="resourceClassName">com.ibm.commerce.tools.command.ToolsForwardViewCommandImpl</param>
      </result>
      </action>
      <action class="com.ibm.commerce.struts.v2.BaseAction" name="RLDiscountDetailsDialogView">
      <param name="https">0:1</param>
      <result name="RLDiscountDetailsDialogView">
      <param name="location">/tools/custom/RLDiscountDetails.jsp</param>
      <param name="resourceClassName">com.ibm.commerce.tools.command.ToolsForwardViewCommandImpl</param>
      </result>
      </action>
  21. Dans le registre de commandes de HCL Commerce, mettez à jour la table CMDREG pour associer les nouvelles implémentations de commande de tâche à l'interface de commande de contrôleur existante. L'instruction SQL suivante montre un exemple de mise à jour :
    
    update CMDREG set CLASSNAME='CustomCreateRLPromotionCmdImpl' where 
        INTERFACENAME='com.ibm.commerce.tools.epromotion.commands.CreateRLPromotionCmd'
    
    
    update CMDREG set CLASSNAME='CustomUpdateRLPromotionCmdImpl' where 
        INTERFACENAME='com.ibm.commerce.tools.epromotion.commands.UpdateRLPromotionCmd'
    
  22. Testez la personnalisation dans l'environnement de développement. Pour effectuer ce test :
    1. Arrêtez et redémarrez votre instance HCL Commerce de développement.
    2. Lancez HCL Commerce Accelerator.
    3. Dans le menu Marketing, sélectionnez Promotions.
    4. Cliquez sur Nouvelle promotion. Cette opération lance l'assistant Promotion qui doit contenir le nouveau type de remise. Créez une promotion avec le nouveau type.
    5. Parcourez le magasin avec un ID client de test. Compilez un panier répondant aux critères de la nouvelle promotion et déterminez si la promotion est correctement appliquée à la commande. En cas de réussite, cela signifie que la personnalisation a abouti et que vous pouvez propager vers l'environnement de production toutes les modifications apportées à l'environnement de développement (voir étapes suivantes). En cas d'échec, vous devez déterminer la cause de l'erreur et procéder au débogage.
  23. Exportez les ressources mises à jour. Pour exporter les ressources, cliquez avec le bouton droit de la souris sur le nouveau fichier CustomizedPWP.jsp et sélectionnez Exporter. L'assistant d'exportation s'ouvre. Depuis l'assistant d'exportation :
    1. Sélectionnez Système de fichiers et cliquez sur Suivant.
    2. Le fichier CustomizedPWP.jsp est sélectionné.
    3. Veillez également à sélectionner les fichiers suivants :
      • RLPromotionProperties.jsp
      • RLProdPromoWhat.jsp
      • RLProductSearchResult.jsp
      • RLDiscountDetails.jsp
    4. Accédez au dossier WebSphereCommerceServerExtensionsLogic/src/com/myCompany/epromotion/logic, puis sélectionnez le fichier ExtendedPromotionConstants.
    5. Accédez au dossier WebSphereCommerceServerExtensionsLogic/src/com/myCompany/epromotion/implementations, puis sélectionnez le fichier CategoryLevelPurchaseWithPurchase.
    6. Accédez au dossier WebSphereCommerceServerExtensionsLogic/src/com/myCompany/epromotion/databeans, puis sélectionnez le fichier RLProductDisountDatabean.
    7. Accédez au dossier WebSphereCommerceServerExtensionsLogic/src/com/myCompany/epromotion/properties, puis sélectionnez le fichier RLPromotionsNLS_locale.properties.
    8. Sélectionnez Créer une structure de répertoire pour les fichiers sélectionnés.
    9. Dans la zone du répertoire de destination, entrez un répertoire temporaire pour y placer ces ressources. Par exemple, entrez C:\ExportTemp\StoreAssets
    10. Cliquez sur Terminer.
    11. Si vous y êtes invité, créez le répertoire indiqué.
  24. Transférez les ressources mises à jour vers l'environnement de production. Pour transférer les fichiers :
    1. Sur la machine cible, localisez le répertoire .ear de l'instance HCL Commerce. Voici un exemple de répertoire :
      • For IBM i OS operating system /QIBM/ProdData/WebAsAdv4/installedApps/ WAS_node_name/ WC_instance_name.ear
      • LinuxAIX /WAS_installdir/installedApps/cellName/ WC_instance_name.ear
      • Windows/WAS_installdir\installedApps\cellName\WC_ instance_name.ear

      Où :

      instance_name
      Nom de votre instance HCL Commerce.
      For IBM i OS operating system WAS_node_name
      For IBM i OS operating systemSystème sur lequel le produit WebSphere Application Server est installé.
      nomCellule
      Nom de cellule WebSphere Application Server.
    2. Copiez les fichiers exportés à l'étape 22 ci-dessus dans les répertoires suivants :
      CustomizedPWP.jsp
      WC_eardir/CommerceAccelerator.war/tools/custom
      RLPromotionProperties.jsp
      WC_eardir/CommerceAccelerator.war/tools/custom
      RLProdPromoWhat.jsp
      WC_eardir/CommerceAccelerator.war/tools/custom
      RLProductSearchResult.jsp
      WC_eardir/CommerceAccelerator.war/tools/custom
      RLDiscountDetails.jsp
      WC_eardir/CommerceAccelerator.war/tools/custom
      myCampaignsRB_locale.properties
      WC_eardir/properties/com/myCompany/epromotion/properties
    3. Transférez les fichiers suivants vers votre environnement de production :
      /xml/myCustomXML/tools/epromotion/RLPromotionWizard.xml
      copiez dans AppServer/V6/Base/profiles/instance_name/installedApps/WC_instance_name_cell/WC_instance_name.ear/xml/myCustomXML/tools/epromotion/RLPromotionWizard.xml
      /xml/myCustomXML/tools/epromotion/RLPromotionNotebook.xml
      copiez dans AppServer/V6/Base/profiles/instance_name/installedApps/WC_instance_name_cell/WC_instance_name.ear/xml/myCustomXML/tools/epromotion/RLPromotionNotebook.xml
      /xml/myCustomXML/tools/epromotion/resources.xml
      copiez dans AppServer/V6/Base/profiles/instance_name/installedApps/WC_instance_name_ce ll/WC_instance_name.ear/xml/myCustomXML/tools/epromotion/resources.xml
    4. Répliquez dans la version d'exécution du fichier RLPromotion.xml les modifications apportées au cours de l'étape 11. Ce fichier se trouve dans le répertoire suivant :

      AppServer/V6/Base/profiles/instance_name/installedApps/WC_instance_name_ce ll/WC_instance_name.ear/xml/tools/epromotion/

      La modification requise consiste à ajouter le bloc de code suivant afin d'enregistrer le nouveau type d'objet Java pour utilisation par la fabrique de promotion.
      <type name="CategoryLevelPurchaseWithPurchase" 
         className="com.myCompany.promotions.implementations.CategoryLevelPurchaseWithPur
      chase" 
         mappingFileRelativePath=""/>
      
    5. Mettez à jour le fichier de configuration HCL Commerce .