Show / Hide Table of Contents

    Developer guide for product bundles

    The Mercury Product Bundle feature provides all functionality needed to incorporate product bundles in your e-commerce site. Product bundles can contain any number of products, and by default, Mercury provides the necessary functionality. However, if you need to implement your own solution for getting product bundle data, Mercury provides extension points, see the Extension points section.

    Design

    Model

    A bundle has a reference id, title, description, and a (discount) price. Products in a bundle are described by bundle items. A bundle item has a title, quantity, price, and an (optional) image. One of the bundle items is marked as "main" item. This information is used for presentation, the main item is shown differently than the others.

    A bundle reference id is used to uniquely identify a bundle. In the current implementation the reference id is the product id, variant id plus a suffix for the bundle: {productid}_{bundleid} or in case of a variant: {productid}_{variantid}_{bundleid}. For example: dr001_101_1, where dr001 is the product id, 101 is the variant id and 1 is the bundle id. The bundle id only needs to be unique within the product or variant. If the default reference separator: _ conflicts with your product ids or variant ids, its possible to change the separator value with the following Sitecore configuration setting: Mercury.ProductBundles.ReferenceSeparator.

    Title and description are useful fields for marketeers to specify custom names for bundles and its items. Prices are calculated, based on a absolute or relative discount amount, from the original price.

    A bundle may have a directly related product. If so, this relation identifies the product in the catalog that is composed of all bundle items (i.e. a SKU). Note that in this case, bundle items may still be useful as they indicate the products the SKU is composed of.

    The complete UML class diagram for Product Bundles is shown below.

    Product bundles model

    Note that in code, a second, next to above model, exists that is optimized for persistent storage.

    To summarize, there are two ways of storing a product bundle:

    • without direct product relation: bundle does not relate to a product, but contains a collection of items that relate to a product or a variant
    • with direct product relation: bundle relates to a product (i.e. a SKU) and contains items that relate to a product

    Defining a product bundle

    Bundle data is stored as JSON in the custom property "Bundles" for a Commerce product or in a "Variant_Bundles" property for a Commerce product variant. These properties need to be added to the commerce schema of the catalog. The JSON schema is based on the Bundle persistence model. An example of a product bundle in JSON:

    [
        {
            "referenceId": "DR-012_1",
            "title": "Cola and Juice bundle",
            "description": "Cola and Juice product bundle",
            "priceInformation": {
                "type": "fixedprice",
                "value": 2.50,
                "description": "Bundle price: 2.50"
            },
            "bundleItems": [
                {
                    "isMain": true,
                    "productID": "DR-012"
                },
                {
                    "title": "Lemon Juice",
                    "isMain": false,
                    "productID": "DR-016",
                    "variantID": "DR-016-02"
                }
            ]
        }
    ]
    

    An example of a product with a related product in the catalog, i.e. a SKU, is:

    {
            "referenceId": "DR-012_3",
            "title": "Celery, Cucumber and Carrot combi",
            "productID": "VEBU-001",
            "bundleItems": [
                {
                    "title": "Celery 3x",
                    "isMain": true,
                    "productID": "VE-010",
                    "quantity": 3
                },
                {
                    "title": "Cucumber 3x",
                    "isMain": false,
                    "productID": "VE-013",
                    "quantity": 3
                },
                {
                    "title": "Carrot 3x",
                    "isMain": false,
                    "productID": "VE-008",
                    "quantity": 3
                }
            ]
        }
    

    The productID in above example indicates the product in the catalog that represents the SKU.

    As seen in above examples, for storage a slighty modified persistence model, which e.g. doesn't contain the full product data, is used. One should use the mercury.translate.bundleToViewModel pipeline to convert the persistence model to a full model.

    In a production setup the bundle data should be imported from e.g. a back-office system that contains product bundle definitions. Mercury does currently not provide bundle data import functionality.

    Functionality

    Add product bundle to cart

    A product bundle is added to the cart by using Mercury Checkout. The mercury.addBundleToCart pipeline connects to the Mercury Checkout service and this pipeline can be used to customize this functionality. The pipeline is exposed to the React UI via the REST API that calls the Mercury.Foundation.ProductBundles service.

    Display product bundles in cart

    The Product Bundle Javascript bundle registers itself to Mercury Checkout for displaying product bundles line items. In this way the cart will use the registered cart React components for rendering product bundle line items.

    Remove the bundle from the cart

    This works out-of-the-box with the existing Mercury Checkout functionality.

    Buy a bundle

    Creating an order from a cart is standard Mercury Checkout functionality; this works out-of-the-box.

    See bundle in an order

    For displaying product bundle order line items the same mechanism as for cart line items is used: the Javascript bundle registers itself to the Mercury Checkout bundle.

    React components

    A product bundles view is generated using the React components located in UI/components. The components are structured as follows:

    • productbundles.jsx
    • bundles
      • bundle.jsx
      • bundleitems.jsx
      • ...
      • item
        • bundleitem.jsx
        • ...
    • cart
      • maincartlineitem.jsx
      • orderlineitem.jsx

    At the top level productbundles.jsx can be used to display a collection of product bundles. Each bundle is displayed by bundle/bundle.jsx, and each item in a bundle is displayed by bundle/item/bundleitem.jsx. This structure closely follows the model and adheres to the atomic design principle that components should consist of (replaceable) building blocks.

    Extension points

    Provided pipelines

    The Product Bundles feature provides the following pipelines as extension points for customization:

    • mercury.getProductBundles
    • mercury.getVisibleProductBundles
    • mercury.getProductBundlesByReference
    • mercury.addBundleToCart
    • mercury.translate.bundleToViewModel

    mercury.getProductBundles

    This pipeline retrieves the product bundles of a specific product. Mercury provides a default implementation for the processors. These processors can be replaced with a custom implementation.

    The following processors are available:

    • GetProductBundlesFromProductField: Get product bundles from the field Bundles of a product.
    • ExcludeOutOfStockBundles: Excludes out of stock product bundles from the result.
    • CalculateBundlePrices: Calculate and set the prices of the products bundles.

    mercury.getVisibleProductBundles

    This pipeline retrieves the product bundles of a specific product that should be displayed. This pipeline is similar to mercury.getProductBundles but it can be used to filter out bundles that should not be shown on product pages, e.g. to exclude bundles without stock. Mercury provides a default implementation for the processors. These processors can be replaced with a custom implementation.

    The following processors are available:

    • GetProductBundlesFromProductField: Get product bundles from the field Bundles of a product.
    • ExcludeOutOfStockBundles: Excludes out of stock product bundles from the result.
    • CalculateBundlePrices: Calculate and set the prices of the products bundles.

    mercury.getProductBundlesByReference

    Loads a product bundle by the given reference id, e.g. the reference id set in the ReferenceID field on the Bundle class.

    mercury.addBundleToCart

    Adds a product bundle to the cart using the Mercury Checkout Foundation.

    mercury.translate.bundleToViewModel

    Loads the complete product bundle model from the given persistence storage model.

    Used pipelines

    Product Bundles uses several pipelines from which the following are worth noting:

    • mercury.catalog.getDeliveryDetails
    • Commerce Server Basket

    mercury.catalog.getDeliveryDetails

    To calculate the delivery details for a product bundle the GetDeliveryDetails processor is added to the pipeline. This processor provides a simple default implementation to calculate the delivery details (e.g. size, weight) for a bundle.

    Commerce Server Basket

    To keep the Commerce basket up-to-date, e.g. when a bundle no longer exists, the QueryProductBundleInfo component is inserted in the Commerce pipeline. Make sure that the product bundle commerce pipeline components are registered, by running the Deploy.ps1 that comes with Mercury. The component should be inserted in the basket pipeline at the following location:

    Pipeline component

    Installation

    Add the NuGet package Mercury.Feature.ProductBundles as dependency to your project. This will automatically add the package Mercury.Foundation.ProductBundles as dependency.

    The following files are included in the packages:

    • Configuration files
      • Feature\Mercury.Feature.ProductBundles.config
      • Feature\Mercury.Feature.ProductBundles.Serialization.config
      • Foundation\Mercury.Foundation.ProductBundles.config
    • Assets (script) files
      • assets\js\MercuryProductBundles.js
      • assets\js\MercuryProductBundles.js.map
    • Serialization items

    You need to copy;

    • configuration files to the App_config\Include\Mercury
    • script files to the Scripts
    • serialization items to the Serialization folders of your website.

    Configure or patch the Sitecore variable MercurySerializationData in the Sitecore configuration to the location of your serialization folder. This will ensure the serialization items can be synced using Unicorn. For example:

    <sitecore>
    ...
      <sc.variable name="MercurySerializationData" value="$(dataFolder)\unicorn\mercury\" />
    ...
    </sitecore>
    

    Register QueryProductBundleInfo the processor to the Commerce Server Basket pipeline:

    Windows Registry Editor Version 5.00
    
    ; Query Product Bundle Info
    [HKEY_CLASSES_ROOT\CLSID\{5CD9F8FE-DDCF-45D6-8D4E-E856E105FD7F}\Implemented Categories]
    [HKEY_CLASSES_ROOT\CLSID\{5CD9F8FE-DDCF-45D6-8D4E-E856E105FD7F}\Implemented Categories\{CF7536D0-43C5-11D0-B85D-00C04FD7A0FA}]
    [HKEY_CLASSES_ROOT\CLSID\{5CD9F8FE-DDCF-45D6-8D4E-E856E105FD7F}\Implemented Categories\{D82C3499-43C5-11D0-B85D-00C04FD7A0FA}]
    
    Advanced
    • Improve this Doc
    Back to top Copyright © 2015-2018 Aviva Solutions
    Generated by DocFX