Jump to content

Changing order status in hookActionOrderStatusUpdate


Esnyper

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
Link to comment
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
Link to comment
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?).

Link to comment
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)
Link to comment
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"

Link to comment
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)
Link to comment
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

Link to comment
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?

Link to comment
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();
			}
		
		}	
Link to comment
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

Link to comment
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?

Link to comment
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

Link to comment
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.

Link to comment
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
Link to comment
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)
Link to comment
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)
Link to comment
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?

Link to comment
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.

Link to comment
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();
}

 

  • Thanks 1
Link to comment
Share on other sites

  • 2 years later...

Hi!

I am in a situation where I am creating a module that can be called by an external service and which would change the status of an order based on the ps_orders.id_order passed.

So I do not need to rewrite or override tha existing functionality, but I am failing to figure out how I can trigger the default Prestashop functionality to change an order to Payment Accepted status just as doing so in the BO would do.

Where do I need to look to call these function(s)?

(Running 1.7.5. upgraded to 1.7.8.7)

 

 

Edited by GoPure Kratom (see edit history)
Link to comment
Share on other sites

11 hours ago, 4you.software said:

Hi.

If you want an answer, it's a good idea to start a new topic. No one will want to scroll through several years old and long thread for old versions of Prestashop. It is a good idea to always indicate which versions of Prestashop the help should be for.

Could be, sometimes I just feel a post in a related topic gets relevant answer better than completely new topic.

Link to comment
Share on other sites

3 hours ago, GoPure Kratom said:

Could be, sometimes I just feel a post in a related topic gets relevant answer better than completely new topic.

Well, if you think so, good luck waiting for an answer.
The theme was created for Prestashop PS 1.6.0.9 in 2014.
He opened more such topics and with the same question.
I would also like to help you, but not in such a long and old thread. When I'm on mobile, I have to scroll through a long list of responses.

Don't you wonder why no one has answered you here yet?
Did you answer what I asked of you?
And so the thread continues to grow and nothing.

Link to comment
Share on other sites

Hi @4you.software!
 

I added the Presta version to my orig, post.

I also assumed what I'm asking and need is quite core stuff in Prestashop and is not theme related or changed heavily in different versions.

I've luckily gotten quite far from this, and making headway. Although still stuck with something (feel free to have a look).

Below is a solution offered to me and what I'm trying:

In the above thread, my code uses id_product to get the product object.
However, I managed to find out how to get an order instance with order reference (which I ultimately need) as well:

$orders = Order::getByReference($order_reference);
$order_obj;

if(sizeof($orders) == 1) { 
    $order_obj = $orders[0];
} else {
    // Terminate
}

 

Link to comment
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
×
×
  • Create New...