VirtueMart Forum

VirtueMart 2 + 3 + 4 => Virtuemart Development and bug reports => Development & Testing => Topic started by: gba on April 15, 2015, 17:40:03 PM

Title: Set order status via URL - possible?
Post by: gba on April 15, 2015, 17:40:03 PM
Hi community!

In BE view of an order you can manually update the order status.
Is there a possibility to update the status via an URL?
Like i.e.:
http://myshop.com/index.php?option=com_virtuemart&view=orders&task=updatestatus&order_status=S&order_number=a73e031&order_pass=p_958d6

Any useful hints are very welcome!

Kind regards,
Gerald

EDIT:
Of course on updating the status via URL everything shall work like having it manually done in BE (update status in DB, send e-mails according to configuration, etc.)
Title: Re: Set order status via URL - possible?
Post by: gba on April 15, 2015, 21:32:13 PM
Hi VM development team!

I seem to be on a good path.
I created a component 'com_updateorderstatus' having following code in FE:if (!class_exists( 'VmConfig' )) require(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_virtuemart'.DS.'helpers'.DS.'config.php');

$data = vRequest::getRequest();
$model = VmModel::getModel('orders');
$virtuemart_order_id = $model->getOrderIdByOrderPass($data['order_number'],$data['order_pass']);
$order = array();
$order[$virtuemart_order_id] = ($data);
$result = $model->updateOrderStatus($order);


The URL I use is:
http://myshop.com/index.php?option=com_updateorderstatus&order_number=150415105101&order_pass=C2gVIMHH&order_status=U

But $data needs to contain some information more, than just my own parameters.
The main work seems to be done in function updateStatusForOneOrder() in file /administrator/components/com_virtuemart/models/orders.php, right?

Could you, please, give me a hint, what parameters exactly are needed to update the order status and to run all necessary triggers?
I'd be very grateful for any help!

Kind regards,
Gerald
Title: Re: Set order status via URL - possible?
Post by: GJC Web Design on April 15, 2015, 22:12:12 PM
Your basically imitating what the response part of any payment plugin does

perhaps a comp is a bit over kill - you could probably do it as a dummy payment plugin and use the std. response url (pm is the payment method id)
you could set its filter to some extra high cart amount so it doesn't show on the frontend

index.php?option=com_virtuemart&view=vmplg&task=pluginresponsereceived&on=5555555&pm=6&order_status=U&order_pass=xxxxx

in the plugin is
function plgVmOnPaymentResponseReceived (&$html) {
      
      
      if (!class_exists ('VirtueMartModelOrders')) {
         require(JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php');
      }
      $jinput = JFactory::getApplication()->input;
      $return = $jinput->getArray(array( 'on' => '', 'pm' => '', 'order_status' => '', 'order_pass' => ''));

                $model = VmModel::getModel('orders');
              $virtuemart_order_id = $model->getOrderIdByOrderPass($return['on'],$return['order_pass']);
               $order = $model->getOrder($virtuemart_order_id);

                 result = $model->updateStatusForOneOrder ($virtuemart_order_id, $order, TRUE);
}

might work

if you look at a simple payment plugin










Title: Re: Set order status via URL - possible?
Post by: gba on April 20, 2015, 15:02:57 PM
Hello!

Thank you very much for your hint.
This approach makes for sure, that calling this URL all triggers will be run like if I would update the order status in backend manually?

Kind regards,
Gerald
Title: Re: Set order status via URL - possible?
Post by: GJC Web Design on April 20, 2015, 22:16:41 PM
exactly
Title: Re: Set order status via URL - possible?
Post by: gba on April 21, 2015, 13:36:32 PM
Hello!

I really tried hard to implement your example, but it seems as if the parameters are not completely right:
The function plgVmOnPaymentResponseReceived() in my "payment" plugin seems not to be triggered.
There is no place in the VM source code, where the parameter 'task' can is checked for value 'pluginresponsereceived'.

BTW: What difference is between view=vmplg and view=pluginresponse?

Kind regards,
Gerald
Title: Re: Set order status via URL - possible?
Post by: GJC Web Design on April 21, 2015, 15:15:46 PM
components\com_virtuemart\controllers\vmplg.php
Title: Re: Set order status via URL - possible?
Post by: gba on April 21, 2015, 16:34:53 PM
Thank you very much for your help!
I decided to stick to a tiny component.

In the site part I have following code:<?php
// no direct access
defined'_JEXEC' ) or die( 'Restricted access' );

if (!
class_exists'VmConfig' )) require(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_virtuemart'.DS.'helpers'.DS.'config.php');
VmConfig::loadConfig();
VmConfig::setdbLanguageTag();
$jinput JFactory::getApplication()->input;
$rdata $jinput->getArray(array('on'=>'','op'=>'','os'=>''));
$model VmModel::getModel('orders');
$virtuemart_order_id $model->getOrderIdByOrderPass($rdata['on'],$rdata['op']);
$order = array();
$order['order_status'] = $rdata['os'];
$orderstatusForShopperEmail VmConfig::get('email_os_s',array('U','C','S','R','X'));
if(!
is_array($orderstatusForShopperEmail)) $orderstatusForShopperEmail = array($orderstatusForShopperEmail);
$order['customer_notified'] = (in_array($order['order_status'],$orderstatusForShopperEmail)) ? 0;
$order['include_comment'] = 0;
$result $model->updateStatusForOneOrder ($virtuemart_order_id,$order,TRUE);
echo 
$result;


And here is an example URL for using it to update the order status:
http://myshop.com/index.php?option=com_updateorderstatus&on=150415105101&op=C2gVIMHH&os=U&format=raw

This way I get 1 if succeeded, otherwise 0.
What does the VM community think about that?  ;)

