Friday, March 9, 2018

Sitecore Experience Commerce - Plugin to extend a price card

As part of a Sitecore Experience Commerce implementation, I had requirements that involved putting some additional data (text) on price cards. The code for this plugin involves some minor changes to the SellableItem plugin example provided by Sitecore.

The full plugin code to extend a PriceCard in Experience Commerce is available on GitHub. The key file differecnes to target PriceCard instead of SellableItem are as follows:

Configure Sitecore
public void ConfigureServices(IServiceCollection services)
{
    var assembly = Assembly.GetExecutingAssembly();
    services.RegisterAllPipelineBlocks(assembly);

    services.Sitecore().Pipelines(config =>
        config
            .ConfigurePipeline<IGetEntityViewPipeline>(c =>
            {
                c.Add<GetPriceDetailViewBlock>().After<GetPriceCardDetailsViewBlock>();
            })
            .ConfigurePipeline<IPopulateEntityViewActionsPipeline>(c =>
            {
                c.Add<PopulatePriceDetailActionsBlock>().After<InitializeEntityViewActionsBlock>();
            })
            .ConfigurePipeline<IDoActionPipeline>(c =>
            {
                c.Add<DoActionEditPriceDetail>().After<ValidateEntityVersionBlock>();
            })
    );
}
The view block is added after GetPriceCardDetailsViewBlock in this case instead of GetSellableItemDetailsViewBlock with a SellableItem.

Get View Block
[PipelineDisplayName(Constants.Pipelines.Blocks.GetPriceDetailViewBlock)]
public class GetPriceDetailViewBlock : PipelineBlock<EntityView, EntityView, CommercePipelineExecutionContext>
{
private readonly ViewCommander _viewCommander;

public GetPriceDetailViewBlock(ViewCommander viewCommander)
{
    this._viewCommander = viewCommander;
}

public override Task<EntityView> Run(EntityView arg, CommercePipelineExecutionContext context)
{
    Condition.Requires(arg).IsNotNull($"{Name}: The argument cannot be null.");

    var request = this._viewCommander.CurrentEntityViewArgument(context.CommerceContext);

    var pricingViewsPolicy = context.GetPolicy<KnownPricingViewsPolicy>();

    var viewsPolicy = context.GetPolicy<KnownPriceDetailViewsPolicy>();
    var actionsPolicy = context.GetPolicy<KnownPriceDetailActionsPolicy>();

    // Make sure that we target the correct views
    if (string.IsNullOrEmpty(request.ViewName) ||
        !request.ViewName.Equals(pricingViewsPolicy.Master, StringComparison.OrdinalIgnoreCase) &&
        !request.ViewName.Equals(pricingViewsPolicy.Details, StringComparison.OrdinalIgnoreCase) &&
        !request.ViewName.Equals(viewsPolicy.PriceDetail, StringComparison.OrdinalIgnoreCase))
    {
        return Task.FromResult(arg);
    }

    // Only proceed if the current entity is a price card
    if (!(request.Entity is Sitecore.Commerce.Plugin.Pricing.PriceCard))
    {
        return Task.FromResult(arg);
    }

    var priceCard = (Sitecore.Commerce.Plugin.Pricing.PriceCard) request.Entity;

    var targetView = arg;

    // Check if the edit action was requested
    var isEditView = !string.IsNullOrEmpty(arg.Action) && arg.Action.Equals(actionsPolicy.EditPriceDetail, StringComparison.OrdinalIgnoreCase);
    if (!isEditView)
    {
        // Create a new view and add it to the current entity view.
        var view = new EntityView
        {
            Name = context.GetPolicy<KnownPriceDetailViewsPolicy>().PriceDetail,
            DisplayName = "Pricing Details",
            EntityId = arg.EntityId
        };

        arg.ChildViews.Add(view);

        targetView = view;
    }

    if (priceCard != null && (priceCard.HasComponent<PriceDetailComponent>() || isEditView))
    {
        var component = priceCard.GetComponent<PriceDetailComponent>();
        AddPropertiesToView(targetView, component, !isEditView);
    }

    return Task.FromResult(arg);
}
In this case the views policy changes from KnownCatalogViewsPolicy to KnownPricingViewsPolicy and of course we target the PriceCard entity instead of SellableItem.

It's not a lot to change when trying to extend various entities in Experience Commerce 9. It's worth noting that the types of which we do extend all appear to be of type CommerceEntity in the Sitecore DLLs.

No comments:

Post a Comment