VirtueMart Forum

VirtueMart 2 + 3 + 4 => Plugins: Payment, Shipment and others => Topic started by: dmb on June 27, 2020, 15:05:24 PM

Title: How to write a plugin that's triggered on order status change ?
Post by: dmb on June 27, 2020, 15:05:24 PM
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
Title: Re: How to write a plugin that's triggered on order status change ?
Post by: Jörgen on June 27, 2020, 18:15:05 PM
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
Title: Re: How to write a plugin that's triggered on order status change ?
Post by: Jörgen on June 27, 2020, 18:27:52 PM
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
Title: Re: How to write a plugin that's triggered on order status change ?
Post by: dmb on June 27, 2020, 19:23:52 PM
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
Title: Re: How to write a plugin that's triggered on order status change ?
Post by: pinochico on June 27, 2020, 22:54:08 PM
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
Title: Re: How to write a plugin that's triggered on order status change ?
Post by: dmb on June 28, 2020, 02:30:07 AM
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
Title: Re: How to write a plugin that's triggered on order status change ?
Post by: pinochico on June 28, 2020, 04:16:48 AM
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.
Title: Re: How to write a plugin that's triggered on order status change ?
Post by: dmb on June 28, 2020, 12:42:25 PM
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
Title: Re: How to write a plugin that's triggered on order status change ?
Post by: AH on June 28, 2020, 13:50:15 PM
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.

Title: Re: How to write a plugin that's triggered on order status change ?
Post by: pinochico on June 28, 2020, 14:17:32 PM
to AH:

thanks for detailed info - you send a lot of options.
I must send to my developers too :D
Title: Re: How to write a plugin that's triggered on order status change ?
Post by: dmb on June 28, 2020, 16:15:23 PM
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
Title: Re: How to write a plugin that's triggered on order status change ?
Post by: AH on June 28, 2020, 17:23:21 PM
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

Title: Re: How to write a plugin that's triggered on order status change ?
Post by: pinochico on June 28, 2020, 17:40:54 PM
I would like to know why the type of vmcalculation plugin, what is the advantage over vmcustom or system
Title: Re: How to write a plugin that's triggered on order status change ?
Post by: AH on June 28, 2020, 17:43:40 PM
I just think he already had created that type of plugin first
Title: Re: How to write a plugin that's triggered on order status change ?
Post by: dmb on June 28, 2020, 22:57:01 PM
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
Title: Re: How to write a plugin that's triggered on order status change ?
Post by: pinochico on June 28, 2020, 23:55:13 PM
To David:

Thanks :)
Title: Re: How to write a plugin that's triggered on order status change ?
Post by: Marttyn on October 04, 2022, 12:25:10 PM
Could you share your solution on this?
Im trying to do something similar: https://forum.virtuemart.net/index.php?topic=148928.0