CX Works

CX Works brings the most relevant leading practices to you.
It is a single portal of curated, field-tested and SAP-verified expertise for SAP Customer Experience solutions

Migrate Legacy Promotion Module to Promotion Engine

17 min read

Migrate Legacy Promotion Module to Promotion Engine

SAP Commerce Cloud version 6.0 introduced a new promotion engine, which utilizes a Drools rule engine. This article covers the recommended practices for either maintaining the legacy promotions in 6.x and  strategies to migrate orders with legacy promotions over to the new promotion engine.

Table of Contents

Background

The Promotions Engine was released with SAP Commerce 6.0. With additional features being added in 6.1 and 6.3 both the legacy promotion and voucher modules have been marked for deprecation and will be removed from the platform in Q2 and Q4 2018. For existing solutions that are looking to upgrade to version 6.x this leaves a couple of options:

  1. Upgrade your platform to a 6.x version that has the legacy promotions and vouchers extensions, and continue to use it. This will make your upgrade go quicker. However, at some point down the line, before removing it form the platform you will have to migrate to the new promotion engine.
  2. Upgrade your platform to any 6.x version and at the same time migrate your existing legacy promotions over to the new promotion engine.

Because of the high level of customization associated with promotions, there is no migration tool for promotions, like the one created for the Hybris Management Console (hmc) to backoffice migration. This article will cover both options listed above as well as:

  • Identify functional gaps in the new promotion engine
  • Strategy for migrating from old promotion extension to the promotion engine
    • Cart migration
    • Order migration
  • Recommendations on removal of legacy promotion extension
  • Recommendations on archiving orders with legacy promotions
  • Running sample code/test data/unit tests

Maintaining Legacy Promotion Engine in 6.x

It is possible to run SAP Commerce v6.x with the legacy promotion and voucher modules, but we recommend spending time migrating existing promotions to the new promotion engine because eventually the legacy promotions/voucher extensions will be deprecated and will no longer be supported. Understandably, migrating orders and promotions can be a large task, so you might decide to use the legacy promotion modules.

If you wish to continue to use legacy promotions/vouchers in 6.x ensure you have completed the following:

  1. Your localextensions.xml should be referencing the legacy extensions:

    <extension name="promotions" />
    <extension name="voucher" />
    <extension name="hmc" />
  2. In your localextensions.xml make sure you've removed any references to the new rule engine (for example, rulebuilderbackoffice, promotionenginebackoffice, droolsruleengineservices, promotionenginesamplesaddon, promotionengineservices, couponservices, and others).

  3. In your accelerator storefront extension,  ensure the following dependency (if it exists) is commented out:

    <!--<requires-extension name="promotionenginesamplesaddon"/>-->
  4. Complete the remainder of your upgrade as per the Upgrade Project Framework

Functional Gaps in New Promotions Engine

This table outlines all of the promotions that were available from the legacy promotion extension and if its functionality can be replicated through the new promotion engine as of SAP Commerce version 6.3:

Promotion Type Functionally Reproduced in 6.3
Order threshold change delivery mode Available
Order threshold fixed discount Available
Order threshold free gift Available
Order threshold perfect partner    x Available
Bundle Available
Buy X get Y free Available
AcceleratorProductBOGOFPromotion Available
Fixed price Available
Multi-buy Available
AcceleratorProductMultiBuyPromotion Available
One to one perfect partner bundle Available

Percentage discount

Available

Perfect partner

Available
Perfect partner bundle Available
Stepped Multi-buy Not Available

As you can see, currently the stepped multi-buy can not be ported over to the new 6.3 promotions-engine. You might be able to reproduce the behaviour through the use of multiple promotions (for instance, one for each step of the stepped multi-buy promotion) but you can't encapsulate all of the steps within a single promotion currently – for the purpose of this article I will consider that it's functional counterpart in the promotions engine is not available. The rest of the legacy promotions are available using the new promotions engine, so the feature gap is relatively low.

Migrating to the new promotion engine

Pre-Requisites

We recommend you complete the. steps below while the application nodes are unavailable to the public, because some of the steps interfere with the customers browsing experience. Once all migration steps are completed, then you can open up your application again for public browsing. Be sure to schedule downtime for your site to execute these steps.

Additionally, we recommend being on the latest version of SAP Commerce Cloud, to take advantage of all the performance and bug fixes related to the promotion engine.

