How to write a plugin that's triggered on order status change ?

Started by dmb, June 27, 2020, 15:05:24 PM

Previous topic - Next topic

dmb

Hi,

J 3.9.19
VM 3.4.2

I've built a system over the years for managing our face-to-face events (VM products). It has a feature that searches for orders for a specific product, and creates registration records for confirmed orders, which allow our attendees to access presentation material etc. in advance of the event. It also deletes registrations for cancelled orders. This has worked fine - I just run the update a few times before the event, and emails are sent out to new attendees with links to let them in.

Now I've extended it to cover online webinars and manually triggering the process is not good enough: people often pay to join events that have already started and they need instant access so I'd like to have this register/de-register process run whenever an order status changes to confirmed or cancelled (and maybe other statuses).

I've been trying to piece this together, and I *think* I need to write a vmcustom plugin with a function plgVmOnUpdateOrderPayment ($data,$old_order_status) that somehow gets called whenever an order is updated. Is this anywhere near true ?

I'm written lots of content plugins, but I don't know how the VM plugins work - what gets called when. I'm happy to read the docs or any examples if there's anything out there that  some kind soul can point me towards.

Thanks,

David

Jörgen

There is custom text input plugin, that could be used as example if remember correctly. Check it out and see if the call is in there.

Jörgen @ Kreativ Fotografi
Joomla 3.9.18
Virtuemart 3.4.x
Olympiantheme Hera (customized)
This reflects current status when viewing old post.

Jörgen

Hum, if it does not get called, unless used as custom field, you need to use maybe a system plugin. But i think it could work.
Jörgen
Joomla 3.9.18
Virtuemart 3.4.x
Olympiantheme Hera (customized)
This reflects current status when viewing old post.

dmb

Hi Jörgen,

Thanks, I'll have a look. I found a tiny hint in another post that plugins based on vmcustom need to be attached as custom fields to every relevant product, so that might work. However it also suggested that if they're based on vmcalculation then they automatically get called for every product, but no indication when :)

I suppose the big problem is that I need this to happen whenever the status changes for any reason, e.g. someone buys from the FE, admin adds or updates an order from the BE, Paypal asynchronously confirms a payment and the status goes from Pending to Confirmed ... I may have to abandon the approach of plugins and go for a cron job checking every minute ... yuck !!

Cheers,

David

pinochico

You need create system plugin with right trigger (I think plgVmOnUpdateOrderPayment is ,ybe right by I dont know sure) for change in FE or BE.
In this plugin you must add cli php file and then you can call by cron.

That is all.

Sure not use customfield or vmcustom text.

I recommend write every change status order to log file from this plugin and setup in plugin - Create log or not.

If you nedd we can create for you
www.minijoomla.org  - new portal for Joomla!, Virtuemart and other extensions
XML Easy Feeder - feeds for FB, GMC,.. from products, categories, orders, users, articles, acymailing subscribers and database table
Virtuemart Email Manager - customs email templates
Import products for Virtuemart - from CSV and XML
Rich Snippets - Google Structured Data
VirtueMart Products Extended - Slider with products, show Others bought, Products by CF ID and others filtering products

dmb

Hi,

Thanks for the reply, but as I mentioned, I already have a component that does this on a button press from the backend, so I could just set up a cron job to wget this once a minute. It's a real kludge though, wasteful of resource while also potentially annoying to people buying the event who will want to join without wondering if an email is going to show up.

Hopefully there's a hook or an override approach that will let me integrate the functionality smoothly.

Cheers,

David

pinochico

QuoteI could just set up a cron job to wget this once a minute

oh my goodness :)

wget once a minute?, Do you understand how function wget - go on Frontend and then lock DB table after calling cron. All customers waiting for ending your cron (every minute). If my developer will be created this, then maybe I will shoot him :D

No, pls thinking a more time about this. You need cli cron (call as php from backend separately from frontend).

We have a lot of extensions with buttons in admin:
- plugin for cleanning media from Patrick (shop42)
- plugin for deleting customfiled from child, if child is discontinued (then parameters from child not showing in CustomFilters Pro)
- plugin for synchronization payments from any banks and change bank transfer to payed
- plugin for creating greetings for acymailing newsletter, if customer created order

and all plugins have cli crons.


Next, I think better for you is forgot about your button in component and create new system plugin with cron. Then you don't need button.

But is your project, maybe you have only 1-2 event per month, then is better go in administration and click on button. Customers will be waiting.
www.minijoomla.org  - new portal for Joomla!, Virtuemart and other extensions
XML Easy Feeder - feeds for FB, GMC,.. from products, categories, orders, users, articles, acymailing subscribers and database table
Virtuemart Email Manager - customs email templates
Import products for Virtuemart - from CSV and XML
Rich Snippets - Google Structured Data
VirtueMart Products Extended - Slider with products, show Others bought, Products by CF ID and others filtering products

