How can I execute plugin method when order placed

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
11 years ago
Is there a way to execute a piece of code in a plugin when an order is placed without changing the core source code?

I'd like my plugin to do some work when an order is placed but want to keep changes restricted to the plugin.

Thanks for any help.

Darren
11 years ago
Have a look at the OrderPlacedEvent event (Nop.Core.Domain.Orders namespace)
11 years ago
More notably, take a look at this file:

\nopcommerce\src\Plugins\Nop.Plugin.SMS.Clickatell\OrderPlacedEventConsumer.cs

Link at the repo:
http://nopcommerce.codeplex.com/SourceControl/changeset/view/e64ec069d646#src%2fPlugins%2fNop.Plugin.SMS.Clickatell%2fOrderPlacedEventConsumer.cs

Here you see how it's defined an IConsumer with the HandleEvent method, plus it's done in a Plugin, you can simply copy from that.
11 years ago
This is great! Thanks very much guys.

"Favorite Categories" plugin should be ready next week. I'll share as soon as it's done.
11 years ago
Nice!
11 years ago
I'm having problems with this line in the HandleEvent method

var plugin = pluginDescriptor.Instance() as FavoriteCategoriesPlugin;


When going off to get an Instance() the code never returns to the HandleEvent method and so doesn't execute the rest of the code in it.

I've followed the code through many many child methods and can't work out why it doesn't return an instance of the plugin.

This is the last hurdle before finishing the plugin (I hope!)

Hope someone can help with this. Would be hugely appreciated.

Darren
11 years ago
Well, the HandleEvent method is called on the Consumer in EvnentHandler#PublishToConsumer


        private static void PublishToConsumer<T>(IConsumer<T> x, T eventMessage)
        {
            try
            {
                x.HandleEvent(eventMessage);
            }


And this happens when the Publish() method is called (with the relevant Event type)


        public void Publish<T>(T eventMessage)
        {
            var subscriptions = _subscriptionService.GetSubscriptions<T>();
            subscriptions.ToList().ForEach(x => PublishToConsumer(x, eventMessage));
        }


The subscriptionService uses reflection to gather all the IConsumer types with the template parameter equal to the event type.

So if your plugin implement IConsumer<OrderPlacedEvent>, when that event is fired (on the PlaceOrder method of the OrderProcessingService) YourPlugin.HandleEvent() should be called, asking for an instance shouldn't trigger the event.

You can try this yourself by breaking on the Publish method when you place an order, and see how the IConsumers defined on the SMS plugins gets loaded and called.

Check that the Plugin is actually being loaded though!

Hope i didn't misunderstood your issue here, anyway if you want you can provide code to aid debugging.
11 years ago
M.Ang wrote:
Well, the HandleEvent method is called on the Consumer in EvnentHandler#PublishToConsumer


        private static void PublishToConsumer<T>(IConsumer<T> x, T eventMessage)
        {
            try
            {
                x.HandleEvent(eventMessage);
            }


And this happens when the Publish() method is called (with the relevant Event type)


        public void Publish<T>(T eventMessage)
        {
            var subscriptions = _subscriptionService.GetSubscriptions<T>();
            subscriptions.ToList().ForEach(x => PublishToConsumer(x, eventMessage));
        }


The subscriptionService uses reflection to gather all the IConsumer types with the template parameter equal to the event type.

So if your plugin implement IConsumer<OrderPlacedEvent>, when that event is fired (on the PlaceOrder method of the OrderProcessingService) YourPlugin.HandleEvent() should be called, asking for an instance shouldn't trigger the event.

You can try this yourself by breaking on the Publish method when you place an order, and see how the IConsumers defined on the SMS plugins gets loaded and called.

Check that the Plugin is actually being loaded though!

Hope i didn't misunderstood your issue here, anyway if you want you can provide code to aid debugging.


Thanks for getting back to me. Here is my HandleEvent Method

 public void HandleEvent(OrderPlacedEvent eventMessage)
        {
        

            //is plugin installed?
            var pluginDescriptor = _pluginFinder.GetPluginDescriptorBySystemName("Misc.FavoriteCategories");
            if (pluginDescriptor == null)
                return;

            var plugin = pluginDescriptor.Instance() as FavoriteCategoriesPlugin;

            if (plugin == null)
                return;

            var order = eventMessage.Order;
          
            if (plugin.AddFavoriteCategories(order.Id))
            {
                order.OrderNotes.Add(new OrderNote()
                {
                    Note = "Categories Added to favorites if valid",
                    DisplayToCustomer = false,
                    CreatedOnUtc = DateTime.UtcNow
                });
                _orderService.UpdateOrder(order);
            }
        }


The code never gets passed this line

  var plugin = pluginDescriptor.Instance() as FavoriteCategoriesPlugin;


When debugging you go down a huge hierarchy of methods before returning to the web browser and the order is placed without executing ever executing this

plugin.AddFavoriteCategories(order.Id)
11 years ago
Well, the only thing i can come up with is that the Instance() method fails to create an instance of the plugin for some reason, thus returning early.

But i need the whole plugin implementation to try and debug this, sorry
11 years ago
M.Ang wrote:
Well, the only thing i can come up with is that the Instance() method fails to create an instance of the plugin for some reason, thus returning early.

But i need the whole plugin implementation to try and debug this, sorry


I'd really appreciate you looking at the plugin for me. What's the best way for me to get a .zip to you? Could you PM me your email address?

Darren
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.