Jump to content

Changing order status in hookActionOrderStatusUpdate


Esnyper
 Share

Recommended Posts

Hi,

 

I'am developing module, which after „Payment Accepted“ state executs it's own process and if everything ok - changes order state to Shipped. For that I'am using hookActionOrderStatusUpdate:

public function hookActionOrderStatusUpdate($params)
{
  if($params['newOrderStatus']->id == 2)
        {
           if(!$this->doSomething())
              return false;            
        }
    return /*function for changing order's state*/;
}

But problem is, that new order status changes before „Payment Accepted“.

Example:

 

1. Waiting for bankwire payment

2. Delivered

3. Payment Accepted

 

Does anyone know how to reslove that problem?

P. S. tried hookActionOrderStatusPostUpdate. PS 1.6.0.9

Edited by Esnyper (see edit history)
  • Like 1

Share this post


Link to post
Share on other sites

I'm not sure I understand the issue.  Why are you changing the order status to delivered?

 

As for the correct hook to use, I would suggest using "actionPaymentConfirmation" instead.  This hook will only get triggered when the status changes to "Payment Accepted".

 

The hook you are using will get triggered any time the order status changes.

  • Like 1

Share this post


Link to post
Share on other sites

Problem is, that Delivered are before Payment Accepted.

 

Correct is: Awaiting bankwire -> Payment Accepted -> Shipped, not like now: Awaiting bankwire -> Shipped -> Payment Accepted (you ship your products before payment accepted?).

Share this post


Link to post
Share on other sites


private function changeOrderStatus($id_order)

{

$Order = new Order((int)$id_order);

return $Order->setCurrentState(5);

}

 

public function hookActionOrderStatusUpdate($params)

{

 

if($params['newOrderStatus']->id == 2)

{

if(!$this->doSomething())

return false;

return $this->changeOrderStatus((int)$params['id_order']);

}

return;

}

 

Edited by Esnyper (see edit history)

Share this post


Link to post
Share on other sites

You are using "actionOrderStatusUpdate" hook. This hook executes BEFORE the order status is changed to the "new" order status

 

If you want to do something AFTER the order status is changed to the "new" order status, you might want to use "actionOrderStatusPostUpdate"

Share this post


Link to post
Share on other sites

  • 1 month later...

Hi,

The bugtracker team points theres not a real bug.

You can achieve the expected behaviour using a Dynamic Hook. In this case, the following code will work:

public function hookActionObjectOrderHistoryAddAfter($params)
{

$orderHistory = $params['object'];
$order = new Order($orderHistory->id_order);
if ($order->getCurrentState()==$this->old_state) {

$orderHistory->changeIdOrderState($this->new_state, $order);
$orderHistory->add();

// Another way
// $order->setCurrentState($this->preparation_post_status);
}
}

Edited by PrestaNitro (see edit history)

Share this post


Link to post
Share on other sites

Well, I'm glad that you at least have a working solution.  However the fact that their hooks do not function properly, would still be a bug.

 

"actionOrderStatusPostUpdate" is executed after the status is updated, so the fact that you cannot use it to take some action is a bug

Share this post


Link to post
Share on other sites

  • 4 months later...

Hi

i'm trying to use the script with the dynamic hook, but there is no action after a modification of order's history.

i registered the hook :

if (!parent::install()OR 
            !$this->registerHook('displayAdminProductsExtra') OR
            !$this->registerHook('actionProductUpdate') OR
			!$this->registerHook('actionOrderStatusPostUpdate')	OR
            !$this->registerHook('actionObjectOrderHistoryAddAfter') OR
				
            !$this->runSql($sql))
			return false;
		return true;

And i wrote the same script :

