Creating a Custom Sitecore Commerce Engine Shipping Plugin
Under your Commerce Engine Solution, create a new .Net Core project and name it as you wish. I will name the one in this blog Custom.Plugin.Shipping.
I am using Visual Studio 2015 and my .Net framework is 4.6.1
Open the project.json file under the new project and update the following
version : 1.0.1
Framework
"frameworks": {
"net461": {
}
}
Dependencies update with the a[ppropriate version of the following:
"dependencies": {
"Sitecore.Commerce.Core": "1.2.*",
"Sitecore.Commerce.Plugin.CsAgent": "1.2.159",
"Sitecore.Commerce.Plugin.Fulfillment": "1.2.159",
"Sitecore.Commerce.Plugin.Management": "1.2.159",
"Sitecore.Commerce.Plugin.Catalog": "1.2.159",
"Sitecore.Commerce.Plugin.Catalog.Cs": "1.2.159"
},
Create a folder named Pipelines
Inside Pipelines, create a subfolder named Blocks
Inside blocks folder, create two classes for updating cart shipping and cartline shipping
I will be naming them "TestCartShipping" and "TestCartLineShipping" respectively
Set the each of classes to inherit from : PipelineBlock
Make the run method async
Switch to your TestCartShipping.cs class and add the code below to override the default shipping. It also shows the point where you can call other APIs for shipping price:
///
///
///
public class TestCartShipping : PipelineBlock
{
///
///
///
///
///
///
public override async Task Run(Cart arg, CommercePipelineExecutionContext context)
{
// Get all the adjustments that may have been applied.
var adjustments = arg.Adjustments;
// If no adjustments return cart
if (adjustments == null || adjustments.Count <= 0)
{
return await Task.FromResult(arg);
}
// Check if an adjustment has been applied by the default fulfilment plugin that is what we need to overide.
var fulfillment = adjustments.FirstOrDefault(x => x.Name.ToLower().Contains("fulfillmentfee"));
if (fulfillment == null)
{
return await Task.FromResult(arg);
}
// If you are at this point, the default fulfillment plugin has applied an adjustment. and we can now replace it with our own custom.
// Go get you shipping from Fedex or USPS or UPS web service or from Sitecore
var customShipping = 6.95M; // This can come from calculating shipping from external source based on items in the cart above or address of the buyer
// If already set, or same as the amount set return cart
if (customShipping == fulfillment.Adjustment.Amount)
{
return await Task.FromResult(arg);
}
// Prepare to overide the shipping value
var awardedAdjustment = new CartLevelAwardedAdjustment
{
Name = fulfillment.Name,
DisplayName = fulfillment.DisplayName
};
// convert the new shipping price from decimal to money
var money = new Money(context.CommerceContext.CurrentCurrency(), customShipping);
// set the money as the new adjustment
awardedAdjustment.Adjustment = money;
awardedAdjustment.AdjustmentType = context.GetPolicy().Fulfillment;
// populate other values with that of the default plugin value or change them to suit you.
awardedAdjustment.IsTaxable = fulfillment.IsTaxable;
// Set the name of the awarding block to that of the current code block
awardedAdjustment.AwardingBlock = Name;
// Remove the default shipping price
adjustments.Remove(fulfillment);
// Add the new shipping price
adjustments.Add(awardedAdjustment);
// Return cart
return await Task.FromResult(arg);
}
}
Switch to your TestCartLineShipping.cs class and add the code below to override the default shipping. It also shows the point where you can call other APIs for shipping price:
///
///
///
public class TestCartLineShipping : PipelineBlock
{
///
///
///
///
///
///
public override async Task Run(Cart arg, CommercePipelineExecutionContext context)
{
// If the cart is not null and has product lines
if (arg != null && arg.Lines.Any())
{
// lop through to reset Shipping for all line that already has fulfilment set.
foreach (var cartLineComponent in arg.Lines)
{
// Get all adjustment applied to the cartline
var adjustments = cartLineComponent.Adjustments;
// It there are adjustments
if (adjustments != null && adjustments.Count > 0)
{
// Check if shipping adjustment has been applied by the default fulfillment plugin.
var fulfillment = adjustments.FirstOrDefault(x => x.Name.ToLower().Contains("fulfillmentfee"));
// If it has been applied, then we can simply replace it with our desired value based on our external APIs or internal apps.
if (fulfillment != null)
{
// Go get you shipping from Fedex or USPS or UPS web service or from Sitecore
// This can come from calculating shipping from external source based on items in the cart above or address of the buyer
var customShipping = 0.99M;
// If already set, or same as the amount set return cart
if (customShipping == fulfillment.Adjustment.Amount)
{
continue;
}
// Prepare to overide the shipping value
var awardedAdjustment = new CartLineLevelAwardedAdjustment
{
Name = fulfillment.Name,
DisplayName = fulfillment.DisplayName
};
// convert the new shipping price from decimal to money
var money = new Money(context.CommerceContext.CurrentCurrency(), customShipping);
// set the money as the new adjustment
awardedAdjustment.Adjustment = money;
awardedAdjustment.AdjustmentType =
context.GetPolicy().Fulfillment;
// populate other values with that of the default plugin value or change them to suit you.
awardedAdjustment.IsTaxable = fulfillment.IsTaxable;
// Set the name of the awarding block to that of the current code block
awardedAdjustment.AwardingBlock = Name;
// Remove the default shipping price
adjustments.Remove(fulfillment);
// Add the new shipping price
adjustments.Add(awardedAdjustment);
}
}
}
}
// Return cart
return await Task.FromResult(arg);
}
}
To add the reference of the new plugin to your Commerce Engine solution,
Goto your base Solution plugin such as Sitecore.Commerce.Plugin.AdventureWorks, open its project.json file and add reference to the new plugin as shown below.
Also open the class ServiceCollectionExtensions.cs and replace the pipeline calls as shown below:
.Add
with
.Add
.Add
with
.Add
You may down load the sample plugin from Github here: