1

Here am trying to Cancel a order from a controller using order ID. but order is cancelling only if security key adding to URL disabled from admin configuration. How to cancel order without disabling secure URL Key.

here is my code controller

protected $orderManagement;
public function __construct( \Magento\Sales\Api\OrderManagementInterface $orderManagement)
{
 $this->orderManagement = $orderManagement;
}
 public function execute()
 {
   $orderId = 10;  
   if($this->orderManagement->cancel((int)$orderId)){
        $this->messageManager->addSuccess(__("Order Cancellation Success"));
        return $resultRedirect;
   }else{
        $this->messageManager->addError(__("Can't Cancel this Order"));
        return $resultRedirect;
   }
}

Where am doing wrong. Can I get help? Thank you in advance.

7
  • Can you give more context on your requirements? From where do you want to cancel orders? A cronjob? Commented Oct 17, 2020 at 8:33
  • thank you @Jonathan Ribas for responce, I have added a action column on sales-order grid to cancel order, by the action am calling a controller to cancel the order by passing order Id. path of controller is /Myvendor/Orders/Controller/Adminhtml/Post/Index.php Commented Oct 17, 2020 at 8:43
  • I see, why don't you use mass action button to cancel order from orders grid? It's a native feature. Commented Oct 17, 2020 at 8:46
  • that feature we have to add in action column that is the requirement. Commented Oct 17, 2020 at 8:56
  • I see but try to sell it the native way to your customer: less custom code = less maintenance! Commented Oct 17, 2020 at 10:07

1 Answer 1

1

I agree with the comments, extend and reuse the core code as much as possible.

You either are having issues with how you form the cancel link or it is something in the controller, the code below works fine.

app/code/StackExchange/CancelOrder/Controller/Adminhtml/Order/Cancel.php

namespace StackExchange\CancelOrder\Controller\Adminhtml\Order;

use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Sales\Controller\Adminhtml\Order\Cancel as CancelOrderController;

class Cancel extends CancelOrderController implements HttpGetActionInterface
{
    public function execute()
    {
        $resultRedirect = $this->resultRedirectFactory->create();

        $order = $this->_initOrder();
        if ($order) {
            try {
                $this->orderManagement->cancel($order->getEntityId());
                $this->messageManager->addSuccessMessage(__('You canceled the order.'));
            } catch (\Magento\Framework\Exception\LocalizedException $e) {
                $this->messageManager->addErrorMessage($e->getMessage());
            } catch (\Exception $e) {
                $this->messageManager->addErrorMessage(__('You have not canceled the item.'));
                $this->_objectManager->get(\Psr\Log\LoggerInterface::class)->critical($e);
            }
        }
        return $resultRedirect->setPath('sales/order/index');
    }
}

app/code/StackExchange/CancelOrder/view/adminhtml/ui_component/sales_order_grid.xml

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <columns name="sales_order_columns">
        <actionsColumn name="actions" class="StackExchange\CancelOrder\UI\Component\Listing\Column\Actions"/>
    </columns>
</listing>

app/code/StackExchange/CancelOrder/UI/Component/Listing/Column/Actions.php

namespace StackExchange\CancelOrder\UI\Component\Listing\Column;

use Magento\Sales\Ui\Component\Listing\Column\ViewAction;

class Actions extends ViewAction
{
    public function prepareDataSource(array $dataSource)
    {
        $dataSource =  parent::prepareDataSource($dataSource);

        if (isset($dataSource['data']['items'])) {
            foreach ($dataSource['data']['items'] as & $item) {
                if (isset($item['entity_id'])) {
                    $urlEntityParamName = $this->getData('config/urlEntityParamName') ?: 'entity_id';
                    $item[$this->getData('name')]['cancel'] =
                        [
                            'href' => $this->urlBuilder->getUrl(
                                'cancel/order/cancel',
                                [
                                    $urlEntityParamName => $item['entity_id']
                                ]
                            ),
                            'label' => __('Cancel')
                        ];
                }
            }
        }

        return $dataSource;
    }
}

app/code/StackExchange/CancelOrder/etc/adminhtml/routes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="admin">
        <route id="cancel" frontName="cancel">
            <module name="StackExchange_CancelOrder" before="Magento_Sales" />
        </route>
    </router>
</config>
1
  • Thank you @Kristoffer I already found solution, am marking this coz this is correct way I did. Commented Oct 19, 2020 at 8:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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