Magento 2.4 – Fix sales_order_item_cancel Event Not Triggered

event-observermagento2magento2.4

I'm currently working on a module that involves the programmatic cancellation of orders. To cancel orders, I am using $this->orderManagement->cancel($orderId); in my code. This appears to be working correctly as the order status and state change to 'canceled' and the products within the order also seem to be getting canceled appropriately.

However, I have noticed a discrepancy when it comes to the triggering of the sales_order_item_cancel event. When I manually cancel an order by clicking on the 'cancel' button in the order view, this event is invoked, which is what I expect.

The problem arises when an order is canceled programmatically using my module, as this event does not seem to get triggered. This is causing issues since this event is required by other modules to carry out their operations when an order is canceled.

Looking into the source code, I can see that the $this->orderManagement->cancel($orderId); call should trigger the cancel method in \Magento\Sales\Model\Order\Item, which includes the dispatch of the sales_order_item_cancel event $this->_eventManager->dispatch('sales_order_item_cancel', ['item' => $this]);.

This leaves me puzzled as to why this event isn't triggered the same way when orders are canceled programmatically as compared to when they are manually canceled from the admin panel. All the more confusing is that the rest of the cancellation process seems to work as expected, including the restocking of items.

Has anyone else encountered this issue or have any insight on why this might be happening? Any help would be greatly appreciated!

Here is my controller:

<?php
namespace Makey\OrderCancel\Controller\Index;

use Magento\Framework\App\Action\Context;
use Magento\Framework\App\CsrfAwareActionInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\App\Request\InvalidRequestException;
use Magento\Checkout\Model\Session;
use Magento\Sales\Api\OrderManagementInterface;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Framework\Event\ManagerInterface;
use \Psr\Log\LoggerInterface;

class Cancel extends \Magento\Framework\App\Action\Action implements CsrfAwareActionInterface
{

    /**
     * @var Session
     */
    protected $checkoutSession;

    /**
     * @var OrderManagementInterface
     */
    protected $orderManagement;

    protected $orderRepository;
    /**
     * @var logger
     */
    private  $logger;

    /**
     * @var CollectionFactory
     */
    protected $orderCollectionFactory;

    protected $eventManager;

    /**
     * @param Context $context
     * @param OrderManagementInterface $orderManagement
     * @param OrderSender $orderSender
     */
    private $state;

    public function __construct(
        Context $context,
        Session $checkoutSession,
        OrderManagementInterface $orderManagement,
        LoggerInterface $logger,
        OrderRepositoryInterface $orderRepository,
        ManagerInterface $eventManager,
        \Magento\Framework\App\State $state
    ){
        $this->checkoutSession = $checkoutSession;
        $this->orderManagement = $orderManagement;
        $this->orderRepository = $orderRepository;
        $this->logger = $logger;
        $this->eventManager = $eventManager;
        $this->state = $state;
        parent::__construct($context);
    }
    public function execute()
    {
        try {
            $postValue = $this->getRequest()->getPostValue();
            $orderId = $postValue['OrderId'];

            if ($orderId) {
                $order = $this->orderRepository->get($orderId);

                if (!empty($order)) {
//                    $this->orderManagement->cancel($orderId);

                    $this->state->emulateAreaCode(
                        'adminhtml',
                        [$this->orderManagement, 'cancel'],
                        [$orderId]
                    );

                    echo 'OK!';
                } else {
                    $this->logger->info('Order ' . $orderId . ' was not found');
                }
            }

        } catch (\Exception $e) {
            echo 'NOT OK! \n';
            $this->logger->critical($e->getMessage());
            echo $e->getMessage();
        }
    }

    public function createCsrfValidationException(RequestInterface $request): ? InvalidRequestException
    {
        return null;
    }
    public function validateForCsrf(RequestInterface $request): ? bool
    {
        return true;
    }
}

Thank you.

Best Answer

I have created an Observer for this event sales_order_item_cancel and also create a controller to cancel the product but it is working

So, I think of two possible reasons that

  1. Creating issue with area or scope you have set
  2. Issue with observer code throwing error - sometime error get supress that cause in observer

Thanks

Related Topic