How to undo cancel of an order which was canceled by mistake?
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('*/*/');
}
Hi this doesn´t seem to work with configurable products...
04/06/10 03:08:51|DS
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.
04/06/10 03:12:26|Damodar Bashyal
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.
09/07/10 06:27:35|Alan