0

I have created a plugin which intercept the cancel function from the interface Magento\Sales\Api\OrderManagementInterface, the plugin intercept before the cancel function is called.

My problem is that when my module is activated, I can't cancel any orders, neither from the page admin/sales/order/view/order_id/10 or from the list of orders.

For example, when i click the cancel button, the text "You canceled the order." is displayed but in fact the order isn't canceled and has still the status "pending".

I have a custom table which reference the sales_order table, but the attribute referencing the table has the action on delete cascade

->addColumn(
                    'sales_order_id',
                    Table::TYPE_INTEGER,
                    10,
                    ['nullable' => false,
                    'unsigned' => true],
                    'Reference to entity_id of table sales_order'
                )
->addForeignKey(
                    $installer->getFkName('my_custom_table', 'sales_order_id', 'sales_order', 'entity_id'),
                    'sales_order_id',
                    $installer->getTable('sales_order'), /* main table name */
                    'entity_id',
                    \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE
                )

But even with the action on delete cascade, before canceling an order, I'm deleting the record which is referencing to the order being cancelled.

After cancelling an order, the order is not deleted from the database and has the status cancelled, so I'm getting confused on how can my module make the cancel function bug.

The purpose of my function beforeCancel is only to remove the record with an particular id from the table referencing the sales_order table and add it into an other table having no reference.

0

I am a little bit confused about your requirement.

So far my understanding, you want to remove a record from your table which related with your cancelled Order. If this requirement then you're doing wrong bcoz of Foreign Key means when an order delete from sales_order table then a record from custom_table will be removed.

In Magento, an order is cancelled NOT means Delete the order from sales_order. It is status changed to Cancel.

So, you want to remove the record from the database table my_custom_table when order cancels then you have do below steps:

  • Remove Foreign Key related to my_custom_table's table sales_order_id column.

  • Create an after Plugin on Magento\Sales\Api\OrderManagementInterface::cancel and delete record..

Here the Plugin Class

<?php


namespace StackExchange\MagentoTest\Plugin\Magento\Sales;


class OrderManagement
{
    /**
     * @var \Magento\Sales\Model\ResourceModel\Order
     */
    private $orderResource;

    public function __construct(
     \Magento\Sales\Model\ResourceModel\Order $orderResource
    ){
        $this->orderResource = $orderResource;
    }

    public function cancel(
        \Magento\Sales\Api\OrderManagementInterface $subject,
        $result,
        $id) {

        $where = [
            ' sales_order_id = ? ' => $id
        ];
        try {
            $this->orderResource->getConnection()->delete(
                $this->orderResource->getTable('my_custom_table'),
                $where
            );
        } catch (\Exception $e) {
            throw $e;
        }
    }
}

| improve this answer | |
  • Thanks for your answer, I already tried to do afterCancel, but the problem was that the $id received in the parameters of the afterCancel was always equals to 1. What is the problem with the foreign key here? I don't get it since the record is not being deleted but the only the status is changed? – ChristopheS Mar 30 at 8:51
0

I found out what was wrong, nothing about the foreign key.

In order to create the plugins I first went to the interface defining the cancel order function which was declared as

     /**
     * Cancels a specified order.
     *
     * @param int $id The order ID.
     * @return bool
     */
    public function cancel($id);

So I did declare the plugin in my module/etc/di.xml

<type name="Magento\Sales\Api\OrderManagementInterface">
        <plugin name="before_cancel_order_operation"
                type="Vendor\Module\Plugin\OrderManagement"/>
</type>

Then in my Module/Plugin/OrderManagement.php file I added the function

public function beforeCancel(
        OrderManagementInterface $subject,
        int $id
    ) {
       /* Logic code */
      return true;
      }

So my thinking was since the cancel function in the OrderManagementInterface.php return a boolean (the doc is specifying that the function return a boolean), it should return true if my logic code doesn't encounter a problem.

I was wrong, returning false will lead me to an error which tells me something like 'you need to provide an id to cancel an order' returning true will lead me to an error which tells me that I can't cancel order.

I just had to remove the return...

| improve this answer | |

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.