Vue boîte noire de l'architecture du moteur de promotion

Le moteur de promotion est au coeur du composant de promotion. Le moteur de promotion est encadré de trois ensembles d'API : les API de gestion de persistance, les API de gestion de dépendance et les API d'exécution.

Le diagramme suivant présente le moteur de promotion sous forme de boîte noire.

Moteur de promotion sous forme de boîte noire

Le bloc central dans le diagramme représente le moteur de promotion. Le moteur de promotion est bien isolé par les trois ensembles d'API, comme illustré dans le diagramme.

Le premier groupe d'API est constitué par les API de gestion de la persistance. Celles-ci définissent les interactions entre le moteur de promotion et un système de stockage persistant. Ce stockage persistant permet au moteur de promotion de faire perdurer des objets persistants tels que promotions, stratégies de promotion, résultats de l'application de promotions à des commandes et statistiques.

Le second groupe d'API est constitué par la couche de définition des dépendances. Cette couche définit comment le moteur de promotion voit HCL Commerce en définissant un ensemble d'interfaces telles que commande, client, profil client et entrée de catalogue. Elle définit les dépendances d'objet du moteur de promotion vis-à-vis de HCL Commerce. HCL Commerce utilise un modèle de données particulièrement complexe. Le moteur de promotion n'est pas concerné par tous les détails du modèle de données. En définissant l'API de dépendances, le moteur de promotion déclare explicitement comment il utilise le modèle de données de HCL Commerce et s'isole des modifications intervenant dans le modèle de données HCL Commerce.

Le troisième groupe d'API est constitué par les API d'exécution. Ces API réalisent deux tâches. Elles fournissent d'abord une API d'initialisation système. Actuellement, cela est appelé par le serveur HCL Commerce. Lors de son initialisation, le serveur Commerce appelle cet ensemble d'API, en transmettant les informations de configuration au moteur de promotion, et indique au moteur de promotion de s'initialiser. Sa seconde tâche consiste à fournir une API d'appel avec laquelle le sous-système de commandes de HCL Commerce appelle le moteur de promotion lors de la préparation d'une commande. Il définit les données d'entrée et de sortie de la méthode d'appel, ainsi que les cas d'exception éventuels et les codes d'erreur.

HCL Commerce est exposé comme le bloc le plus externe. Il contient le modèle de données traditionnel de HCL Commerce , la logique métier et le mécanisme de gestion de la persistance. HCL Commerce fournit au moteur de promotion des services de gestion de la persistance à l'aide de l'API de gestion de persistance définie et implémente la couche de dépendances requise par le moteur de promotion à l'aide du modèle de données traditionnel de HCL Commerce.

Les caractéristiques de l'API sont décrites de manière plus détaillée dans les sections suivantes.

API d'exécution et intégration avec le sous-système de commandes

L'ensemble d'API d'exécution comprend deux appels. La première méthode gère l'initialisation du système. Comme il est très peu probable que cette API requière une personnalisation quelconque, cette section se consacre aux API d'appel. Les API d'appel du moteur de promotion contiennent une seule méthode sur l'interface PromotionEngine et un paramètre d'entrée et de sortie unique, dénommé PromotionArgument. PromotionRuntimeException constitue l'unique exception définie et représente une exception non contrôlée.

La définition de la méthode est la suivante :


PromotionArgument invoke(
    String template,
    Long orderId,
      boolean discardPreviousResult,
      boolean saveCurrentResult,
      Hashtable NVP)
throws PromotionRuntimeException;

Le premier paramètre de cette méthode, appelé template, est une chaîne. Ceci définit le nom du modèle utilisé pour appelé le moteur. Les modèles sont le mode d'appel prescrit du moteur de promotion. Un modèle contient une liste ordonnée de promotions. Les modèles sont configurés dans le fichier XML de configuration de promotion. Ce fichier est abordé plus loin dans ce document. Le fragment XML ci-dessous présente une configuration de modèle classique. Les commentaires dans le fragment XML expliquent l'objet de chaque section du fragment.


