1

I am using sales_order_save_after event to change order status. It's working fine for all order status except STATE_COMPLETE. when i set the order status STATE_COMPLETE to make order Complete but it changed to Closed instead of being Complete. Other order States is working fine. The issue only happening when i try to use STATE_COMPLETE.

public function execute(\Magento\Framework\Event\Observer $observer)
{
    $order = $observer->getEvent()->getOrder();
       if($order->getState() != 'complete') {
            $order->setState(\Magento\Sales\Model\Order::STATE_COMPLETE)->setStatus(\Magento\Sales\Model\Order::STATE_COMPLETE);
            $order->save();
       }
}

This is what i'm doing

Can anyone help me out to make order status to "Complete" via observer ?

  • Please post your code. – Khoa TruongDinh Jul 26 at 6:15
  • @KhoaTruongDinh updated my post. – Nayem Jul 26 at 6:24
1

Please take note that invoking the the save method of the order would trigger a state check which might explain why you are experiencing the issue.

Magento 2 has a separate class for checking the order state.

In the Magento\Sales\Model\ResourceModel\Order class you will find the save method invoking state check

public function save(\Magento\Framework\Model\AbstractModel $object)
    {
        /** @var \Magento\Sales\Model\Order $object */
        $this->stateHandler->check($object);
        return parent::save($object);
    }

The stateHandler is an instance of Magento\Sales\Model\ResourceModel\Order\Handler\State

I would recommend that you have a look that the method "check" to trace the logic flow.

You could either override the method check or create a plugin aroundCheck to change the state logic flow

1

Ok, so the problem was when i set STATE_COMPLETE Magento make the order closed. But if i set STATE_PROCESSING or STATE_PENDING with status Complete then order status show complete but when i view the order details there it show processing/pending. So i tried to figure out when magento make order status complete and it is when a invoice is generated.

So i use checkout_submit_all_after event and create an invoice through my observer. When i create invoice through my observer magento make the order completed because the invoice is generated.

Here's the observer code -

class CheckoutSubmitAllAfter implements ObserverInterface{

protected $_invoiceService;
protected $_transactionFactory;

public function __construct(
  \Magento\Sales\Model\Service\InvoiceService $invoiceService,
  \Magento\Framework\DB\TransactionFactory $transactionFactory
) {
   $this->_invoiceService = $invoiceService;
   $this->_transactionFactory = $transactionFactory;
}

public function execute(\Magento\Framework\Event\Observer $observer)
{
    $order = $observer->getEvent()->getOrder();

    try {
        if(!$order->canInvoice()) {
            return null;
        }
        if(!$order->getState() == 'new') {
            return null;
        }

        $invoice = $this->_invoiceService->prepareInvoice($order);
        $invoice->setRequestedCaptureCase(\Magento\Sales\Model\Order\Invoice::CAPTURE_ONLINE);
        $invoice->register();

        $transaction = $this->_transactionFactory->create()
          ->addObject($invoice)
          ->addObject($invoice->getOrder());

        $transaction->save();

    } catch (\Exception $e) {
        $order->addStatusHistoryComment('Exception message: '.$e->getMessage(), false);
        $order->save();
        return null;
    }
}}
0

Please try following code:

use \Magento\Sales\Model\Order;

public function execute(\Magento\Framework\Event\Observer $observer)
{
    $order = $observer->getEvent()->getOrder();

    if($order->getState() != Order::STATE_COMPLETE) {

        $orderState = Order::STATE_COMPLETE;

        // set order status to COMPLETE
        $order->setState($orderState)->setStatus(Order::STATE_COMPLETE);

        // Save order
        $order->save();
    }
}

Hope it Works!

  • Not working order status showing closed – Nayem Jul 26 at 8:13
  • @RaselUddin can you change order status to complete by manually for any single order and check what status it displays. – KKR Jul 26 at 9:53
  • If i manually change it show complete – Nayem Jul 26 at 9:58
  • @RaselUddin can you please check order status in backend Stores->Settings->Order Status. – KKR Jul 26 at 10:02
  • yes everything is fine there. Please see i answered my ques how i solved it. – Nayem Jul 26 at 10:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.