Tuesday, September 8, 2020

Sitecore Experience Commerce (Generate a custom order number with policies)

Recently, I got a requirement to generate a custom order number, As the default number is a GUID. I did a similar task in Sitecore Commerce 8.2.1.  here is a link . I used a custom store procedure to generate the order number but would be very straight forward, As the requirement was to generate only random numbers for a fixed digit.

Steps to do that -

1. Create a new plugin -

2.  Give it a name let's say 

Sitecore.Plugin.CustomOrderGenerator

The plugin will look like this -  Now build the plugin


Define the policy here, I need the policy to put a Prefix and make a decision whether to generate a random number or sequential numbers



Add a reference to Sitecore.Commerce.Plugin.Catalog - Because my XC version is 9.3, I have chosen version 5.0.43

Second reference for Commerce.Plugin.Order


Replace OrderPlacedAssignConfirmationIdBlock pipeline block with your custom block



  [PipelineDisplayName("Sitecore.Commerce.Plugin.Sample.CustomOrderGeneratorBlock")]  
   public class CustomOrderGeneratorBlock : PipelineBlock<Order, Order, CommercePipelineExecutionContext>  
   {  
     private readonly FindEntitiesInListCommand _getEntitiesInListCommand;  
     public CustomOrderGeneratorBlock(FindEntitiesInListCommand findEntitiesInListCommand) : base((string)null)  
     {  
       _getEntitiesInListCommand = findEntitiesInListCommand;  
     }  
     public override Task<Order> Run(Order order, CommercePipelineExecutionContext context)  
     {  
       order.OrderConfirmationId = GenerateCustomOrderNumber(order, context, _getEntitiesInListCommand);  
       return Task.FromResult<Order>(order);  
     }  
     private string GenerateCustomOrderNumber(Order order, CommercePipelineExecutionContext context, FindEntitiesInListCommand findEntitiesInListCommand)  
     {  
       var contactComponent = order.GetComponent<ContactComponent>();  
       var orders = (IEnumerable<Order>)findEntitiesInListCommand.Process<Order>(context.CommerceContext, CommerceEntity.ListName<Order>(), 0, int.MaxValue).Result.Items;  
       var orderCount = orders.Count();  
       if (orders.Any())  
       {  
         OrderGeneratorPolicy policy = context.GetPolicy<OrderGeneratorPolicy>();  
         string nextOrderNumber;  
         if (policy.IsRandomNumber)  
         {  
           nextOrderNumber = GenerateNumber(policy.TotalDigitMin, policy.TotalDigitMax);  
         }  
         else  
         {  
           nextOrderNumber = Convert.ToString(orderCount + 1);  
         }  
         return policy.Prefix + nextOrderNumber.ToString();  
       }  
       return Guid.NewGuid().ToString("B");  
     }  
     private string GenerateNumber(int min, int max)  
     {  
       Random r = new Random();  
       int randNum = r.Next(min, max);  
       return randNum.ToString();  
     }  
   }  
When we run the order flow, We can see the result on the order confirmation page.

A few additional notes - Make sure you have registered your policies correctly.

1.  The name should be correct  Plugin.CustomOrderGenerator.PolicySet-1.0.0.json - I think the when we do the bootstrap the application Global.json file consider the ref version ( not sure) but it's better to keep the same naming convention as an example - PlugIn.Payments.Braintree.PolicySet-1.0.0.json

2. Make sure your the definition withing the file is correct and using the correct namespace, As an example below

 {  
  "$type": "Sitecore.Commerce.Core.PolicySet, Sitecore.Commerce.Core",  
  "Id": "Entity-PolicySet-CustomOrderGenerator",  
  "Version": 1,  
  "IsPersisted": false,  
  "Name": "CustomOrderGenerator",  
  "Policies": {  
   "$type": "System.Collections.Generic.List`1[[Sitecore.Commerce.Core.Policy, Sitecore.Commerce.Core]], mscorlib",  
   "$values": [  
    {  
     "$type": "Plugin.CustomOrderGenerator.OrderGeneratorPolicy,Plugin.CustomOrderGenerator",  
     "Environment": "sandbox",  
     "Prefix": "XX",  
     "IsRandomNumber": true,  
     "TotalDigitMin": 9999999,  
     "TotalDigitMax": 1000000  
    }  
   ]  
  }  
 }  


3. Add entity entry in all roles

{ "$type": "Sitecore.Commerce.Core.PolicySetPolicy, Sitecore.Commerce.Core", "PolicySetId": "Entity-PolicySet-BraintreePolicySet" },


That's so much easy, Let me know if have any questions ;) 

No comments:

Post a Comment