public function hookActionObjectOrderHistoryAddAfter($params)
	{
	
	//	var_dump($params);
		$checkApprovalProducts = array();
		$orderHistory = $params['object'];
		$order = new Order($orderHistory->id_order);
		
		$products = $order->getProducts();
			
		//	var_dump($products);exit;
			
		foreach ($products as $key => $product)
		{
			//test: y a til un produit à valider ?
			$checkApproval = OrdersApprovalTable::loadByIdProduct($product['product_id']);
			if(isset($checkApproval->isApprovable) && $checkApproval->isApprovable >0) $checkApprovalProducts[] = $product['product_id'];
		}
		
		
		
		if ($order->getCurrentState()==Configuration::get('PS_OS_PREPARATION') && count($checkApprovalProducts)>0) {
		
			$orderHistory->changeIdOrderState(Configuration::get('PS_OS_APPROVALORDER'), $order);
			$orderHistory->add();
		}
	}
}

But after many orders, i did not see any action?

Share this post


Link to post
Share on other sites

Yes !

i begun with the hookActionOrderStatusPostUpdate.

But with this hook, the status change AFTER i made the first changeIdOrderState. the final status is not as expect.

public function hookActionOrderStatusPostUpdate($params)
	{
		
		// Getting differents vars
		$context = Context::getContext();
		$id_lang = (int)$context->language->id;
		$id_shop = (int)$context->shop->id;
		$checkApprovalProducts = array();
		
		if($params['newOrderStatus']->id == Configuration::get('PS_OS_PREPARATION')){
		
			$orderId = $params['id_order']; //Ok Id de la commande démarrée
			$order = new Order($orderId);
			$products = $order->getProducts();
			
		//	var_dump($products);
			
			foreach ($products as $key => $product)
			{
				//test: y a til un produit à valider ?
				$checkApproval = OrdersApprovalTable::loadByIdProduct($product['product_id']);
				if(isset($checkApproval->isApprovable) && $checkApproval->isApprovable >0) $checkApprovalProducts[] = $product['product_id'];
			}
			
		//	var_dump($checkApprovalProducts);exit;
					
			if(count($checkApprovalProducts)>0){
				$history = new OrderHistory();
				$history->id_order = (int) $orderId;
				$history->changeIdOrderState(Configuration::get('PS_OS_APPROVALORDER'), (int) $orderId);
				$history->add();
			}
		
		}	

Share this post


Link to post
Share on other sites

But with this hook, the status change AFTER i made the first changeIdOrderState. the final status is not as expect.

 

'actionOrderStatusPostUpdate is executed AFTER the order status is changed, that is why it is called "PostUpdate".  If you want to take action BEFORE the status has changed, then use 'actionOrderStatusUpdate'

 

If you are still having trouble, then stop posting code and start explaining in plain english what you are trying to accomplish

Share this post


Link to post
Share on other sites

Hi 

thanks for all your quick answers!

 

I would like to change the order status of a new order (Status "New") to an approval status, when there is one or more approval products in this order.

This approval status is a custom new parameter i added to each product.

 

I don't know if i'm clear enough?

Share this post


Link to post
Share on other sites

There is no such thing as "new" order status, unless you have added a custom order state.  Have you?

 

If you just want to take an action on any new order regardless of its order state, then use the 'actionValidateOrder' event.  This will trigger for every new order, and then you can execute your logic on the products and change the order status as required

Share this post


Link to post
Share on other sites

There is no such thing as "new" order status, unless you have added a custom order state.  Have you?

 

If you just want to take an action on any new order regardless of its order state, then use the 'actionValidateOrder' event.  This will trigger for every new order, and then you can execute your logic on the products and change the order status as required

 

hi bellini13

I added a custom order state in my module (Approval State). The "New State" i'm talking about, is the standard state of a new order.

 

I will try quickly the hook you specified and i will tell you if it's ok for me.

Share this post


Link to post
Share on other sites

I already explained this back on March 28th.   There are 2 static hooks you can use.

 

actionOrderStatusUpdate will get invoked BEFORE the order status is changed

actionOrderStatusPostUpdate will get invoked AFTER the order status is changed

 

You need to decide which one you want to use...

  • Like 1

Share this post


Link to post
Share on other sites

  • 4 months later...
  • 8 months later...
Hello

 

This is an old post, but maybe this will help someone... I also ran into problems with actionOrderStatusPostUpdate (didn't work as i expected.)

 

This is what i use to change order state on checkout, and it works.



public function hookActionOrderHistoryAddAfter($params)
{
$new_os = $params['order_history'];
//Only change state during checkout, and only after 'out of stock paid' state
if (isset($this->context->controller->php_self) && $this->context->controller->php_self == 'order' && $new_os->id_order_state == Configuration::get('PS_OS_OUTOFSTOCK_PAID')) {
$order = new Order($new_os->id_order);
$order->setCurrentState(Configuration::get('MY_CUSTOM_STATE_ID'));
}
}

Edited by WilliamDam.dk (see edit history)

Share this post


Link to post
Share on other sites

  • 4 months later...

Would it maybe be possible to prevent the status change by using hookActionObjectOrderHistoryAddBefore and make it change to the status it already had?

I'm asking since actionOrderStatusUpdate don't allow you to return anything back that could stop the update of an order status and we would really like to automate our systems as much possible by capture the money when an order is shipped. It would be a mess to first update an order to shipped, and then afterwards to payment failed.

Edited by Casper_O (see edit history)

Share this post


Link to post
Share on other sites

  • 5 months later...

Hello.

 

I have this code

    public function install()
    {
.....
        return parent::install() &&
            $this->registerHook('header') &&
            $this->registerHook('backOfficeHeader') &&
            $this->registerHook('actionOrderStatusPostUpdate') &&
            $this->registerHook('actionOrderStatusUpdate') &&
            $this->registerHook('actionValidateOrder') &&
			$this->installTab() &&
			$this->registerHook('displayBackOfficeHeader');
}

.......


    public function hookActionOrderStatusPostUpdate($params)
    {
        /* Place your code here. */
		Tools::fd($params, 'log'); 
		Tools::fd('hola hookActionOrderStatusPostUpdate', 'log'); 
    }

    public function hookActionOrderStatusUpdate($params)
    {
        /* Place your code here. */
		Tools::fd($params, 'log'); 
		Tools::fd('hola hookActionOrderStatusUpdate', 'log'); 

and not work. I change status of any order and not is print anything in log, ideas?

Share this post


Link to post
Share on other sites

  • 1 year later...
On 8/23/2015 at 5:17 AM, Esnyper said:

Hello,

sorry for the long time of silence.

I am using hookActionObjectOrderHistoryAddAfter and almost everything working fine, except Order current_status. It remains for last order state.

post-177402-0-80692600-1440321477_thumb.png

 

I was able to get it to work by using "hookActionOrderHistoryAddAfter" instead of "hookActionObjectOrderHistoryAddAfter" as per WilliamDam.dk's advice.

Share this post


Link to post
Share on other sites

  • 1 year later...
  • 1 year later...

⚠️WARNING : a lot of examples above use hookActionObjectOrderHistoryAddBefore, this a dynamic hook where you should replace the object part with the targeted "object name", in this case it should be hookActionOrderHistoryAddAfter.


Anyway: I confirm that the correct solution is to use  hookActionOrderHistoryAddAfter, the hookActionOrderStatusPostUpdate solution is not working, regardless how you try to add a new state it will never be the last one.

Here's a working example:

<?php
// ...
public function install() {
    // Register the actionOBJECTAddAfter hook
    return parent::install() &&
      $this->registerHook('actionOrderHistoryAddAfter');
}

// Put your logic here.
public function hookActionOrderHistoryAddAfter(&$params) {
 	$new_os = $params['order_history'];
	$order_id = (int)$new_os->id_order;
    $order = new Order($order_id);
    // ...
    // Add a new Order state.
    $orderHistory = new OrderHistory();
    $orderHistory->id_order = $order_id;
    $orderHistory->changeIdOrderState(Configuration::get('PS_OS_SHIPPING'), (int)$order_id);
    $orderHistory->save();
}

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

Cookies ensure the smooth running of our services. Using these, you accept the use of cookies. Learn More