How to undo cancel of an order which was canceled by mistake?

Posted by Damodar Bashyal on May 17, 2010

 

I mistakenly canceled one order and spent a day to go through magento & different forums and blogs and searching for a solution and this is how i fixed myself after few tries. I am still not sure how to extend the controller so i modified the core file and made a copy so i can paste back if overwritten when upgrade or i can copy when i find the solution how to extend or override a magento controllers.

Create a file @ app\code\local\Codefight\Adminhtml\Block\Sales\Order\Grid.php

<?php
/**
* Adminhtml sales orders grid
*
* @category   Mage
* @package    Mage_Adminhtml
* @author Damodar Bashyal     
*/
class Codefight_Adminhtml_Block_Sales_Order_Grid extends Mage_Adminhtml_Block_Sales_Order_Grid
{
public function __construct()
{
parent::__construct();
}
protected function _prepareMassaction()
{
$this->setMassactionIdField('entity_id');
$this->getMassactionBlock()->setFormFieldName('order_ids');

 

if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/cancel')) { $this->getMassactionBlock()->addItem('cancel_order', array( 'label'=> Mage::helper('sales')->__('Cancel'), 'url' => $this->getUrl('*/*/massCancel'), )); } if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/changestatus')) { $this->getMassactionBlock()->addItem('changestatus_order', array( 'label'=> Mage::helper('sales')->__('Undo Cancel'), 'url' => $this->getUrl('*/*/massChangestatus'), )); } if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/hold')) { $this->getMassactionBlock()->addItem('hold_order', array( 'label'=> Mage::helper('sales')->__('Hold'), 'url' => $this->getUrl('*/*/massHold'), )); } if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/unhold')) { $this->getMassactionBlock()->addItem('unhold_order', array( 'label'=> Mage::helper('sales')->__('Unhold'), 'url' => $this->getUrl('*/*/massUnhold'), )); } $this->getMassactionBlock()->addItem('pdfinvoices_order', array( 'label'=> Mage::helper('sales')->__('Print Invoices'), 'url' => $this->getUrl('*/*/pdfinvoices'), )); $this->getMassactionBlock()->addItem('pdfshipments_order', array( 'label'=> Mage::helper('sales')->__('Print Packingslips'), 'url' => $this->getUrl('*/*/pdfshipments'), )); $this->getMassactionBlock()->addItem('pdfcreditmemos_order', array( 'label'=> Mage::helper('sales')->__('Print Credit Memos'), 'url' => $this->getUrl('*/*/pdfcreditmemos'), )); $this->getMassactionBlock()->addItem('pdfdocs_order', array( 'label'=> Mage::helper('sales')->__('Print All'), 'url' => $this->getUrl('*/*/pdfdocs'), )); return $this; } }

Now Create another file: app\etc\modules\Codefight_Adminhtml.xml

<?xml version="1.0"?>
<config>
<modules>
<Codefight_Adminhtml>
<active>true</active>
<codePool>local</codePool>
</Codefight_Adminhtml>
</modules>
<global>
<blocks>
<adminhtml>
<rewrite>
<sales_order_grid>Codefight_Adminhtml_Block_Sales_Order_Grid</sales_order_grid>
</rewrite>
</adminhtml>
</blocks>
</global>
</config>

Now, add the new function on the controller: app/code/core/mage/adminhtml/controllers/sales/ordercontroller.php

public function massChangestatusAction()
{
$orderIds = $this->getRequest()->getPost('order_ids', array());
$countCancelOrder = 0;
$countNonCancelOrder = 0;
foreach ($orderIds as $orderId)
{
$w = Mage::getSingleton('core/resource')->getConnection('core_write');
$result = $w->query("select item_id, qty_canceled from `sales_flat_order_item` where `order_id`={$orderId}");
$_is_canceled = FALSE;
while ($row = $result->fetch(PDO::FETCH_ASSOC))
{
$_is_canceled = FALSE;
if($row['qty_canceled'] > 0) $_is_canceled = TRUE;
//If the order was canceled...
if($_is_canceled)
{
//Reset canceled qty to 0
$update = $w->query("UPDATE `sales_flat_order_item` SET qty_canceled=0 WHERE `item_id`={$row['item_id']}");
}
}
//If the order was canceled... when undoing cancel change back all original values.
if($_is_canceled)
{
$result = $w->query("select * from `sales_order` where `entity_id`={$orderId}");
while ($row = $result->fetch(PDO::FETCH_ASSOC))
{
//
$update = $w->query("
UPDATE `sales_order` 
SET 
shipping_invoiced = '" . $row['shipping_amount'] . "',
base_shipping_invoiced = '" . $row['base_shipping_amount'] . "',
tax_invoiced = '" . $row['tax_amount'] . "',
base_tax_invoiced = '" . $row['tax_amount'] . "',
base_subtotal_invoiced = '" . $row['base_subtotal'] . "',
subtotal_invoiced = '" . $row['subtotal'] . "',
total_paid = '" . $row['grand_total'] . "',
total_invoiced = '" . $row['grand_total'] . "',
base_total_paid = '" . $row['base_grand_total'] . "',
base_total_invoiced = '" . $row['base_grand_total'] . "',
status 	 = 'processing',
state = 'processing',
subtotal_canceled 	 = '0',
tax_canceled 	 = '0',
shipping_canceled 	 = '0',
base_subtotal_canceled 	 = '0',
base_shipping_canceled 	 = '0'
WHERE 
`entity_id`={$row['entity_id']}");
$countCancelOrder++;
}
} else {
$countNonCancelOrder++;
}
}
if ($countNonCancelOrder) {
if ($countCancelOrder) {
$this->_getSession()->addError($this->__('%s order(s) could not be updated', $countNonCancelOrder));
} else {
$this->_getSession()->addError($this->__('Order(s) can not be updated'));
}
}
if ($countCancelOrder) {
$this->_getSession()->addSuccess($this->__('%s order(s) successfully updated', $countCancelOrder));
}
$this->_redirect('*/*/');
}

