Overriding Purchase Order Number generation mechanism

Vote:
 

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

        }

    }

#270647
Edited, Jan 27, 2022 8:56
Vote:
 

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.

#270652
Jan 27, 2022 9:30
Vote:
 

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();
        }
    }

#270689
Jan 27, 2022 13:59
Vote:
 

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.

#270902
Jan 31, 2022 2:41
Vote:
 

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 

#271036
Feb 02, 2022 11:42
Vote:
 

Thanks Quan, It worked in this case.

Just a curiosity Does PurchaseOrder.TrackingNumber and IPurchaseOrder.OrderNumber affect the same field in the backend?

#271037
Feb 02, 2022 12:16
Vote:
 

Thanks Quan, It worked in this case.

Just a curiosity Does PurchaseOrder.TrackingNumber and IPurchaseOrder.OrderNumber affect the same field in the backend?

#271038
Feb 02, 2022 12:16
Vote:
 

they arre the same IIRC, TrackingNumber is the implementation of OrderNumber for PurchaseOrder 

#271039
Feb 02, 2022 12:21
Vote:
 

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. 

#271043
Feb 02, 2022 13:38
Vote:
 

Thanks Quan :)

#271044
Feb 02, 2022 13:43
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.