The general strategy to migrate the old promotion extension to the new promotion extension is relatively straight forward. The steps are the following:

  1. Disable new users from using the site while migrating.
  2. Modify the localextensions.xml to include the following:

    localextensions.xml
    <extension name='rulebuilderbackoffice' />
    <extension name='promotionenginebackoffice' />
    <extension name='droolsruleengineservices' />
    <extension name='promotionenginesamplesaddon' />
  3. In your accelerator storefront extension ensure the following dependency (if it exists) is included:

    <requires-extension name="promotionenginesamplesaddon"/>
  4. Build and run the platform from the command line:

    Command Line
    ant clean all
  5. Update running system with all options checked after you have started up the application. At the very least make sure the following project data is set:

    1. atddengine

    2. ruleengine

    3. ruleengineservices

    4. ruledefinitions

    5. droolsrulesengineservices

    6. promotionengineservices

    7. (optional) promotionenginesamplesaddon

    8. voucherbackoffice
    9. ruleenginebackoffice

    10. rulebuilderbackoffice

    11. promotionsbackoffice

    12. promotionenginebackoffice

    13. couponbackoffice

    This will create essential data to run. If you do not want essential data to run, you can verify the steps below in your test environment without the box checked.

  6. Create equivalent promotions using the new promotion engine for any promotion created using legacy promotion (see sample IMPEX below).
  7. Publish the new promotions.
  8. Confirm the promotions are working on the site (no need to complete the order, but at least maker sure the carts are now picking up the promotions).
  9. Create the cron job (see process below) in the system with the following script:

    INSERT_UPDATE ServicelayerJob;code[unique=true];springId[unique=true]
    ;migrateLegacyPromotionsForOrdersCronJob;migrateLegacyPromotionsForOrdersCronJob
    
    INSERT_UPDATE MigrateLegacyPromotionsForOrdersCronJob;code[unique=true];job(code)[default=migrateLegacyPromotionsForOrdersCronJob];sessionLanguage(isoCode)[default=en]
    ;migrateLegacyPromotionsForOrdersCronJob
  10. Run the cron job.
  11. Check the result, if SUCCESS, then all orders have been migrated, if ERROR, check the logs to determine the orders that had a problem and identify the root cause


Note: To revert to the legacy promotions extension see legacy section above

Sample IMPEX

Here is an example IMPEX that creates equivalent promotion engine promotions for the legacy promotions that come with SAP Commerce.

There is no default way of determining the equivalency of a legacy promotion with a promotion engine rule. We recommend you name the promotion engine rule using the same code as the legacy promotion, as it makes the lookup much easier later.

