2

I'm on Magento 1.7.0.2. I'm using "Cash On Delivery" as my payment method.I'll tell you exactly the steps That i follow on any order. When an order is placed(Qty decreased 1 item), I create a shipment for it and if customer paid the order grand total price. I create an invoice for that order.

My problem, If an order is placed(Qty decreased 1 item), I create a shipment for this order. If the customer refused to pay, I open this order and "Cancel" it and on this case the "Qty" doesn't increase so How can I make it increase?

gonzo
  • 145
  • 3
  • 12

2 Answers2

2

If order status is Processing

Create a custom module with observer for 'order_cancel_before' (see example @ Change Magento default status for duplicated products change <catalog_model_product_duplicate> to <order_cancel_before>

since <order_cancel_before> is not defined in app/code/core/Mage/Sales/Model/Order.php

You could override/rewrite order model class see e.g http://phprelated.myworks.ro/how-to-override-rewrite-model-class-in-magento/

In your local module do

public function cancel()
{
    if ($this->canCancel()) {
        Mage::dispatchEvent('order_cancel_before', array('order' => $this));
        $this->getPayment()->cancel();
        $this->registerCancellation();

        Mage::dispatchEvent('order_cancel_after', array('order' => $this));
    }

    return $this;
}

Or you could create a new method increaseProductQty() in your model and copy the code below into it (this way you would not need an observer). Then replace the line Mage::dispatchEvent('order_cancel_before'... with $this->increaseProductQty()

In your observer method (pseudo code)

$curr_date = date('Y-m-d H:i:s');
$order = $observer->getEvent()->getOrder();

foreach ($order->getItemsCollection() as $item) 
{ 
    $productId  = $item->getProductId();
    $qty = $item->getQty();

    // you need to check order status to make sure it processing
    //$order->getStatus() (assuming you are canceling entire order)
    //$order->getPayment();

    $product = Mage::getModel('catalog/product')->load($product_id);
    $stock_obj = Mage::getModel('cataloginventory/stock_item')->load($product_id);
    $stockData = $stock_obj->getData();
    $product_qty_before = (int)$stock_obj->getQty();
    $product_qty_after = (int)($product_qty_before + $qty); 
    $stockData['qty'] = $product_qty_after;

    $productInfoData = $product->getData();
    $productInfoData['updated_at'] = $curr_date;
    $product->setData($productInfoData);
    $product->setStockData($stockData);
    $product->save();
}

If you have issue with updating stock see Set default product values when adding new product in Magento 1.7

Reference http://pragneshkaria.com/programatically-change-products-quantity-after-order-cancelled-magento/

If order status is Pending

Take a look at System > Configuration > Inventory

Set Items’ Status to be In Stock When Order is Cancelled — Controls whether products in pending orders automatically return to the stock if orders are cancelled. Scope: STORE VIEW.

Read more @

How to Manage Magento Store Inventory?

ADMIN: System → Configuration → Inventory Tab

Community
  • 1
  • 1
MagePal Extensions
  • 17,646
  • 2
  • 47
  • 62
  • your solution works well when the order on Pending status but my problem is canceling an order on Processing status (as I shipped it) – gonzo Nov 11 '12 at 11:11
  • Thank you very very much and I'll try your code but I want the above code to work only with "Cash On Delivery" payment method. – gonzo Nov 11 '12 at 12:21
  • Check the payment method type http://stackoverflow.com/questions/4669099/how-to-get-payment-information-on-magento – MagePal Extensions Nov 11 '12 at 12:24
  • Really I appreciate your effort with me. I have another question Please How can I check order status to make sure it processing – gonzo Nov 11 '12 at 12:30
  • On the config.xml what is the method name?? – gonzo Nov 11 '12 at 13:08
  • $order->getStatus() (assuming that you are canceling the entire order which i think your doing) – MagePal Extensions Nov 11 '12 at 13:40
  • xml duplicateProduct ... observer public function productDuplicate(Varien_Event_Observer $observer) – MagePal Extensions Nov 11 '12 at 13:46
  • as the event order_cancel_after so the $order->getStatus() will get the new status which will be "canceled" not "processing". Please advise – gonzo Nov 11 '12 at 14:09
  • Take a look at all the observer http://www.nicksays.co.uk/magento_events_cheat_sheet/... it doesnt seem like there is a before cancel, so take a look at app/code/core/Mage/Sales/Model/Order.php you may need to extend cancel() ... take a look @ http://phprelated.myworks.ro/how-to-override-rewrite-model-class-in-magento/ and put this Mage::dispatchEvent('order_cancel_before', array('order' => $this)); after the if statement OR you could just put the above code in this section without creating a observer – MagePal Extensions Nov 11 '12 at 14:18
  • After Adding the observer code and canceling the order, the Qty became zero. Please advise – gonzo Nov 11 '12 at 14:27
  • Take a look at my update code... 'order_cancel_before' should contain the order info before it's status or qty change – MagePal Extensions Nov 11 '12 at 14:32
  • I'll create a new method increaseProductQty() so what is the code I'll replaced for `$order = $observer->getEvent()->getOrder();` – gonzo Nov 11 '12 at 15:08
  • Try $this->getAllItems(), $this->getId() take a look at canCancel() in app/code/core/Mage/Sales/Model/Order.php – MagePal Extensions Nov 11 '12 at 15:19
  • Great, but how can we allow cancel function to execute? – gonzo Nov 11 '12 at 15:33
  • If you override/rewrite the order model class as shown in the link then it will execute instead of app/code/core/Mage/Sales/Model/Order.php – MagePal Extensions Nov 11 '12 at 15:44
  • It didn't work with me here is my code //config.xml http://pastebin.com/98wisM20 //NileCreations_ExtendOrderCancel.xml http://pastebin.com/1fMuQiCG //Order.php http://pastebin.com/KEZWDp2f – gonzo Nov 11 '12 at 15:52
  • Your config is not complete... replace this example http://stackoverflow.com/questions/12677971/change-magento-default-status-for-duplicated-products with your and update the section – MagePal Extensions Nov 11 '12 at 16:00
  • Did you add your custom module xml file to app/etc/modules/NileCreations_ExtendOrderCancel.xml? As in example http://stackoverflow.com/questions/12677971/change-magento-default-status-for-duplicated-products – MagePal Extensions Nov 11 '12 at 16:16
  • Yes, I added it on that path. here are all the path pp/etc/modules/NileCreations_ExtendOrderCancel.xml /app/code/local/NileCreations/ExtendOrderCancel/Model/Order.php /app/code/local/NileCreations/ExtendOrderCancel/etc/config.xml – gonzo Nov 11 '12 at 16:26
  • You are missing the closing '' in config.xml ... http://pastebin.com/YLNTFKSr – MagePal Extensions Nov 11 '12 at 17:57
  • I'm so sorry for missing ``. I have test the new module using the method increaseProductQty() and the Qty became 0 which is wrong value so I'll the Observer method. – gonzo Nov 12 '12 at 09:39
  • I have tried the observer method and I got the same result Qty became 0. Please advise – gonzo Nov 12 '12 at 09:50
  • I think the problem on qty as I have mailed myself the $product_qty_before I got 0 and $qty I got nothing and $product_qty_after I got 0 – gonzo Nov 12 '12 at 09:58
  • I got it and I'll update your answer. Thanks for your support and your time. – gonzo Nov 12 '12 at 11:24
1

Thanks to R.S as he helped me more & more.

I followed all instructions on R.S's reply https://stackoverflow.com/a/13330543/1794834 and I've only changed the observer code. Here is the observer code that worked with me on Magento 1.7.0.2.

$curr_date = date('Y-m-d H:i:s');
$order = $observer->getEvent()->getOrder();

foreach ($order->getItemsCollection() as $item) 
{ 
    $productId  = $item->getProductId();
    $qty = (int)$item->getQtyOrdered();
    $product = Mage::getModel('catalog/product')->load($productId);
    $stock_obj = Mage::getModel('cataloginventory/stock_item')->loadByProduct($productId);
    $stockData = $stock_obj->getData();
    $product_qty_before = (int)$stock_obj->getQty();
    $product_qty_after = (int)($product_qty_before + $qty); 
    $stockData['qty'] = $product_qty_after;
    /*
     * it may be case that admin has enabled product add in stock, after product sold,
     * he set is_in_stock = 0 and if order cancelled then we need to update only qty not is_in_stock status.
     * make a note of it
     */
    if($product_qty_after != 0) {
        $stockData['is_in_stock'] = 1;
    }else{
        $stockData['is_in_stock'] = 0;
    }

    $productInfoData = $product->getData();
    $productInfoData['updated_at'] = $curr_date;
    $product->setData($productInfoData);
    $product->setStockData($stockData);
    $product->save();
}
Community
  • 1
  • 1
gonzo
  • 145
  • 3
  • 12