dmb

OK, let's drop the cron discussion - I've said from the outset that this is not a viable solution. CLI via cron is just as bad as any other method, it's just lipstick on a pig.

Any other ideas welcome  :)

David

AH

Felt I had to respond especially because of "lipstick on a pig"  ;D

I agree that doing this manually must be a real headache.

As you suggested earlier create yourself a  plugin could do the trick as Order update will call the triggers:-

$_returnValues = $_dispatcher->trigger('plgVmOnUpdateOrderShipment',array(&$data,$old_order_status,$inputOrder));
$_returnValues = $_dispatcher->trigger('plgVmOnUpdateOrderPayment',array(&$data,$old_order_status,$inputOrder));

You could even clone a payment plugin and adjust to meet your own needs it can do whatever you need without any manual intervention as you get all the order data as well.
Create your own fields that are updated and even your own triggers that can be called when things are displayed to retrieve and show your date etc etc

You could describe your own table and get data update and use this data as and when required in various places


And for cancelled you could also use
$_dispatcher->trigger('plgVmOnCancelPayment',array(&$data,$old_order_status));
But you should be able to determine what you require from the payment/shipment trigger

If you look in the orders model you will see various triggers and functions.

My simple brain seems to point to you handling things by order status.

Regards
A

Joomla 4.4.5
php 8.1

pinochico

to AH:

thanks for detailed info - you send a lot of options.
I must send to my developers too :D
www.minijoomla.org  - new portal for Joomla!, Virtuemart and other extensions
XML Easy Feeder - feeds for FB, GMC,.. from products, categories, orders, users, articles, acymailing subscribers and database table
Virtuemart Email Manager - customs email templates
Import products for Virtuemart - from CSV and XML
Rich Snippets - Google Structured Data
VirtueMart Products Extended - Slider with products, show Others bought, Products by CF ID and others filtering products

dmb

Fantastic AH, I think this is what I need !

Following your suggestions I've dredged through orders.php, and I *think* I see how this works now.

So I wrote a vmcalculation plugin, with plgVmOnUpdateOrderShipment() and plgVmOnUpdateOrderPayment() functions. I also included plgVmConfirmedOrder() which seems to be triggered when the user checks out but before they pay. For free events this sets the status per VM configuration to "Confirmed by user", and for non-free events the order status is Pending. Once Paypal confirms the payment, plgVmOnUpdateOrderPayment() is called with the new status Confirmed.

I then added in plgVmOnCancelPayment(), and yaay !!! That gets called, with order_status = Cancelled/Refuunded/etc. when an order is updated from the backend.

Thanks loads !

David

AH

dmb

yes - you are definitely on the right track

Get your plugin to handle any triggers and even write your own custom ones that can be fired from custom page overrides

e.g. - this gets any stored shipping dates for an order when an order is viewed/printed/invoiced etc

JPluginHelper::importPlugin('vmshipment');
$dispatcher = JDispatcher::getInstance();
$ship_date = $dispatcher->trigger('plgVmgetShipDates', $this->orderdetails['details']['BT']->virtuemart_order_id);




The trigger is in the plugin:

public function plgVmgetShipDates($virtuemart_order_id){

  some stuff

}




Your plugin can create a table for your plugin to store associated data and you can get functions to write read data as you require from that table or any table

Regards
A

Joomla 4.4.5
php 8.1

pinochico

I would like to know why the type of vmcalculation plugin, what is the advantage over vmcustom or system
www.minijoomla.org  - new portal for Joomla!, Virtuemart and other extensions
XML Easy Feeder - feeds for FB, GMC,.. from products, categories, orders, users, articles, acymailing subscribers and database table
Virtuemart Email Manager - customs email templates
Import products for Virtuemart - from CSV and XML
Rich Snippets - Google Structured Data
VirtueMart Products Extended - Slider with products, show Others bought, Products by CF ID and others filtering products

AH

I just think he already had created that type of plugin first
Regards
A

Joomla 4.4.5
php 8.1

dmb

It was because from what I read (though I don't know if it's correct, but it works !) plugins based on vmcustom have to be added to each individual product as custom fields. This would be great for plugins that are only required to fire for specific products.

However I read that those based on vmcalculation (and maybe others) are triggered for every product without being attached specifically. As I wanted the post-processing hook for all of our products I took this route and this is the behaviour I'm getting.

Cheers,

David