DS posted on - Saturday 5th of June 2010 01:08:51 AM

Hi this doesn´t seem to work with configurable products...

Damodar Bashyal posted on - Saturday 5th of June 2010 01:12:26 AM

Hi DS
I tested with Simple products only as that was required for my client, i haven't tested with configurable so i am unable to say for sure.

Alan posted on - Saturday 10th of July 2010 04:27:35 PM

Thanks! Works perfectly.

As a side note line 17 on the first block of code has a 2 <p> tags which need to be deleted.

Nick posted on - Wednesday 8th of September 2010 03:13:54 PM

Just tried it myself, but get either cannot update order or unknown column status / state

louis vuitton posted on - Friday 24th of September 2010 01:25:48 AM

reorder an order and change order number on phpadmin its easier way

adfab posted on - Tuesday 16th of November 2010 04:41:56 PM

For configurable products, add "product_type= 'configurable'" in the two requests on the table"sales_flat_order_item"

$w->query("select item_id, qty_canceled from `sales_flat_order_item` where product_type= 'configurable' and `order_id`={$orderId}");

$w->query("UPDATE `sales_flat_order_item` SET qty_canceled=0 WHERE product_type= 'configurable' and `item_id`={$row['item_id']}");

Nick posted on - Saturday 11th of December 2010 03:24:29 PM

Just noticed. This only applies to sales_order table. Surely its should also do sales_order_items as well...

Gabriel Queiroz - Flow eCommerce posted on - Thursday 23rd of December 2010 02:55:47 AM

You would be better off not doing these changes straight to the table. For example, now with the sales_flat_order, the above code doesn't work. Also, setting the amounts invoiced equal to the amount ordered is not safe, IMHO.

Here is what i did:

public function massStatusChangeAction() {
$orderIds = $this->getRequest()->getPost('order_ids', array());
$status = $this->getRequest()->getPost('status', array());

foreach ($orderIds as $orderId) {
$order = Mage::getModel('sales/order')->load($orderId);

if ($order->getEntityId()) {

if ($order->getStatus() == 'canceled') {
foreach($order->getItemsCollection() as $item)
{
if ($item->getQtyCanceled() > 0)
$item->setQtyCanceled(0)->save();
}

$order
->setBaseDiscountCanceled(0)
->setBaseShippingCanceled(0)
->setBaseSubtotalCanceled(0)
->setBaseTaxCanceled(0)
->setBaseTotalCanceled(0)
->setDiscountCanceled(0)
->setShippingCanceled(0)
->setSubtotalCanceled(0)
->setTaxCanceled(0)
->setTotalCanceled(0);
}

$order
->setStatus($status)
->setState($status)
->save();
}
}

$path_to_local_xml = Mage::getBaseDir() . "/app/etc/local.xml";
$admin_path = $this->parseLocalXML($path_to_local_xml);
$this->_redirect($admin_path . '/sales_order/index/');
}

Cheers,
Gabriel
 
not published on website


QR Code: How to undo cancel of an order which was canceled by mistake?