Mapping of legacy promotions to promotion engine IMPEX
INSERT_UPDATE PromotionSourceRule;code[unique=true];uuid;priority;maxAllowedRuns;stackable[default=false];ruleGroup(code);conditions;actions;website(Identifier)[default=$defaultPromoGrp]
;10DiscountCanonEOS450D;10DiscountCanonEOS450D;500;1;true;productPromotionRuleGroup;[{"definitionId":"y_qualifying_products","parameters":{"products_operator":{"uuid":"cdd760b9-7571-4f4d-bffa-6fd7ac3b93c4","type":"Enum(de.hybris.platform.ruledefinitions.CollectionOperator)","value":"CONTAINS_ANY"},"quantity":{"uuid":"edd3bdb5-c283-4d22-afdc-d4d0d29c8fdf","type":"java.lang.Integer","value":1},"operator":{"uuid":"94d0b427-6287-4688-9f6b-a2c8a41a13a1","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"LESS_THAN_OR_EQUAL"},"products":{"uuid":"87075d2f-3d76-49d8-bba7-abe16e4e3e40","type":"List(ItemType(Product))","value":["1382080","1382080"]}},"children":[]}];[{"definitionId":"y_order_entry_percentage_discount","parameters":{"value":{"uuid":"e5e8d897-421a-46b7-bde1-d9a2aa9420c2","type":"java.math.BigDecimal","value":10.00}}}];
;BOGOFElectronics;BOGOFElectronics;700;1;true;productPromotionRuleGroup;[{"definitionId":"y_container","parameters":{"id":{"uuid":"452439f1-19e9-4b6f-8282-a1ff02beb1c1","type":"java.lang.String","value":"CONTAINER_X"}},"children":[{"definitionId":"y_qualifying_categories","parameters":{"quantity":{"uuid":"d16683f6-f438-424f-b432-09794924a7b1","type":"java.lang.Integer","value":1},"categories_operator":{"uuid":"1968dded-7216-4b4c-9d30-914ac29f7757","type":"Enum(de.hybris.platform.ruledefinitions.CollectionOperator)","value":"CONTAINS_ANY"},"excluded_categories":{"uuid":"b7ab8beb-df20-46f1-9657-15dac1ba3a37","type":"List(ItemType(Category))"},"categories":{"uuid":"fce6d79d-cd7e-471e-9f60-4822b0f7998a","type":"List(ItemType(Category))","value":["902"]},"excluded_products":{"uuid":"b174597d-150e-4bda-a4f5-c013bc3ae9fd","type":"List(ItemType(Product))"},"operator":{"uuid":"56dc934c-cb3e-44e3-9639-0d6771b808a7","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"}},"children":[]}]},{"definitionId":"y_container","parameters":{"id":{"uuid":"7f1c6efd-f7d1-4f82-86ab-f102886f1da0","type":"java.lang.String","value":"CONTAINER_Y"}},"children":[{"definitionId":"y_qualifying_categories","parameters":{"quantity":{"uuid":"bde69a9d-2afc-4262-9ac3-bd274ee7638a","type":"java.lang.Integer","value":1},"categories_operator":{"uuid":"98d07bef-b1c7-43c5-972b-68cd2453ddf3","type":"Enum(de.hybris.platform.ruledefinitions.CollectionOperator)","value":"CONTAINS_ANY"},"excluded_categories":{"uuid":"c6122d09-6456-4b36-bdcd-024276d8b499","type":"List(ItemType(Category))"},"categories":{"uuid":"a0116fcc-777d-425f-bb21-4e5d9842da0a","type":"List(ItemType(Category))","value":["902"]},"excluded_products":{"uuid":"67d1b3a1-9ce6-4447-a638-98a653baafee","type":"List(ItemType(Product))"},"operator":{"uuid":"92f3cf59-8d5d-4db6-a24f-1d449ba5c5f9","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"}},"children":[]}]}];[{"definitionId":"y_partner_order_entry_percentage_discount","parameters":{"selection_strategy":{"uuid":"7ca69abf-0e6b-4ce6-90d6-f30cc039265b","type":"Enum(de.hybris.platform.ruleengineservices.enums.OrderEntrySelectionStrategy)","value":"CHEAPEST"},"qualifying_containers":{"uuid":"fccf5966-332e-438f-bbe0-7ab809b49c3f","type":"Map(java.lang.String,java.lang.Integer)","value":{"CONTAINER_X":3}},"target_containers":{"uuid":"08a56fb7-23bb-49f0-b350-47c2b24b9462","type":"Map(java.lang.String,java.lang.Integer)","value":{"CONTAINER_Y":1}},"value":{"uuid":"4e8aa924-5ce6-4d42-9966-dc3ee3d90ca3","type":"java.math.BigDecimal","value":100}}}];
;BundlePricing;BundlePricing;1000;1;true;productPromotionRuleGroup;[{"definitionId":"y_container","parameters":{"id":{"uuid":"445e1073-21aa-42f9-b75e-c9a1aecb1d0f","type":"java.lang.String","value":"CONTAINER_X"}},"children":[{"definitionId":"y_qualifying_products","parameters":{"products_operator":{"uuid":"d4f1d3ad-d58e-4761-8d97-fe7bb322a99d","type":"Enum(de.hybris.platform.ruledefinitions.CollectionOperator)","value":"CONTAINS_ALL"},"quantity":{"uuid":"e2a5d144-de8e-4166-be90-b91d1be3d457","type":"java.lang.Integer","value":1},"operator":{"uuid":"2ab1cc07-83ef-48a4-bcdd-72c7870cb830","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"},"products":{"uuid":"5a2f8422-4e9c-4c94-9910-5db11e366a28","type":"List(ItemType(Product))","value":["816323","816262"]}},"children":[]}]}];[{"definitionId":"y_target_bundle_price","parameters":{"selection_strategy":{"uuid":"a3221bcf-2c08-420e-9ea2-4204d8905150","type":"Enum(de.hybris.platform.ruleengineservices.enums.OrderEntrySelectionStrategy)","value":"DEFAULT"},"qualifying_containers":{"uuid":"5877a227-fc0b-4483-b060-c9ed9645a882","type":"Map(java.lang.String,java.lang.Integer)","value":{"CONTAINER_X":2}},"value":{"uuid":"6460c7f4-a32b-41d5-910e-066237e3ce2f","type":"Map(ItemType(Currency),java.math.BigDecimal)","value":{"USD":150.0}}}}];
;BuyXGetYFree;BuyXGetYFree;1000;1;true;productPromotionRuleGroup;[{"definitionId":"y_container","parameters":{"id":{"uuid":"6f3e2d14-59fe-40a6-96d8-cbbdd8b78b34","type":"java.lang.String","value":"CONTAINER_X"}},"children":[{"definitionId":"y_qualifying_products","parameters":{"products_operator":{"uuid":"082226ac-897e-410d-9572-659106195dcf","type":"Enum(de.hybris.platform.ruledefinitions.CollectionOperator)","value":"CONTAINS_ALL"},"quantity":{"uuid":"60c0d535-30d5-43ee-a3be-7a956df9e944","type":"java.lang.Integer","value":1},"operator":{"uuid":"b2445ab2-5abf-47f2-939d-6171e141b9f1","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"},"products":{"uuid":"b222f294-3489-41ef-9130-7c605fafa75d","type":"List(ItemType(Product))","value":["816261"]}},"children":[]}]},{"definitionId":"y_container","parameters":{"id":{"uuid":"6b7edc03-9a78-478a-9162-c51549b73cee","type":"java.lang.String","value":"CONTAINER_Y"}},"children":[{"definitionId":"y_qualifying_products","parameters":{"products_operator":{"uuid":"697ee4e9-4caa-443a-8a88-0a62e1e47272","type":"Enum(de.hybris.platform.ruledefinitions.CollectionOperator)","value":"CONTAINS_ALL"},"quantity":{"uuid":"5ea68a4d-838c-418f-809c-03970d1675f5","type":"java.lang.Integer","value":1},"operator":{"uuid":"0a4f3c52-f819-4a4b-9132-abc4af304ebb","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"},"products":{"uuid":"b26b99eb-1ec6-4b34-bf7e-ce35b6857bc3","type":"List(ItemType(Product))","value":["816261"]}},"children":[]}]}];[{"definitionId":"y_partner_order_entry_fixed_price","parameters":{"selection_strategy":{"uuid":"d6232294-6944-4880-9555-018b3d2ced26","type":"Enum(de.hybris.platform.ruleengineservices.enums.OrderEntrySelectionStrategy)","value":"CHEAPEST"},"qualifying_containers":{"uuid":"8867c6f7-84a3-4466-81c6-a9a3ec2a913f","type":"Map(java.lang.String,java.lang.Integer)","value":{"CONTAINER_X":2}},"target_containers":{"uuid":"f8455825-bb26-4fd3-9dc8-f993a2a82585","type":"Map(java.lang.String,java.lang.Integer)","value":{"CONTAINER_Y":1}},"value":{"uuid":"66738f14-7435-4b4c-acda-b2f25aadf5ad","type":"Map(ItemType(Currency),java.math.BigDecimal)","value":{"USD":0.00}}}}];
;FixedPriceFlashCard;FixedPriceFlashCard;700;1;true;productPromotionRuleGroup;[{"definitionId":"y_qualifying_categories","parameters":{"quantity":{"uuid":"af923bac-845b-47d2-b234-52a796a10036","type":"java.lang.Integer","value":1},"categories_operator":{"uuid":"cc276d81-a55a-4adc-b8f2-bbc46422999b","type":"Enum(de.hybris.platform.ruledefinitions.CollectionOperator)","value":"CONTAINS_ANY"},"excluded_categories":{"uuid":"28a0393b-62b4-497a-94e1-929b8ddf2932","type":"List(ItemType(Category))"},"categories":{"uuid":"eff46a0a-282b-4fb0-b853-36d53364ed93","type":"List(ItemType(Category))","value":["902"]},"excluded_products":{"uuid":"50426a50-49b3-486b-825c-6a3a95201108","type":"List(ItemType(Product))"},"operator":{"uuid":"d6da820b-31b5-4ee2-ab67-d33096453fd5","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"}},"children":[]}];[{"definitionId":"y_order_entry_fixed_price","parameters":{"value":{"uuid":"e535a930-3ae9-4089-a49f-5e9f67ad87c0","type":"Map(ItemType(Currency),java.math.BigDecimal)","value":{"USD":24.99}}}}];
;MultiBuyElectronics;MultiBuyElectronics;700;1;true;productPromotionRuleGroup;[{"definitionId":"y_container","parameters":{"id":{"uuid":"1ec1fb8e-3bc4-4701-96ca-fc7d851f68ee","type":"java.lang.String","value":"CONTAINER_X"}},"children":[{"definitionId":"y_qualifying_categories","parameters":{"quantity":{"uuid":"465d2bf2-249d-4162-91fa-8f9c1eb3c899","type":"java.lang.Integer","value":1},"categories_operator":{"uuid":"d6b64e89-3451-456f-99ac-ff056fe7929d","type":"Enum(de.hybris.platform.ruledefinitions.CollectionOperator)","value":"CONTAINS_ANY"},"excluded_categories":{"uuid":"c032ff8e-925c-4e47-8abb-aef7d61e0379","type":"List(ItemType(Category))"},"categories":{"uuid":"7b19dc4b-1fd8-4082-9b25-9b70c701c621","type":"List(ItemType(Category))","value":["597","598"]},"excluded_products":{"uuid":"3284b513-364c-4005-b3e5-4d9fb3b8f78c","type":"List(ItemType(Product))"},"operator":{"uuid":"8afc664d-82b3-4538-9919-af31b326b08a","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"}},"children":[]}]}];[{"definitionId":"y_target_bundle_price","parameters":{"selection_strategy":{"uuid":"a2bcefb6-9fd5-4254-8115-7a1c81a315f1","type":"Enum(de.hybris.platform.ruleengineservices.enums.OrderEntrySelectionStrategy)","value":"DEFAULT"},"qualifying_containers":{"uuid":"1eedafa1-1263-4535-a858-4c59f16a557d","type":"Map(java.lang.String,java.lang.Integer)","value":{"CONTAINER_X":3}},"value":{"uuid":"739b0380-09dc-42af-b499-d89d9d551a2a","type":"Map(ItemType(Currency),java.math.BigDecimal)","value":{"USD":10.00}}}}];
;OneToOnePerfectDiscount;OneToOnePerfectDiscount;1000;1;true;productPromotionRuleGroup;[{"definitionId":"y_container","parameters":{"id":{"uuid":"2e59355d-5367-43fb-8ddd-5b192ca8290e","type":"java.lang.String","value":"CONTAINER_BASE"}},"children":[{"definitionId":"y_qualifying_products","parameters":{"products_operator":{"uuid":"c242877a-50c8-4c7f-8a2d-2d51558e6061","type":"Enum(de.hybris.platform.ruledefinitions.CollectionOperator)","value":"CONTAINS_ALL"},"quantity":{"uuid":"6bc82d1f-468c-41e8-bb9f-6ee0867513f7","type":"java.lang.Integer","value":1},"operator":{"uuid":"e150a483-27c5-4dbc-a16a-2509f2d81b96","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"},"products":{"uuid":"55ce8f53-4dd0-4f8b-85ae-2f1c74b05724","type":"List(ItemType(Product))","value":["478828"]}},"children":[]}]},{"definitionId":"y_container","parameters":{"id":{"uuid":"1435909a-1b64-4204-b58c-ce31687da207","type":"java.lang.String","value":"CONTAINER_PERFECT_PARTNER"}},"children":[{"definitionId":"y_qualifying_products","parameters":{"products_operator":{"uuid":"c87f985e-a08a-4154-8802-cab0eb51596b","type":"Enum(de.hybris.platform.ruledefinitions.CollectionOperator)","value":"CONTAINS_ALL"},"quantity":{"uuid":"2497bc06-c3cd-477d-8a77-fc6e4f5fb9b3","type":"java.lang.Integer","value":1},"operator":{"uuid":"526db933-2a17-4b7e-a6b4-8e2430456365","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"},"products":{"uuid":"a70719d3-4102-4b57-9564-ce91ea8c8745","type":"List(ItemType(Product))","value":["503392"]}},"children":[]}]}];[{"definitionId":"y_target_bundle_price","parameters":{"selection_strategy":{"uuid":"59df1bb1-0326-4ade-a6fa-f23ceaa6ba0d","type":"Enum(de.hybris.platform.ruleengineservices.enums.OrderEntrySelectionStrategy)","value":"DEFAULT"},"qualifying_containers":{"uuid":"21f21049-4f3b-49ec-8fdd-2e687bb5d47b","type":"Map(java.lang.String,java.lang.Integer)","value":{"CONTAINER_BASE":1,"CONTAINER_PERFECT_PARTNER":1}},"value":{"uuid":"0e3ee0bf-c09b-4ed1-8454-919d3b675da8","type":"Map(ItemType(Currency),java.math.BigDecimal)","value":{"USD":15.00}}}}];
;OrderThreshold20Discount;OrderThreshold20Discount;500;1;true;orderPromotionRuleGroup;[{"definitionId":"y_cart_total","parameters":{"value":{"uuid":"5f0a0be8-1ebb-48ad-ba70-8786b85e2261","type":"Map(ItemType(Currency),java.math.BigDecimal)","value":{"USD":200.00}},"operator":{"uuid":"873d63c5-89e0-44a4-b3aa-2afd61d45e95","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"}},"children":[]}];[{"definitionId":"y_order_fixed_discount","parameters":{"value":{"uuid":"d2586b35-04a0-4324-9981-55ea74a0188e","type":"Map(ItemType(Currency),java.math.BigDecimal)","value":{"USD":20}}}}];
;OrderThresholdPerfectPartner;OrderThresholdPerfectPartner;500;1;true;productPromotionRuleGroup;[{"definitionId":"y_cart_total","parameters":{"value":{"uuid":"7071325c-c456-42f8-bf6b-60a140c1e3c3","type":"Map(ItemType(Currency),java.math.BigDecimal)","value":{"USD":1000}},"operator":{"uuid":"8d546d2e-65e6-4db0-bfdc-9508052a38dd","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"}},"children":[]},{"definitionId":"y_container","parameters":{"id":{"uuid":"6efb2148-b5db-48bb-94ab-bb9b65178e5a","type":"java.lang.String","value":"CONTAINER_X"}},"children":[{"definitionId":"y_qualifying_products","parameters":{"products_operator":{"uuid":"077df6ff-a03b-40fa-bcd4-1c30fe850b90","type":"Enum(de.hybris.platform.ruledefinitions.CollectionOperator)","value":"CONTAINS_ANY"},"quantity":{"uuid":"b4cb5ddd-a4d6-45a1-bc36-f68caea7c5ec","type":"java.lang.Integer","value":1},"operator":{"uuid":"63ebae80-7d44-4faa-94d9-00673c5cdac1","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"},"products":{"uuid":"3639ccee-36f9-45df-a7fd-0d2e63e0560b","type":"List(ItemType(Product))","value":["1438466"]}},"children":[]}]}];[{"definitionId":"y_partner_order_entry_fixed_price","parameters":{"selection_strategy":{"uuid":"8451e08e-3400-490c-9d14-c60c7fe62f26","type":"Enum(de.hybris.platform.ruleengineservices.enums.OrderEntrySelectionStrategy)","value":"CHEAPEST"},"qualifying_containers":{"uuid":"dfc15ac6-dd9a-47af-8645-6df3d8f07134","type":"Map(java.lang.String,java.lang.Integer)"},"target_containers":{"uuid":"aeb50155-962e-4b55-95e2-92cd7900f20a","type":"Map(java.lang.String,java.lang.Integer)","value":{"CONTAINER_X":1}},"value":{"uuid":"51abcb55-addb-4718-ace0-d672e0c8138e","type":"Map(ItemType(Currency),java.math.BigDecimal)","value":{"USD":15.99}}}}];
;PerfectPartnerBundle;PerfectPartnerBundle;1000;1;true;productPromotionRuleGroup;[{"definitionId":"y_container","parameters":{"id":{"uuid":"edc1773b-5525-42f4-af0b-d276189a29d6","type":"java.lang.String","value":"CONTAINER_X"}},"children":[{"definitionId":"y_qualifying_products","parameters":{"products_operator":{"uuid":"3d3623fc-0211-47eb-85b7-d401538b20c0","type":"Enum(de.hybris.platform.ruledefinitions.CollectionOperator)","value":"CONTAINS_ALL"},"quantity":{"uuid":"5f3ba7a5-2560-487e-9c65-6efd7ea9252b","type":"java.lang.Integer","value":1},"operator":{"uuid":"0e505148-ea23-45f7-9523-4cdadcde8668","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"},"products":{"uuid":"e2a09f6f-cc55-4bb3-b26b-84a6fc5d7542","type":"List(ItemType(Product))","value":["503392","572461","832386"]}},"children":[]}]}];[{"definitionId":"y_target_bundle_price","parameters":{"selection_strategy":{"uuid":"c8c9db52-e754-48e9-95e1-6f24df688351","type":"Enum(de.hybris.platform.ruleengineservices.enums.OrderEntrySelectionStrategy)","value":"DEFAULT"},"qualifying_containers":{"uuid":"1fdded3d-f2b7-4058-9e15-16c3b746025e","type":"Map(java.lang.String,java.lang.Integer)","value":{"CONTAINER_X":3}},"value":{"uuid":"24f639b1-c062-40e2-a44d-64a3c2c1e02b","type":"Map(ItemType(Currency),java.math.BigDecimal)","value":{"USD":299.00}}}}];
;PerfectPartnerElectronics;PerfectPartnerElectronics;800;1;true;productPromotionRuleGroup;[{"definitionId":"y_container","parameters":{"id":{"uuid":"9c58fe10-5e19-46d8-89b0-d9ce69948323","type":"java.lang.String","value":"CONTAINER_X"}},"children":[{"definitionId":"y_qualifying_products","parameters":{"products_operator":{"uuid":"dfd8d0ed-06f3-49d9-a28e-859abe8fdaf5","type":"Enum(de.hybris.platform.ruledefinitions.CollectionOperator)","value":"CONTAINS_ALL"},"quantity":{"uuid":"cb7e2206-5309-4336-b7f0-900cd27b0acd","type":"java.lang.Integer","value":1},"operator":{"uuid":"8aeaa415-04c4-48bf-b05f-b91257f0ed44","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"},"products":{"uuid":"525902a9-8b17-47eb-a8aa-1e96604bf968","type":"List(ItemType(Product))","value":["816780"]}},"children":[]}]},{"definitionId":"y_container","parameters":{"id":{"uuid":"209e7ca7-47ac-4eb4-8387-80dc2ec5fb6c","type":"java.lang.String","value":"CONTAINER_Y"}},"children":[{"definitionId":"y_qualifying_products","parameters":{"products_operator":{"uuid":"8e5690fc-9ef1-4f93-beb7-94a360928a7e","type":"Enum(de.hybris.platform.ruledefinitions.CollectionOperator)","value":"CONTAINS_ALL"},"quantity":{"uuid":"722af697-f21f-46c2-a281-ab6287706dc6","type":"java.lang.Integer","value":1},"operator":{"uuid":"d073e6c8-c49d-474a-9ede-f36be176b933","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"},"products":{"uuid":"923e2478-836f-4e57-98cd-7dd80ca1531a","type":"List(ItemType(Product))","value":["482105"]}},"children":[]}]}];[{"definitionId":"y_partner_order_entry_fixed_price","parameters":{"selection_strategy":{"uuid":"06d528bd-62b7-40dd-9acb-b9b8cd25931b","type":"Enum(de.hybris.platform.ruleengineservices.enums.OrderEntrySelectionStrategy)","value":"CHEAPEST"},"qualifying_containers":{"uuid":"1faea51d-f036-4b72-bc6a-500d865d5309","type":"Map(java.lang.String,java.lang.Integer)","value":{"CONTAINER_X":1}},"target_containers":{"uuid":"6f602198-2afe-46f8-a89f-4865946b255f","type":"Map(java.lang.String,java.lang.Integer)","value":{"CONTAINER_Y":1}},"value":{"uuid":"bb942995-8c03-491e-8bb0-296794786eed","type":"Map(ItemType(Currency),java.math.BigDecimal)","value":{"USD":75.00}}}}];
;ProductBundleElectronics;ProductBundleElectronics;700;1;true;productPromotionRuleGroup;[{"definitionId":"y_container","parameters":{"id":{"uuid":"88fec1eb-c185-4a41-803e-08a8c311fe06","type":"java.lang.String","value":"CONTAINER_X"}},"children":[{"definitionId":"y_qualifying_products","parameters":{"products_operator":{"uuid":"69ad076e-ed58-47d2-8364-f27d776cd628","type":"Enum(de.hybris.platform.ruledefinitions.CollectionOperator)","value":"CONTAINS_ALL"},"quantity":{"uuid":"f6ea48d2-e8f3-426f-b720-6cafad0c6f42","type":"java.lang.Integer","value":1},"operator":{"uuid":"e734efd8-ee25-490f-ba3a-9f198497a404","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"},"products":{"uuid":"5f79b3e6-5296-41ba-ac9c-a4ab728c1fee","type":"List(ItemType(Product))","value":["1934406","278688","1687508"]}},"children":[]}]}];[{"definitionId":"y_target_bundle_price","parameters":{"selection_strategy":{"uuid":"03c16eab-9d52-4964-85b3-ee1288621f30","type":"Enum(de.hybris.platform.ruleengineservices.enums.OrderEntrySelectionStrategy)","value":"DEFAULT"},"qualifying_containers":{"uuid":"7942fe4a-9759-40ef-abe3-82d58b9a1961","type":"Map(java.lang.String,java.lang.Integer)","value":{"CONTAINER_X":3}},"value":{"uuid":"2ab2e7d1-ce6d-414e-80ae-ba515a05bfe0","type":"Map(ItemType(Currency),java.math.BigDecimal)","value":{"USD":500.00}}}}];
;Spend300FreeGift;Spend300FreeGift;500;1;true;orderPromotionRuleGroup;[{"definitionId":"y_cart_total","parameters":{"value":{"uuid":"b876cd13-280a-46b9-83a7-67fd05820230","type":"Map(ItemType(Currency),java.math.BigDecimal)","value":{"USD":300.00}},"operator":{"uuid":"13accd17-2590-492c-a0c2-f27384fe57f9","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"}},"children":[]}];[{"definitionId":"y_free_gift","parameters":{"product":{"uuid":"a63bc46f-6382-43d0-98aa-3f14d1248e77","type":"ItemType(Product)","value":"107701"},"quantity":{"uuid":"71430d38-bfb0-47f2-a1df-bd42e2614a51","type":"java.lang.Integer","value":1}}}];
;Spend800FreeShipping;Spend800FreeShipping;500;1;true;orderPromotionRuleGroup;[{"definitionId":"y_cart_total","parameters":{"value":{"uuid":"d76b0386-c9d4-4092-af28-84a5669e2079","type":"Map(ItemType(Currency),java.math.BigDecimal)","value":{"USD":800.00}},"operator":{"uuid":"5d4f05fe-7564-4e92-9656-3360c4917725","type":"Enum(de.hybris.platform.ruledefinitions.AmountOperator)","value":"GREATER_THAN_OR_EQUAL"}},"children":[]}];[{"definitionId":"y_change_delivery_mode","parameters":{"delivery_mode":{"uuid":"2690a713-b8ff-4d7b-b071-7b86af5c0399","type":"ItemType(DeliveryMode)","value":"free-standard-shipping"}}}];

Solution

Cart Migration

Pre-Requisite

Make sure to model any legacy promotions that was active before switching to the promotion engine, using new data structure. There are a couple of options to create these promotions:

  • Data load (the promotions were created on some other system and then imported into production) through impex (see sample impex above)
  • Hand create them in thebackofficeapplication

More information about promotion engine can be found on this page of the product documentation.

There may be carts that have legacy promotions on them that need to be migrated over to the new promotion-engine (so they don't reference promotions in the legacy promotion extension). The key here is as mentioned above is that the promotions that were active before the system was switched to the new promotion engine need to be modeled in the new data model that the promotion engine uses in order for there to be a seamless transition from the view of the customer. After you migrate promotions and make your site publicly available when the customer returns to their cart there should be an automatic re-calculation fired, because their cart will be loaded from the database (no cache). Additionally during the checkout their cart will be recalculated, causing all promotions to be removed and re-evaluated. This will result in replacing the legacy promotion results with the promotion results now being created by the promotions engine.

In summary, there should be no further intervention required to migrate carts since the system will be restarted; the SAP Commerce platform should be able to handle the update to promotion engine promotions automatically.

Order Migration

Pre-Requisite

Make sure to model any legacy promotions that have been used in older orders before switching to the promotion engine using the new data structure, published and activated. There are a couple of options to create these promotions:

  • Data load (the promotions were created on some other system and then imported into production) through impex(see sample impex above)
  • Hand create them in thebackofficeapplication

More information about promotionengine can be found on this page of the product documentation.

There will be orders in the system that have legacy promotions attached to them. When migrating to the the new promotion engine you have two options:

  • Do nothing and leave those orders the same: This means the old orders with legacy promotions can not be modified anymore, and once the legacy promotions are removed they won't be able to be opened without errors. Any modification to an order with a legacy promotion will cause a recalculate, which would remove the legacy promotion and alter the price of the order. Think about archiving old orders (otherwise will always have to keep the legacy promotion extension in order to view orders in the future). This is most likely not an option for situations because because potential orders could require changes (refunds, returns, cancellations).
  • Migrate those orders to use the new promotion engine promotions: This will allow you to continue to modify orders as needed, as a recalculate would use the equivalent promotion engine promo during recalculate. With this option you will be able to remove the legacy promotions from the system. The two issues with this option. Firstly, you need to create equivalent promotion engine promotions for every legacy promotion created. Secondly, you  need to recalculate every order that could potentially be modified. During recalculation you may run into other issues. For example, if taxes change between when the order was originally created and when it is recalculated, even if the promotion engine promotion is applied correctly, the total would change due to the tax change.

Our recommendations for orders are:

  • Evaluate how many orders and legacy promotions you have and find an appropriate time in the past where an order most likely needed to be open. This will typically be 6 months to 1 year, but could be longer. The shorter the time period, the fewer promotions you'll have to recreate and the fewer orders you will need to recalculate.
  • Create a strategy for what to do if an opened order hasn't been recalculated with a promotion engine promo. This should be shared with all customer-facing employees, so they understand what to do when this happens. Unfortunately, there isn't a common strategy because every solution will be different depending on company policy.

Cronjob Process

The process outlined here involves recalculating orders with a promotion engine rule(s) applied. There is a known bug in some versions of SAP Commerce that prevents recalculation on an order/cart with the new promotions. If you wish to proceed with the steps outlined below, make sure you are running at least one of the following versions

  • 6.3.0.0+
  • 6.2.0.8+
  • 6.1.0.12+
  • 6.0.0.14

The easiest way to migrate orders is to create a CronJob that can be run once (after all of the data is set up and ready and promotion engine is enabled) that will force recalculation of the orders and allow for the equivalent promotion engine promo to be applied to each order. The cron job should log an error if the promotion migration fails an integrity check (if the order total before does not equal the order total after the calculation) – these orders would have to be looked at manually to determine the issue.

A general outline of the cron job activities are as follows:

  1. Queries for orders that have promotion results (assumption is there are no orders with new promotion engine promotions because we haven't allowed any customers to use site yet)

    "SELECT DISTINCT({" + PromotionResultModel.ORDER + "}) FROM {" + PromotionResultModel._TYPECODE + " as pr "
                    + "LEFT JOIN " + OrderModel._TYPECODE + " as o ON {o." + OrderModel.PK + "}={pr." + PromotionResultModel.ORDER + "}} "
                    + "WHERE {o." + OrderModel.PK + "} IS NOT NULL"
  2. (optional) If you're not querying all orders and you are utilizing a smaller timeline, ensure your cronjob takes a date/number of days as a parameter and utilize the parameter in the query above to reduce the number of results.
  3. (optional) Perform a sanity check that determines if all legacy promotions have equivalent promotion engine rules. If not you need to determine what to do (abort, log and continue, and so on) this can prevent an error in step #5 from occurring
  4. Disable all of the published promotion engine promotions, once orders are found 
  5. For each order found in step #1, find the equivalent promotion engine promo(s) and enable them

    for (final String droolsRuleCode : legacyPromotionCode)
    {
    	final AbstractRuleEngineRuleModel droolsRule = platformRuleEngineService.getRuleForCode(droolsRuleCode);
    	//log error if you can't find the equivalent promotion engine rule
    	//enable drools rules
    }
  6. Capture the existing order total before recalculation.

  7. Re-calculate the order, then re-apply promotions and taxes.

  8. Compare the new order total with the value in step #4. If they are not the same, log the order as an error for manual follow-up later.
  9. Disable all the promotions enabled in step #3.
  10. Continue steps 3-7 until all orders are migrated.
  11. Return the cron job SUCCESS if all orders were migrated without error, otherwise ERROR status.


In order to prevent orders from receiving promotions that weren't intended for them, we disable all active rules between each order. This means at the end of a run ALL your rules except for any from the last order processed will be disabled. Before re-enabling your site for users ensure you have published and activated all the rules that should be active for your site currently (inbackofficesee Rule Engine->Drools Rules)

Recommendations for Removal of Legacy Promotions Extension

The legacy promotion extension is still depended upon heavily by SAP Commerce code; it can be seen as dependant on the commerceservices, promotionengineservices, and promotionsbackoffice extensions (all of which are platform code). The best that you can do is remove any dependencies in your data to the types contained within the promotions extension, so when it's completely removed from the product, it makes the task easier without breaking the viewing of orders.

Currently this is not possible by the way that the code is organized in the code, but in preparation of this for the future the following is required:

  • No multi-step promotions on orders in the system (because they can't be modeled in the new promotion engine and therefore the order can't be migrated).
  • All orders with legacy promotions are migrated over to use the new promotions using the promotion engine.

Recommendations for Archiving Legacy Promotion Orders

Archiving old orders should be considered if the likelihood of opening them to view them is remote. We recommend this approach, because if you want to migrate orders with legacy promotions to use the new promotion-engine, then you would have to re-create all promotions that are present on the old orders. This is a time consuming task, as there could be thousands or millions of orders and just as much promotions. So, having to re-create promotions for each order that you might not have to open again is a waste of time. Therefore, it is more efficient to have a threshold or orders that you are trying to migrate while archiving the rest of the orders in some manner.

Archiving orders would require effort to create and customize for your needs, but with every order you archive you will have fewer orders to migrate promotions

Conclusion

You should now understand the effort to either maintain your legacy promotion module in 6.x versions of SAP Commerce Cloud or how to take the recommended steps of migrating to the promotion engine.


Overlay