Extending a cart line

Sitecore XC supports easily extending the existing solution using compositional extensibility patterns. Compositional extensibility allows you to extend the solution in a way that does not prevent upgrades and that enables a separation of concerns between multiple plugins that seek to extend the same Commerce entity.

Scenario: Add loyalty points earned to the cart line so it can be carried into the order.

The simplest way to make an item part of the order is to copy the component from the SellableItem into the cart line during the AddCartLine pipeline.

To extend a cart line:

  1. Open the same NodeConfiguration file that you referenced previously, and find the AddCartLine pipeline:

    -----------------------------------------------------------------
    Sitecore.Commerce.Plugin.Carts
    IAddCartLinePipeline (Sitecore.Commerce.Plugin.Carts.CartLineArgument => Sitecore.Commerce.Plugin.Carts.Cart)
    ------------------------------------------------------------
    Plugin.Catalog.ValidateSellableItemBlock (Sitecore.Commerce.Plugin.Carts.CartLineArgument => Sitecore.Commerce.Plugin.Carts.CartLineArgument)
    ------------------------------------------------------------
    Plugin.Carts.AddCartLineBlock (Sitecore.Commerce.Plugin.Carts.CartLineArgument => Sitecore.Commerce.Plugin.Carts.Cart)
    ------------------------------------------------------------
    Plugin.Carts.ICalculateCartLinesPipeline (Sitecore.Commerce.Plugin.Carts.Cart => Sitecore.Commerce.Plugin.Carts.Cart)
    ------------------------------------------------------------
    Plugin.Carts.ICalculateCartPipeline (Sitecore.Commerce.Plugin.Carts.Cart => Sitecore.Commerce.Plugin.Carts.Cart)
    ------------------------------------------------------------
    Plugin.GiftCards.AddCartLineGiftCardBlock (Sitecore.Commerce.Plugin.Carts.Cart => Sitecore.Commerce.Plugin.Carts.Cart)
    ------------------------------------------------------------
    Plugin.Carts.PersistCartBlock (Sitecore.Commerce.Plugin.Carts.Cart => Sitecore.Commerce.Plugin.Carts.Cart)
    ------------------------------------------------------------
    Plugin.Carts.WriteCartTotalsToContextBlock (Sitecore.Commerce.Plugin.Carts.Cart => Sitecore.Commerce.Plugin.Carts.Cart)
    -----------------------------------------------------------------
  2. Create another component that takes a Cart as a parameter and returns a Cart, and runs after the AddCartLineBlock.

  3. To access an Entity from the Carts plugin, add a reference to it. For example:

    /// <summary>
            /// The execute.
            /// </summary>
            /// <param name="arg">
            /// The SampleArgument argument.
            /// </param>
            /// <param name="context">
            /// The context.
            /// </param>
            /// <returns>
            /// The <see cref="SampleEntity"/>.
            /// </returns>
            public override Task<Cart> Run(Cart cart, CommercePipelineExecutionContext context)
            {
                Condition.Requires(cart).IsNotNull("The argument can not be null");
                //var result = this._pipeline.Run(arg, context).Result;
                return Task.FromResult(cart);
            }
  4. Add the following configuration:

    .ConfigurePipeline<IAddCartLinePipeline>(
                        configure =>
                        {
                            configure.Add<AddCartLineLoyaltyBlock>().After<AddCartLineBlock>();
                        })
  5. As in the previous scenario, you must run the block with no logic, adding a break point so you can check if the objects that you need are in the objects collection. To test this piece, add a SellableItem to the cart. In Postman, go to CartsAPISamples/Add Cart Line Without Variant and run it. This adds an item to the cart.

  6. When you look at the objects collection, you can see the SellableItem, and can get to the line that was added by retrieving the CartLineArgument and using the Line property. Copy the component from the SellableItem to the Cart Line. For example:

    public override Task<Cart> Run(Cart cart, CommercePipelineExecutionContext context)
            {
                Condition.Requires(cart).IsNotNull("The argument can not be null");
                var sellableItem = context.CommerceContext.GetObjects<SellableItem>().First();
                var arg = context.CommerceContext.GetObjects<CartLineArgument>().First();
                var cartLine = arg.Line;
                cartLine.SetComponent(sellableItem.GetComponent<LoyaltyComponent>());
                return Task.FromResult(cart);

    Going forward, each time an item is added to the cart, the loyalty points for the item are added to the cart. This can be mapped and displayed on the storefront by using the Commerce Connect component.

    You can run the solution and add the item to the cart to verify using Postman. Because the item is now a component in a cart line, it is automatically copied over, along with all other components in the cart line, to the order line when an order is placed.

  7. For this example, finish the order in Postman.

  8. Add a physical fulfillment option, a federated payment option, and complete the order, and then copy the OrderID from the completed order results.

  9. In Postman, go to GetOrder, paste the OrderID, and retrieve the order. You can see the LoyaltyComponent in the completed order.