Best regards,
Gerald
Title: Re: Set order status via URL - possible?
Post by: Milbo on April 21, 2015, 18:49:13 PM
nice done, check for security
Title: Re: Set order status via URL - possible?
Post by: gba on April 21, 2015, 21:02:28 PM
Thank you  :)
Check for security?
Doesn't function getOrderIdByOrderPass() already check security??

Kind regards,
Gerald
Title: Re: Set order status via URL - possible?
Post by: inkomico on January 30, 2016, 19:17:35 PM
Hello gba, can you share this component?

Thanks!
Title: Re: Set order status via URL - possible?
Post by: gba on February 02, 2016, 13:16:07 PM
Hi!

The question about the security issue mentioned is not ansered, yet.
The code you can find above.

Kind regards,
Gerald
Title: Re: Set order status via URL - possible?
Post by: inkomico on February 03, 2016, 19:47:58 PM
Ok, thanks. I'll create the component and try.
Title: Re: Set order status via URL - possible?
Post by: Adwans on September 05, 2016, 23:01:50 PM
Hello everybody!
So I decided to prepare a plugin according to your , gba and GJC tips. Dummy payment plugin. With only one php file containing only one function:
function plgVmOnPaymentResponseReceived( &$virtuemart_order_id, &$html) {
if (!class_exists ('VirtueMartModelOrders')) {
     require(JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php');
      }
     $jinput = JFactory::getApplication()->input;
     $statusy = array( 'P' => 'oczekujący', 'U' => 'potwierdzony przez użytkownika', 'C' => 'potwierdzony', 'S' => 'wysłany','X' => 'anulowany','R' => 'zwrócony');

$return = $jinput->getArray(array( 'on' => '', 'os' => ''));
        $model = VmModel::getModel('orders');
.....

and - URL status change works! Also sends email to me everytime it happens.
BUT :( I missed sth, since PLugin interrupts "VM payments method edit page" - FOR EXAMPLE:
With plugin enabled:
/administrator/index.php?option=com_virtuemart&view=paymentmethod&task=edit&cid[]=7
is blank.
With plugin disabled - is ok.
What is wrong? Does payment plugin need some another file, config, language? More plugin must-be functions?

@GJC maybe this is the reason:
Quoteyou could set its filter to some extra high cart amount so it doesn't show on the frontend
This is my first approach to this topic, since I only desired to manipulate order status - not to have any new payment created .
Regards!
Title: Re: Set order status via URL - possible?
Post by: GJC Web Design on September 06, 2016, 09:51:47 AM
I guess you should add to the plug the conditions function to stop it being called during the edit

maybe by amount or detect if FE/admin or look for a url var etc .. depends how your using this

e.g. with an amount

protected function checkConditions ($cart, $method, $cart_prices) {
$amount = $this->getCartAmount($cart_prices);
if($amount < 999999999) { return false;}
}
Title: Re: Set order status via URL - possible?
Post by: Adwans on September 06, 2016, 17:43:36 PM
Hello!
I tried:
protected function checkConditions ($cart, $method, $cart_prices) {
$amount = $this->getCartAmount($cart_prices);
if($amount < 999999999) { return false;}

}
function plgVmOnShowOrderBEPayment ($virtuemart_order_id, $virtuemart_payment_id) {
return false;
}

with no success. Maybe is there any function in charge of BE paymentmethod editing? However, it is called from another view and task.
Or plugin is "listening" and waiting for some parameters?
Quotemaybe by amount or detect if FE/admin or look for a url var etc .. depends how your using this
I use this that way:
index.php?option=com_virtuemart&view=vmplg&task=pluginresponsereceived&pm=6&on=HERE-ORDER-NUMBER&os=C as for Confirmed
add some parameter? or pm=6 is wrong?
NOTE: I can see that plugin obeys this:
if (strstr($view,'paymentmethod')) ... //editing payments
else if (strstr($view,'vmplg') ) // plugin working
{

What should I put after ($view,'paymentmethod')) ?
Title: Re: Set order status via URL - possible?
Post by: Adwans on September 06, 2016, 18:33:57 PM
OK, I got it  ;D SOLVED
Thanks Rupostel! for creating this and @GJC for mention: Great plugin that saves you a lot of (free) time:
https://www.rupostel.com/utilities-for-joomla/extensions/fatal-catcher-plugin (https://www.rupostel.com/utilities-for-joomla/extensions/fatal-catcher-plugin)
This plugin has allowed to find the bug, one faulty $require.
Now set order status via URL plugin works fine, sends emails to me, and also doesnt interfere with any edit admin page  :)
If you ever have any WSOD, use this plugin.
Title: Re: Set order status via URL - possible?
Post by: GJC Web Design on September 06, 2016, 21:14:26 PM
https://www.rupostel.com/utilities-for-joomla/extensions/fatal-catcher-plugin

can only agree -- some servers are almost impossible to access logging and this is the 1st tool to use in this case - thanks Stan
Title: Re: Set order status via URL - possible?
Post by: gba on September 29, 2016, 15:25:02 PM
Quote from: gba on April 21, 2015, 21:02:28 PM
Check for security?
Doesn't function getOrderIdByOrderPass() already check security??
Does it or does it not?  ???

Kind regards,
Gerald
Title: Re: Set order status via URL - possible?
Post by: cybersholt on June 06, 2017, 17:29:19 PM
Just wanted to say thanks, the info here helped create something similar that changes the order status to shipped & includes some tracking info as a comment.
Title: Re: Set order status via URL - possible?
Post by: Adwans on June 22, 2017, 18:02:31 PM
Quote from: gba on September 29, 2016, 15:25:02 PM
Quote from: gba on April 21, 2015, 21:02:28 PM
Check for security?
Doesn't function getOrderIdByOrderPass() already check security??
Does it or does it not?  ???
Kind regards,
Gerald
Hi Gerald, I wonder the same. Maybe Milbo say sth less .. enigmatic?.
My ideas since now:
1. checking of logged in user *not guest ?
look:
http://forum.virtuemart.net/index.php?topic=129339.msg445160#msg445160
2. checking if logged-in user is the person which had created specific order in question?
Any further ideas?
:D
Title: Re: Set order status via URL - possible?
Post by: Milbo on June 22, 2017, 21:20:20 PM
for example

if(!vmAccess::manager('core') ){
$msg = 'Forget IT';
$this->setRedirect('index.php?option=com_virtuemart', $msg);
}


Redirects any non Superadmin. Or use only vmAcess::manager(), checks for managers ('core.admin', 'core.manage', 'vm.manage'), which is usually the standard. You can also check for a certain right. The rights to check orders would be 'orders' => vmAccess::manager('orders') and only for order status change it is 'orders.status'. You can even check for more than one right and chain it or use it as or.

I just notice the right order.status is atm only used in the controllers, so it is not checked in your case.

It automatically checks also for Background admin rights. ;-) Makes fun