Question

I have an event Observer for sales_order_place_after

namespace Company\Ordertool\Observer;

use Magento\Framework\Event\ObserverInterface;

class OrderComplete implements ObserverInterface
{
    /**
     * @var ObjectManagerInterface
     */
    protected $_objectManager;

    /**
     * @param \Magento\Framework\ObjectManagerInterface $objectManager
     */
    public function __construct(
        \Magento\Framework\ObjectManagerInterface $objectManager,
        \Magento\Quote\Model\QuoteFactory $quoteFactory,
        \Magento\Sales\Model\Order $order
    ) {
        $this->_objectManager = $objectManager;
        $this->order = $order;
    }

    /**
     *
     * @param \Magento\Framework\Event\Observer $observer
     * @return void
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {



        $order = $observer->getEvent()->getOrder();
        $orderId = $order->getId();

        $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/debug.log');
        $logger = new \Zend\Log\Logger();
        $logger->addWriter($writer);
        $logger->info( $orderId );


    }
}

$order does appear to be the order ... but $orderId is empty. I feel like I'm missing something obvious here...

Was it helpful?

Solution

sales_order_place_after: This event is dispatched after the order payment is placed.

$order = $observer->getEvent()->getOrder();
$incrementId = $order->getIncrementId();

sales_order_save_after: This event is called every time the order is saved. For eg. Order status changed, invoiced, shipped & credit memo.

$order = $observer->getEvent()->getOrder();
$orderId = $order->getId();

OTHER TIPS

The event sales_order_place_after triggers after payment processed but before the order has been saved to database. Id will be available after order was successfully saved to database. So sales_order_place_after will not give you orderId though you will get order incremental id.

On the other hand, if you use sales_order_save_after, it will be triggered every time the order is saved.

If you like to get order id just after place an order using after plugin for Magento\Sales\Api\OrderManagementInterface::place will be the best option.

etc/di.xml

<?xml version="1.0" ?>
    <config>
        <type name="Magento\Sales\Api\OrderManagementInterface">
            <plugin name="MyOrderPlaceAfterPlugin" type="My\Module\Plugin\Order\PlaceAfterPlugin" sortOrder="99" />
        </type>
    </config>

My\Module\Plugin\Order\PlaceAfterPlugin.php

//namespace My\Module\Plugin\Order;

class  PlaceAfterPlugin {


    /**
     * @param \Magento\Sales\Api\OrderManagementInterface $orderManagementInterface
     * @param \Magento\Sales\Model\Order\Interceptor $order
     * @return $order
     */
    public function afterPlace(\Magento\Sales\Api\OrderManagementInterface $orderManagementInterface , $order)
    {
        $orderId = $order->getId();

        // do something with order object (Interceptor )

       return $order;
    }
}

Use this code to get Order Id in sales_order_place_after event

public function execute(\Magento\Framework\Event\Observer $observer)
{
    $orderIds = $observer->getEvent()->getOrderIds();
    $lastorderId = $orderIds[0]; // Here you can get OrderID
}

Try to remove the $order in the contruct function.

/**
 * @param \Magento\Framework\ObjectManagerInterface $objectManager
 */
public function __construct(
    \Magento\Framework\ObjectManagerInterface $objectManager,
    \Magento\Quote\Model\QuoteFactory $quoteFactory,
) {
    $this->_objectManager = $objectManager;
}

Seems like you have not defined the $order variable.

You must have to first create events.xml file in etc folder to your module.

Company/Ordertool/etc/events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="sales_order_place_after">
        <observer name="order_id_sales_after" instance="Company\Ordertool\Observer\OrderComplete" />
    </event>
</config>

By this observer you get the Increment Id instead Order Id as Order Id is only available after successfully order completion.

Comapny/Ordertool/Observer/OrderComplete

namespace Company\Ordertool\Observer;

use Magento\Framework\Event\ObserverInterface;

class OrderComplete implements ObserverInterface
{
/**
 * @var ObjectManagerInterface
 */
protected $_objectManager;

/**
 * @param \Magento\Framework\ObjectManagerInterface $objectManager
 */
public function __construct(
    \Magento\Framework\ObjectManagerInterface $objectManager,
    \Magento\Quote\Model\QuoteFactory $quoteFactory,
    \Magento\Sales\Model\Order $order
) {
    $this->_objectManager = $objectManager;
    $this->order = $order;
}

/**
 *
 * @param \Magento\Framework\Event\Observer $observer
 * @return void
 */
public function execute(\Magento\Framework\Event\Observer $observer)
{
    $order = $observer->getEvent()->getOrder();
    $orderId = $order->getIncrementId();

    $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/debug.log');
    $logger = new \Zend\Log\Logger();
    $logger->addWriter($writer);
    $logger->info( $orderId );
}
}

I've just faced the same situation. I wanted to automatically create an invoice after payment but I needed the orderId for it.

I didn't want to use the 'sales_order_payment_save_after' event because it was running recursively. I wanted to use the 'sales_order_place_after' event instead.

The solution was to call $order->save() in the execute command of the observer before I needed to use it:

public function execute(\Magento\Framework\Event\Observer $observer) {
  $order = $observer->getEvent()->getOrder();
  ...
  // check conditions and if you want to save the order
  $order->save();
  // add code where you need $order->getId() to work
  $orderId = $order->getId();
  ...

Use the sales_model_service_quote_submit_success event.

vendor/magento/module-quote/Model/QuoteManagement::submitQuote dispatches the sales_model_service_quote_submit_success after OrderService place() which saves the order and creates the ID.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top