Remove the [ServiceConfiguration] attribute from the OrderNumberGeneratorDecorator class. You don't need to register it twice.
In the Initialisation module, try intercepting it so DI loads your instance instead of episerver's out of the box one. Something like:
context.Services.Intercept<IOrderNumberGenerator>((locator, orderNumberGenerator) => new OrderNumberGeneratorDecorator(orderNumberGenerator));
If your Commerce 12 or below, you might want to do the same in the Commerce project too.
The execution doesn't reach the GenerateOrderNumber method, Commerce version is 13
[InitializableModule]
[ModuleDependency(typeof(CommerceInitialization))]
public class InitializationModule1 : IConfigurableModule
{
public void ConfigureContainer(ServiceConfigurationContext context)
{
context.Services.Intercept<IOrderNumberGenerator>((locator, defaultService) =>
{
return new OrderNumberGeneratorDecorator(defaultService);
});
}
public void Initialize(InitializationEngine context)
{
//Add initialization logic, this method is called once after CMS has been initialized
}
public void Uninitialize(InitializationEngine context)
{
//Add uninitialization logic
}
}
public class OrderNumberGeneratorDecorator : IOrderNumberGenerator
{
private readonly IOrderNumberGenerator _inner;
public OrderNumberGeneratorDecorator(IOrderNumberGenerator inner)
{
_inner = inner;
}
public string GenerateOrderNumber(IOrderGroup orderGroup)
{
var orderNumberField = orderGroup.Properties["PO"];
if (string.IsNullOrEmpty(orderNumberField?.ToString()))
{
var orderNumber = _inner.GenerateOrderNumber(orderGroup);
orderGroup.Properties["PO"] = orderNumber;
return orderNumber;
}
return orderNumberField.ToString();
}
}
Hi Amol,
I've tested this and it does work. The only question mark I can see is if your registration is being overwritten by the OOB one. Can you change [ModuleDependency(typeof(CommerceInitialization))] to [ModuleDependency(typeof(InitializationModule))] instead.
IOrderNumberGenerator is only used when you save a serializable cart as an order, not when you updating one, or saving a payment plan as an order, so that's why your custom code is not called. I don't know why. but you can use Order.OrderNumber to assign the order number as you like
Thanks Quan, It worked in this case.
Just a curiosity Does PurchaseOrder.TrackingNumber and IPurchaseOrder.OrderNumber affect the same field in the backend?
Thanks Quan, It worked in this case.
Just a curiosity Does PurchaseOrder.TrackingNumber and IPurchaseOrder.OrderNumber affect the same field in the backend?
they arre the same IIRC, TrackingNumber is the implementation of OrderNumber for PurchaseOrder
Now I think about it, I think it makes sense to not change the ordernumber everytime. if it is already there, it should be there and not regenerated. that might be the reason we decided to only call it during saving a serializable cart as an order. But it could be simple change - if ordernumber is null, generate it, otherwise, skip.
Not saying that would change anything or how would you do things in your code, but just want to put a perspective on it.
This is with reference to en existing thread
https://world.optimizely.com/forum/developer-forum/Commerce/Thread-Container/2018/7/customising-or-seeding-order-numbers/
I followed the articles
https://episerveradventures.com/2021/02/01/change-order-number-generator/
https://www.patrickvankleef.com/2017/05/22/episerver-commerce-generating-an-order-number/
the fix is simple and it works seamlessely in the default QuickSilver solution. However with the project solution, there is something in the solution which is preventing the overide to happen and the deault IOrderNumberGenerator takes the precedence.
Any lead on how to go about this?
Much Appreciated
Thanks,
Amol
Custom class to override
Registration of the class
[ServiceConfiguration(ServiceType = typeof(IOrderNumberGenerator), Lifecycle = ServiceInstanceScope.Singleton)]
public class OrderNumberGeneratorDecorator : IOrderNumberGenerator
{
private readonly IOrderNumberGenerator _inner;
public OrderNumberGeneratorDecorator(IOrderNumberGenerator inner)
{
_inner = inner;
}
public string GenerateOrderNumber(IOrderGroup orderGroup)
{
var num = new Random().Next(1000, 9999);
return $"XXX-{orderGroup.OrderLink.OrderGroupId}-{num}";
}
}
[InitializableModule]
[ModuleDependency(typeof(ServiceContainerInitialization))]
[ModuleDependency(typeof(ConfigurationInitialization))]
[ModuleDependency(typeof(CommerceInitialization))]
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class InitializationModule1 : IConfigurableModule
{
public void ConfigureContainer(ServiceConfigurationContext context)
{
context.Services.RemoveAll<IOrderNumberGenerator>();
context.Services.AddSingleton<IOrderNumberGenerator, OrderNumberGeneratorDecorator>();
}
public void Initialize(InitializationEngine context)
{
//Add initialization logic, this method is called once after CMS has been initialized
}
public void Uninitialize(InitializationEngine context)
{
//Add uninitialization logic
}
}