5

When I originally installed Commerce 9 via SIF, everything worked fine. But since building/deploying the Sitecore.Commerce.Engine project (sans all sample plugins), adding an item to the cart results in the following error being displayed:

GetCurrentCart: Value cannot be null

Here's there research I've done so far:

The error is being thrown by Sitecore.Commerce.XA.Feature.Cart.Models.JsonResults.CartLineJsonResult.SetLink() because it fails to lookup the product by the id that's being mapped from the Id property of the CartProductComponent that's attached to the CartLineComponent.

Looking at the raw entity data and the id attribute is a GUID, but SXA clearly expects it to be a the product id so it makes sense that the index query turns up nothing.

Looking into the blocks in Plugin.Cart, and AddCartLineBlock does indeed generate a new guid in scenarios where it's not being merged into an existing cart line.

I can see that PopulateLineItemProductBlock does exactly what I expect to happen: load the sellable item and populate the CartProductComponent. However, it's not added to any pipeline's in the Cart (or any other) plugin's ConfigureSitecore class.

I've run into missing plugin issues related to building the Engine project exclusively, so I'm not ruling that out but I can't see the missing piece.

1 Answer 1

7

Edit: Updated code to work around another issue

I started investigating the avenue of missing plugins since that caused the previous issues I had, but the issue ended up being much simpler: the Plugin.Sample.AdventureWorks project registers critical pipeline blocks that were originally included in the Engine project in previous versions of Commerce.

This actually took quite a while to find, since on the surface the AdventureWorks plugin only appears to exist to hook into IInitializeEnvironmentPipeline to import it's sample data. It's made even less obvious by the fact that the SIF installation focuses on Habitat content, not Adventure Works.

The missing blocks actually go beyond this exact problem, and I have no idea why these pipeline blocks aren't registered in their respective plugins (Plugin.Cart, for example, defines both the pipeline and block).

Regardless, the workaround is to include the following in your Commerce.Engine project:

using Microsoft.Extensions.DependencyInjection;
using Sitecore.Framework.Pipelines.Definitions.Extensions;

// You may need to add references to these plugins
using Sitecore.Commerce.Plugin.Carts;
using Sitecore.Commerce.Plugin.Catalog;
using Sitecore.Commerce.Plugin.Coupons;
using Sitecore.Commerce.Plugin.Fulfillment;
using Sitecore.Commerce.Plugin.Payments;
using Sitecore.Commerce.Plugin.Promotions;
using Sitecore.Commerce.Plugin.Tax;

namespace Sitecore.Commerce.Engine
{
    public static class ServiceCollectionExtensions
    {
        public static IServiceCollection ConfigureCartPipelines(
            this IServiceCollection services)
        {
            services.Sitecore().Pipelines(config => config
                .ConfigurePipeline<ICalculateCartLinesPipeline>(builder => builder
                    .Add<PopulateCartLineItemsBlock>()
                    .Add<CalculateCartLinesPriceBlock>()
                    .Add<ValidateCartLinesPriceBlock>()
                    .Add<CalculateCartLinesSubTotalsBlock>()
                    .Add<CalculateCartLinesFulfillmentBlock>()
                    .Add<ValidateCartCouponsBlock>()
                    .Add<CalculateCartLinesPromotionsBlock>()
                    .Add<CalculateCartLinesTaxBlock>()
                    .Add<CalculateCartLinesTotalsBlock>(),
                    order: 1001
                )

                .ConfigurePipeline<ICalculateCartPipeline>(builder => builder
                    .Add<CalculateCartSubTotalsBlock>()
                    .Add<CalculateCartFulfillmentBlock>()
                    .Add<CalculateCartPromotionsBlock>()
                    .Add<CalculateCartTaxBlock>()
                    .Add<CalculateCartTotalsBlock>()
                    .Add<CalculateCartPaymentsBlock>()
                )

                .ConfigurePipeline<IAddPaymentsPipeline>(builder => builder
                    .Add<ValidateCartHasFulfillmentBlock>()
                        .After<ValidateCartAndPaymentsBlock>()
                )
            );

            return services;
        }
    }
}

Which you can then call in your ConfigureServices class:

services.ConfigureCartPipelines();
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.