Как предотвратить отмену заказа с помощью наблюдателя событий?

Я использую следующий код, чтобы предотвратить отмену заказа из панели администратора Magento.

<?xml version="1.0"?>
<config>
    <modules>
        <Muk_OrderCancel>
            <version>1.0.0</version>
        </Muk_OrderCancel>
    </modules>
    <global>
        <models>
            <ordercancel>
                <class>Muk_OrderCancel_Model</class>
            </ordercancel>
        </models>
        <events>
             <sales_order_save_before>
                <observers>
                     <ordercancel>
                        <type>singleton</type>
                        <class>Muk_OrderCancel_Model_Observer</class>
                        <method>canCancelOrder</method>
                     </ordercancel>
                </observers>
            </sales_order_save_before>
        </events>
        <helpers>
            <ordercancel>
                <class>Muk_OrderCancel_Model_Helper</class>
            </ordercancel>
        </helpers>
    </global>
</config>

В наблюдателе я использую следующий код:

<?php
class Muk_OrderCancel_Model_Observer
{
    public function canCancelOrder( Varien_Event_Observer $observer )
    {        
        $incrementId = $observer->getEvent()->getOrder()->getData('increment_id');

        $order = Mage::getModel('sales/order')->loadByIncrementId($incrementId);

        $adminUserSession = Mage::getSingleton('admin/session');

        $adminUserId = $adminUserSession->getUser()->getUserId();

        $adminUserName = $adminUserSession->getUser()->getUsername();

        $adminRoleName = Mage::getModel('admin/user')->load($adminUserId)
                ->getRole()->getData('role_name');        

        if($adminRoleName) { //some condition            
            $order->setActionFlag(Mage_Sales_Model_Order::ACTION_FLAG_CANCEL, false);            
        }       
    }
}

Но даже после включения этого модуля заказ отменяется.

Как предотвратить отмену заказа?


person Mukesh    schedule 25.09.2015    source источник
comment
Вы очистили кеш?   -  person Marko Novakovic    schedule 25.09.2015
comment
@MarkoNovakovic Я очистил кеши, и управление переходит к методу в наблюдателе, но заказ все равно отменен.   -  person Mukesh    schedule 26.09.2015


Ответы (1)


В «Mage_Adminhtml_Sales_OrderController» «cancelAction» идет:

$order->cancel()
       ->save();

что означает, что заказ сначала отменяется, а затем ваш наблюдатель срабатывает. Хотя я нашел это событие:

Mage::dispatchEvent('sales_order_payment_cancel', array('payment' => $this));

в "Mage_Sales_Model_Order_Payment", который срабатывает до: "Mage_Sales_Model_Order": метод "registerCancellation".

В вашем методе наблюдателя, который срабатывает при этом событии, вы можете сделать это:

if ($adminRoleName) {
$payment = $observer-&gt;getEvent()-&gt;getPayment();
$order = $payment-&gt;getOrder();
$order-&gt;setActionFlag(Mage_Sales_Model_Order::ACTION_FLAG_CANCEL, false);
//Get the existing non cancelled orders if they exist, if not create the array and add it to the admin session.
$orderIds = Mage::getSingleton('adminhtml/session')-&gt;getNonCancelledOrders();
if (!$orderIds) {
    $orderIds = array($order-&gt;getId());
} else {
    $orderIds[] = $order-&gt;getId();
}
Mage::getSingleton('adminhtml/session')-&gt;setNonCancelledOrders($orderIds);
}

Затем добавьте еще одного наблюдателя в файл etc/config.xml для следующего события: «controller_action_predispatch»:

<controller_action_predispatch>
    <observers>
         <check_session_message>
            <type>singleton</type>
            <class>Muk_OrderCancel_Model_Observer</class>
            <method>checkSessionMessage</method>
         </check_session_message>
    </observers>
</controller_action_predispatch>

Затем в вашем методе наблюдателя:

public function checkSessionMessage($observer)
{
    //Check if we have admin order view or grid action
    $request = Mage::app()->getRequest();
    $module = $request->getModuleName();
    $controller = $request->getControllerName();
    $action = $request->getActionName();
    if ($module == 'admin' && $controller == 'sales_order') {
        if ($action == 'view' || $action == 'index') {
            //Check if we have orderIds
            $orderIds = Mage::getSingleton('adminhtml/session')->getNonCancelledOrders();
            if ($orderIds && count($orderIds) > 0) {
                //Unset them from the session
                Mage::getSingleton('adminhtml/session')->unsNonCancelledOrders();
                //Clear success message
                Mage::getSingleton('adminhtml/session')->getMessages(true);
                //Add error message
                Mage::getSingleton('adminhtml/session')->addError('You are not allowed to cancel the order(s)');
            }
        }
    }
}
person zokibtmkd    schedule 27.09.2015
comment
Но если я попытаюсь отменить заказ со страницы сетки заказов, он покажет страницу исключения. Как я могу предотвратить это? - person Mukesh; 27.09.2015
comment
Извините, это из-за Mage::throwException в конце, я добавил его, чтобы предотвратить сообщение пользователю об успешном завершении заказа вместо отображения предупреждения. Вы можете удалить эту строку из кода, но вам придется найти способ показать правильное предупреждение или сообщение об успехе. Я отредактирую свой ответ. - person zokibtmkd; 27.09.2015
comment
Я постараюсь, если вы найдете какое-либо решение для этого, пожалуйста, обновите ответ. - person Mukesh; 27.09.2015