Creating a Custom Order Number Plugin - Sitecore Commerce Engine
Sitecore Commerce Engine out of the box uses guid to represent order numbers.
You may have a client who is migrating to Sitecore Commerce and want to preserve the way their order number is formatted from their legacy system or base on the way they conduct their business.
Step 1
Under the Commerce Engine Solution for your site, create a new .NET Core project and name it as you wish. I named mine Sitecore.Plugin.CustomOrderNumber .
I am using Visual Studio 2017 and my .Net framework is 4.6.2
Step 2
Add Sitecore Nugget
Sitecore.Commerce.Core 2.2.29
Sitecore.Commerce.Plugin.Catalog 2.2.46
Sitecore.Commerce.Plugin.Orders 2.2.22
Step 3
Add a folder name Pipelines and under that folder, add a Blocks folder
Under the blocks folder, add a public class for customizing order number and name it as you wish. I named mine CustomOrderNumberBlock I also followed the naming convention and ended the name with Block.
Inherit from PipelineBlock
Implement the required Run method with its parameters.
In the method, you need to replace the OrderConfirmationId property of the passed order parameter with the desired custom value.
This can be done either by calling and external system of referring to a config. In my case, I have opted for sequential order numbers so, I simply increment a new order numbers count by one for a newly placed order.
public class CustomOrderNumberBlock : PipelineBlock
{
///
///
///
private readonly FindEntitiesInListCommand _findEntitiesInListCommand;
///
///
///
///
public CustomOrderNumberBlock(FindEntitiesInListCommand findEntitiesInListCommand) : base((string)null)
{
// We need to use this to get all existing orders placed before the new order
_findEntitiesInListCommand = findEntitiesInListCommand;
}
///
///
///
///
///
///
public override Task Run(Order order, CommercePipelineExecutionContext context)
{
// We need to ensure the order object is not null.
Condition.Requires(order).IsNotNull("The order can not be null");
// We call a methos that will generate our new order number. We pass parameters that may help in formulating the order number.
order.OrderConfirmationId = GetCustomOrderNumber(order, context, _findEntitiesInListCommand);
// return the new order so that it can be sent to the entities databse
return Task.FromResult(order);
}
///
/// You may customized what is returned here based on number od existing orders or date or get number from external system
///
///
///
///
///
private string GetCustomOrderNumber(Order order, CommercePipelineExecutionContext context, FindEntitiesInListCommand findEntitiesInListCommand)
{
//Get Contact Component which contains customer information
var contactComponent = order.GetComponent();
// get all existing orders.
var orders = (IEnumerable)findEntitiesInListCommand.Process(context.CommerceContext, CommerceEntity.ListName(), 0, int.MaxValue).Result.Items;
// Total orders
var orderCount = orders.Count();
// use the info you have to generate an appropriate order number. You may also use the data you have to call an external system.
// in this instance we will just return the number of existing orders incremented by 1
// Return order count and increment by 1 as the new order number.
if (orders.Any())
{
var nextOrderNumber = orderCount + 1;
return nextOrderNumber.ToString();
}
// return a random guid if ther was an isssue retriving existing orders or all else failed.
return Guid.NewGuid().ToString("B");
}
}
Step 4
Create a configuration file at the root of your project and name it ConfigureSitecore inherit from IConfigureSitecore and implement the interface.
In the implemented method, add the line below into the method so that the CustomOrderNumberBlock code block is used to replace default OrderPlacedAssignConfirmationIdBlock
.ConfigurePipeline
public class ConfigureSitecore : IConfigureSitecore
{
public void ConfigureServices(IServiceCollection services)
{
var assembly = Assembly.GetExecutingAssembly();
services.RegisterAllPipelineBlocks(assembly);
services.Sitecore().Pipelines(config => config
.ConfigurePipeline(builder => builder.Replace())
);
services.RegisterAllCommands(assembly);
}
}
The plugin is now ready to put to a test.
Add it to your solution and try it out.
You may down load the sample plugin from Github here: Github Link