Adding custom behavior for migrating carts

 

We need to add some custom behavior for when episever is merging cart from an anonymous user to a logged in user. 

I can see the magic is happening in EPiServer.Business.Commerce.HttpModules.ProfileModule.Profile_MigrateAnonymous method and more spesific in the CartMigrator. Digging into CartMigrator we can see that the code we need to change lies in IOrderGroupExtensions which has a internal method called CopyLineItems.

Creating custom methodes to override episerver all the way down to CopyLineItems is not something i want to do. so my question is; can this be done in an easier way?

#178477 Edited, May 11, 2017 14:29
  • Member since: 2016
     

    I guess the "simplest" would be to make your own method to do this. Then call this method yourself when relevant. 

    You'll have to
    1. Load the anonymous cart.
    2. Perform your business specific logic on that cart to get what items should be added/ignored/removed/etc
    3. Create the logged in users cart (if necessary)
    4. Add/remove line items in the logged in users' cart.
    5. Make sure the lineItems MetaFields get carried over (if applicable)
    5. Delete the anonymous cart (optional, but should be done if you know that it will never be used again.)

    (If you're logging in a user, make sure to keep a reference to the anonomous contact id (CustomerContext.Current.CurrentContactId) during the migration process before logging in the user.)

    Finally you should remove:

    <add name="ProfileModule" type="EPiServer.Business.Commerce.HttpModules.ProfileModule, EPiServer.Business.Commerce"/>

    from your web.config.

    We've done this in our current project and it has worked great, but obviously not ideal if you want to leave the control of calling the method to Episerver.

    #178482 Edited, May 11, 2017 15:45
  • Member since: 2016
     

    What version are you using? I can't seem to find the call to IOrderGroupExtensions.CopyLineItems() in CartMigrator. :O

    #178484 Edited, May 11, 2017 16:26
  •  

    Hi Jafet!

    We're using version 10.4.0.0.

    did you remove the first answer you had because it was not valid?

    #178485 May 11, 2017 16:41
  • Member since: 2016
     

    I removed it because that solution could possibly be more work than trying to change CartMigrator. It's better if we try modifying that first. :) (I might put the answer back if we can't find a way)


    Anyway, the reason why it's called IOrderGroupExtensions is because it's extension methods should be available to everything that inherits/implements IOrderGroup. (for example: IOrderGroup, Cart, ICart, PurchaseOrder, IPurchaseOrder etc etc).

    And since we're dealing with an extension method in a static class you can't really "override it" in the usual sense. A possible workaround for that could be creating your own "CopyLineItems" extension-method with your own logic, then calling that instead of the one from IOrderGroupExtensions. But this approach is dependant on that you can override the method calling IOrderGroupExtensions.CopyLineItems in the first place. Hopefully you can get away with overriding just that instead of everything beginning from CartMigrator.

    Which class is calling it in your case? (I'm on 10.2.3 and still can't find it :P)

    #178487 Edited, May 11, 2017 17:13
  •  

    OK, makes sense now with the name IOrderGroupExtensions. 

     

    EPiServer.Business.Commerce.HttpModules.ProfileModule.Profile_MigrateAnonymous uses methode MigrateCarts which is calling CartMigrator's MigrateCarts. This method uses its private methode MergeForms which calls IOrderGroupExtensions CopyLineItems.

    #178494 May 11, 2017 19:36
  • Member since: 2016
     

    I upgraded my testing site to the latest version and tried to make it work by overriding CartMigrator. But since it's not based on an interface and because it's public methods aren't virtual I couldn't get it to work using Dependency Injection.

    I guess this leaves you with two choices:

    1. Do it like my answer above.
    2. If you'd like to retain the "automatic" migration upon logging in, create your own implemenation of every step (yes, like you feared in your original post): A IHttpModule like the existing ProfileModule, A CartMigrator similar to CartMigrator and then finally create your modified version of the CopyLineItem-extension method. Also make sure to point:

    <add name="ProfileModule" type="EPiServer.Business.Commerce.HttpModules.ProfileModule, EPiServer.Business.Commerce"/>

    in Web.config to your IHttpModule instead.

    #178516 Edited, May 12, 2017 11:20
  •  

    Thanks for the feedback Jafet.

    I've reported this as a feature request to EPiServer. Not sure which option i'll go for but of course having epi adding this functionality would be something i might wait for if i get feedback quickly.

    #178517 May 12, 2017 11:37
  •  

    Ended up solving the issue using my own IHttpModule. But i must take care to add new/changed functionality if episerver updates this module. and of course go back to use episervers module if they provide us with a proper solution.

    #178527 May 12, 2017 13:46
  • Member since: 2011
     

    IProfileModule is so in the past :). With newer version of Episerver Commerce (10.4 or newer, IIRC), you can just implement your own IProfileMigrator and register it in your initialization module. The interface looks like this

        public interface IProfileMigrator
        {
            /// <summary>
            /// Migrates the orders.
            /// </summary>
            /// <param name="anonymousId">The anonymous identifier.</param>
            void MigrateOrders(Guid anonymousId);
    
            /// <summary>
            /// Migrates the carts.
            /// </summary>
            /// <param name="anonymousId">The anonymous identifier.</param>
            void MigrateCarts(Guid anonymousId);
    
            /// <summary>
            /// Migrates the wishlists.
            /// </summary>
            /// <param name="anonymousId">The anonymous identifier.</param>
            void MigrateWishlists(Guid anonymousId);
        }



    #178540 May 12, 2017 19:47
  •  

    Perfect! Just what i wanted. 

    #178556 May 15, 2017 8:34