<Template>
      <!-- A template has a key, comprised of a reference to the owning 
        store, and string name unique within the store. If the store reference 
        refers to the "NullEntity" store of the "root organization", this 
        template is considered a "wildcard" template. If the promotion engine 
        is called in a store for which no template with the given name can be 
        found. The promotion engine searches wildcard templates and attempts 
        to find a name match. If a match is found, this wildcard template is 
        used with all the references to "NullEntity" store replaced with 
        references to the store within which the promotion engine is called. 
        This includes all of the store references in the group key definition 
        in the template.
        -->

   <TemplateKey>
      <!--A template is identified by a key which is made up of a reference 
        to a store and a string identifier unique within the store. -->

      <StoreKey>
         <DN>o=root organization</DN>
         <Identifier>NullEntity</Identifier>
      </StoreKey>
         <!--This is the string identifier. Currently, the only template used 
           by HCL Commerce is named "All Promotions".
         -->
      <Name>All Promotions</Name>
   </TemplateKey>

      <!-- This section defines for the template, which of the following four 
        monetary values associated with an order and order items are present:
        
              Price
              Tax
              Shipping Charge
              Tax on Shipping Charge
             -->

     <MonetaryValuePresence>
            <Price>true</Price>
            <ShippingCharge>false</ShippingCharge>
            <Tax>false</Tax>
            <ShippingTax>false</ShippingTax>
      </MonetaryValuePresence>

          <!-- list of promotion groups will be given -->

        <PromotionGroupKey>
            <StoreKey>
               <DN>o=root organization</DN>
                 <Identifier>NullEntity</Identifier>
            </StoreKey>
            <GroupName>ProductLevelPromotion</GroupName>
         </PromotionGroupKey>
         <PromotionGroupKey>
            <StoreKey>
          <DN>o=root organization</DN>
          <Identifier>NullEntity</Identifier>
       </StoreKey>
       <GroupName>OrderLevelPromotion</GroupName>
     </PromotionGroupKey>
     <PromotionGroupKey>
        <StoreKey>
           <DN>o=root organization</DN>
           <Identifier>NullEntity</Identifier>
        </StoreKey>
        <GroupName>ShippingPromotion</GroupName>
     </PromotionGroupKey>
  </Template>

Actuellement, le seul modèle utilisé par HCL Commerce est nommé "All Promotions" ("toutes les promotions"). Il contient les groupes de promotions "ProductLevelPromotion", "OrderLevelPromotion" et "ShippingPromotion", dans cet ordre. Lorsque ce modèle est appelé, la seule valeur monétaire disponible pour une commande ou un article est celle concernant le prix. Les taxes, les frais de port et les taxes afférentes aux frais de port ne sont pas calculés lors de l'appel du moteur de promotion.

Le second paramètre de cette méthode, appelé orderId, est de type Long. Il s'agit de la clé primaire de la commande à laquelle les promotions éventuelles doivent être appliquées.

Le troisième et le quatrième paramètre cette méthode sont de type booléen. Le troisième paramètre se dénomme "discardPreviousResult". Il s'agit d'une directive adressée au moteur de promotion. Elle lui indique d'éliminer toutes les informations antérieures sur l'application de promotions à la commande en cours, c'est-à-dire à celle dont la clé primaire est spécifiée dans l'appel. Lorsque le troisième paramètre est défini à 'true', les résultats antérieurs sont ignorés. Si sa valeur est définie à 'false', les résultats antérieurs sont chargés en mémoire et l'évaluation des promotions continue à partir de son point d'arrêt précédent, les appels au moteur de promotion étant alors avec état. (En raison d'un problème d'allocation de ressources, l'appel avec état de la fonctionnalité du moteur de promotion n'a pas pu être soumis à un test aussi rigoureux que l'appel sans état. Il est recommandé d'utiliser l'appel sans état pour toute personnalisation éventuelle). Le quatrième paramètre, nommé saveCurrentResult, désigne une autre directive indiquant au moteur de promotion si la persistance des résultats actuels doit être maintenue dans la base de données. Il est généralement défini à 'true'.

Ce dernier paramètre est réservé pour permettre une personnalisation éventuelle requérant des paramètres supplémentaires. Il est du type table de hachage, et représente donc simplement un détenteur de paires nom-valeur. Notez toutefois que l'un des objets usuels de HCL Commerce, CommandContext, est enregistré sur cette table de hachage avec le nom "cmdContext".

Le moteur de promotion renvoie une exception PromotionRuntimeException s'il rencontre une erreur irrécupérable. Il s'agit généralement d'un événement relativement rare. Les erreurs utilisateur, comme une saisie de code promotion incorrect, ne génèrent pas cette exception. Cette exception est une sous-classe de l'exception non contrôlée RuntimeException.

Ses paramètres d'entrée sont simples. A l'opposé, le paramètre de sortie de la méthode est relativement fécond. Il s'agit du paramètre PromotionArgument.

Remarque : PromotionArgument peut également être utilisé comme paramètre d'entrée. Une nouvelle méthode sur l'implémentation par défaut du moteur de promotion reçoit un élément PromotionArgument en entrée. Il véhicule tous les paramètres d'entrée individuels ainsi que des informations supplémentaires.

Le diagramme ci-dessous présente la structure de la classe. Les signatures détaillées de ces interfaces et de ces classes figurent dans la documentation de l'API de ces entités.

image à insérer ici

PromotionArguments renvoie une liste des éléments de PromotionErrorReport. Actuellement, seuls les problèmes associés à une utilisation incorrecte de codes de promotion et de bons de réduction (codes et coupons incorrects ou arrivés à expiration, par exemple) renvoient des erreurs. Une violation des stratégies de promotion applicables à la commande en cours entraîne la non application de la promotion concernée. Cette situation n'est pas interprétée comme une erreur. Aucun rapport PromotionErrorReport n'est généré dans ce cas.

Outre les rapports d'erreur, PromotionArgument porte une liste d'enregistrements PromotionExecutionRecords. Un enregistrement PromotionExecutionRecord témoigne qu'une promotion a été appliquée une fois à une commande. Si une promotion est appliquée N fois à une commande, N enregistrements PromotionExecutionRecords sont alors renvoyés. Chaque élément PromotionExecutionRecord transporte une grande diversité d'informations.

Il comporte d'abord une référence à la promotion appliquée à la commande en cours. Il héberge aussi le code promotion correspondant si un tel code a été saisi et utilisé pour se qualifier pour cette promotion.

Il peut éventuellement aussi conserver une référence à un bon de réduction si celui-ci a été utilisé dans le cadre de cette promotion.

Fait plus notable, un enregistrement PromotionExecutionRecord renvoie un élément LineItemSet contenant tous les articles de commande (ou des parties de ces articles, si leur quantité est supérieure à 1) targeted par cette promotion. Si un article de commande est ciblé, ceci signifie qu'il est utilisé pour se qualifier pour une promotion. Un article ciblé ne bénéficie pas forcément d'une remise suite à l'application de la promotion. Les articles bénéficiant réellement d'une remise sont dénommés articles de commande affected.

Il s'agit toujours d'un sous-ensemble des articles de commande ciblés. L'enregistrement PromotionExecutionRecord conserve une liste des articles de commande affectés sous forme de tableau d'éléments LineItemSet. Un ajustement correspondant est associé à chaque LineItemSet du tableau. l'ajustement capture les modifications apportées aux articles de commande suite à l'application de cette promotion dans l'élément LineItemSet affecté. Un ajustement peut être associé à un élément LineItemSet de trois manières :

  • L'ajustement est appliqué à chaque unité des articles du LineItemSet. Par exemple, si un ajustement FixedAmountOffAdjustment offre une remise de 5 € et est associé de cette façon à l'élément LineItemSet, chaque unité des articles de la commande dans cet élément bénéficie d'une remise de 5 €. Notez que la remise de 5 € est associée à chaque unité et non pas à chaque article. Ceci est important quand un article de commande est composé de quantités supérieures à 1 unité.
  • L'ajustement est appliqué à tous les articles du LineItemSet. Par exemple, si un ajustement FixedAmountOffAdjustment offre une remise de 5 € et est associé à l'élément LineItemSet de cette façon, une remise de 5 € est appliquée à chaque article et ce, quel que soit le nombre d'articles dans le LineItemSet.
  • L'ajustement est appliqué à la commande dans son ensemble. Dans ce cas, l'élément LineItemSet lui-même n'a pas d'importance. Ceci est l'unique exception où les articles affectés (la commande toute entière) peuvent éventuellement ne pas provenir d'un sous-ensemble des articles ciblés.

L'ajustement est défini en tant qu'interface. Ses différentes implémentations sont répertoriées ci-dessous :

Actuellement, le sous-système des commandes appelle le moteur de promotion via cette API. Les deux commandes qui appellent le moteur de promotion sont les suivantes :

  1. PromotionEngineOrderCalculateCmdImpl
  2. com.ibm.commerce.order.calculation.PromotionEngineDiscountCalculationCodeCombineCmdImpl

Lors de son appel, le moteur de promotion traite toutes les promotions concernant la commande en cours et renvoie un résultat PromotionArgument. Le sous-système de commandes se charge alors d'interpréter les résultats (PromotionArgument) renvoyés par le moteur de promotion et de stocker les tables d'ajustement de la commande et des articles correspondants. En raison de limitations du sous-système de commandes, tous les ajustements ne sont pas pris en charge par celui-ci. La liste des ajustements totalement pris en charge par le sous-système de commandes est la suivante :

  • FreePurchasableGiftAdjustment
  • FixedAmountOffAdjustment
  • FixedAmountOffPriceAdjustment
  • FixedAmountOffVolumeDiscountAdjustment
  • FixedCostAdjustment
  • FixedCostShippingAdjustment
  • PercentOffAdjustment
  • PercentOffPriceAdjustment
  • VoucherAdjustment
Remarque : Pour permettre la prise en charge de VoucherAdjustment, un programme d'écoute doit être enregistré auprès du moteur de promotion pour émettre des bons de réduction lorsqu'une promotion est finalisée. Cet aspect est couvert dans la rubrique programmes d'écoutes et événements de promotions.

Si un type d'ajustement non pris en charge par le sous-système de commandes est utilisé, ce dernier ignore simplement l'ajustement renvoyé par le moteur de promotion. L'auteur du nouvel ajustement doit alors de charger de l'appliquer lorsque la promotion est finalisée.

Modèle de dépendances et dépendances en cours

Les API de dépendances sont le second ensemble d'API qui permettent d'isoler le moteur de promotion du reste de HCL Commerce. Elles décrivent toutes les entités externes dont dépend le moteur de promotion. Ce jeu de dépendances comprend actuellement :

  • Campaign
  • CatalogEntry (entrée de catalogue)
  • Catégorie
  • Customer
  • Profil client
  • Ordre
  • Article de commande
  • Royaume-Uni

Toutes ces entités suivent le même schéma de mise en oeuvre dans le moteur de promotion. Ce schéma est présenté dans le diagramme ci-dessous, où une commande sert à l'illustration :

image à insérer ici

Une clé (OrderKey) est définie pour chacune de ces entités. Cette entité est identifiée en externe par ce biais. La dépendance est déclarée en tant qu'interface (Order). Une fabrique abstraite (OrderFactory) est définie. Cette fabrique recherche et instancie les entités externes. Le moteur de promotion est propriétaire d'un ExternalEntityFactoryRegistry, dans lequel la fabrique concrète (WCSOrderFactory) est enregistrée. Lors de l'exécution, le moteur de promotion interagit avec l'interface de dépendance (Order) et la fabrique abstraite (OrderFactory), implémentés par WCSOrder et WCSOrderFactory.

Le fragment XML est utilisé pour configurer ExternalEntityFactoryRegistry, lequel fait partie de la configuration du moteur de promotion. (Les lignes sont séparées à des fins de présentation.)


<ExternalEntityFactoryRegistry 
          impl="com.ibm.commerce.marketing.promotion.dependency.ExternalEntityFactoryRegistry">
   <OrderFactory 
          impl="com.ibm.commerce.marketing.promotion.integration.dependency.WCSOrderFactory" />
   <OrderItemFactory 
          impl="com.ibm.commerce.marketing.promotion.integration.dependency.WCSOrderItemFactory" />
   <CustomerFactory 
          impl="com.ibm.commerce.marketing.promotion.integration.dependency.WCSCustomerFactory" />
   <CustomerProfileFactory 
          impl="com.ibm.commerce.marketing.promotion.integration.dependency.WCSCustomerProfileFactory" />
   <CatalogEntryFactory 
          impl="com.ibm.commerce.marketing.promotion.integration.dependency.WCSCatalogEntryFactory" />
   <StoreFactory 
          impl="com.ibm.commerce.marketing.promotion.integration.dependency.WCSStoreFactory" />
   <CampaignFactory 
          impl="com.ibm.commerce.marketing.promotion.integration.dependency.WCSCampaignFactory" />
</ExternalEntityFactoryRegistry>

Toutes les huit entités externes dont dépend le moteur de promotion suivent le même schéma de mise en oeuvre. Notez que si vous avez besoin d'exposer des attributs supplémentaires d'une commande, vous pouvez étendre les deux classes en vert dans le diagramme afin d'ajouter l'attribut concerné, puis enregistrer la nouvelle fabrique concrète dans ExternalEntityFactoryRegistry. Notez également que si vous devez intégrer le moteur de promotion avec un autre système que HCL Commerce, un ensemble de dépendances externes différent sera alors requis. Dans le cadre de l'exemple ci-dessus concernant une commande, deux nouvelles classes devront être implémentées pour remplacer celles en vert dans le diagramme.

Persistance

Le dernier jeu d'API qui verrouille le pare-feu autour du moteur de promotion est l'API de gestion de persistance. La persistance des objets suivants du moteur de promotion doit être assurée :

  • Promotion
  • Groupe de promotions
  • Stratégie de promotion
  • Bons de réduction
  • Arguments de promotion
  • Statistiques de promotion
  • Attribut dynamique

La persistance de ces objets est gérée de manière identique. Le diagramme suivant illustre comment est gérée leur persistance par le moteur de promotion, à l'aide d'un exemple de promotion.

image à insérer ici

Le service de persistance requis par le moteur de promotion est défini sous forme d'interface ( PromotionPersistenceManager). Des implémentations concrètes peuvent également être fournies. L'implémentation concrète est ensuite enregistrée auprès de l'élément PersistenceManagerRegistry dont est propriétaire le moteur de promotion. Les caractéristiques de toutes ces classes et interfaces sont présentées dans la documentation de l'API.

Le service fourni par les API de gestion de persistance inclue les opérations C.R.U.D (création, lecture, mise à jour ou suppression) sur les objets nécessitant une persistance. Cet ensemble d'API est la base des outils de création de promotions, y compris HCL Commerce Accelerator.

Le fragment XML ci-dessous est utilisé pour configurer l'élément PersistenceManagerRegistry. Cette opération fait partie de la configuration du moteur de promotion. (Les lignes peuvent être séparées à des fins de présentation.)


<PersistenceManagerRegistry 
          impl="com.ibm.commerce.marketing.promotion.persistence.PersistenceManagerRegistry">
   <PromotionPersistenceManager 
          impl="com.ibm.commerce.marketing.promotion.PromotionSessionBeanPersistenceManager">
      <InitialCacheSize>1024</InitialCacheSize>
      <MaxCacheSize>8192</MaxCacheSize>
   </PromotionPersistenceManager>
   <PromotionPolicyPersistenceManager 
          impl="com.ibm.commerce.marketing.promotion.policy.PromotionPolicySessionBeanPersistenceManager">
      <InitialCacheSize>32</InitialCacheSize>
      <MaxCacheSize>1024</MaxCacheSize>
   </PromotionPolicyPersistenceManager>
   <PromotionGroupPersistenceManager 
          impl="com.ibm.commerce.marketing.promotion.group.PromotionGroupSessionBeanPersistenceManager">
      <InitialCacheSize>32</InitialCacheSize>
      <MaxCacheSize>1024</MaxCacheSize>
   </PromotionGroupPersistenceManager>
   <DynamicAttributePersistenceManager 
          impl="com.ibm.commerce.marketing.promotion.dynattr.DynamicAttributeSessionBeanPersistenceManager>
      <InitialCacheSize>32</InitialCacheSize>
      <MaxCacheSize>1024</MaxCacheSize>
   </DynamicAttributePersistenceManager>
   <PromotionArgumentPersistenceManager 
          impl="com.ibm.commerce.marketing.promotion.runtime.PromotionArgumentSessionBeanPersistenceManager" />
   <CouponPersistenceManager 
          impl="com.ibm.commerce.marketing.promotion.coupon.CouponSessionBeanPersistenceManager" />
   <StatsPersistenceManager 
          impl="com.ibm.commerce.marketing.promotion.stats.StatsSessionBeanPersistenceManager" />
</PersistenceManagerRegistry>