Magento – How to Stop Decreasing Stock Quantity When Order is Placed

inventoryordersproductstock

I need to stop decreasing the stock quantity when an order is placed and reduce the stock only on successful payment because there are lot abandoned transactions on my site. I found an article to do this link, which says how to credit back the quantity to the product on redirect action and the decrease it on successful response action. Is there any other way to do this?

Also I am running a cron to cancel the abandoned orders. When the orders are cancelled the quantities get added back to product stock.

My problem is if I follow the above link to decrease stock only on successful payment, how do I skip the product stock being updated when an abandoned order is cancelled?

Best Answer

This is how I soved my problem
Reff: http://www.magentocommerce.com/wiki/groups/132/protx_form_-_subtracting_stock_on_successful_payment

I have 2 payment menthods 1) CCavenue and 2) COD. I only wanted to stop the stock decrease to be done only on the CCavenue orders, so I used this.

The stock is credited back to the system when the customer is redirected to the payment gateway using this code.

if(!isset($_SESSION['updated']) || $_SESSION['updated'] != $session->getLastRealOrderId()) {

            $items = $order->getAllItems(); // Get all items from the order
            if ($items) {
                foreach($items as $item) {
                    if ($item->getParentItem()) { 
                        continue;
                    }
                        $quantity = $item->getQtyOrdered(); // get Qty ordered
                        $product_sku = $item->getSku(); // get it's sku
                    $product = Mage::getModel('catalog/product')->loadByAttribute('sku',$product_sku);
                    if($product){               
                        $stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product); // Load the stock for this product
                        $stock->setQty($stock->getQty()+$quantity); // Set to new Qty           
                        $stock->save(); // Save
                    }
                }
            }
            $_SESSION['updated'] = $session->getLastRealOrderId();
            /* end stock addition */
        } 

I added this code in the redirectAction in the paymentController.php of the payment extension. And in the responseAction I added the below code which re-deducts the stock when the payment is successful.

$items = $order->getAllItems(); // Get all items from the order
if ($items) {
    foreach($items as $item) {

        if ($item->getParentItem()) { 
            continue;
        }
            $quantity = $item->getQtyOrdered(); // get Qty ordered
            $product_sku = $item->getSku(); 
        $product = Mage::getModel('catalog/product')->loadByAttribute('sku',$product_sku);
        if($product){

            $stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product); // Load the stock for this product
            $stock->setQty($stock->getQty()-$quantity); // Set to new Qty           
            $stock->save(); // Save
        }
    }
}

Most of my products are configurable products. When I tried to get the item details from the order items collection it was giving me two values one for configurable and the other for simple product. Since I wanted to reduce the stock for only simple product I used SKU in the above codes to load the simple product.

My other problem was the cron I was running to cancel the abandoned transaction orders credits the stock back to the system when the order is cancelled. To fix this I copied app/code/core/Mage/Sales/Model/Order/Item.php into
app/code/local/Mage/Sales/Model/Order/Item.php and modified the cancel function to this so that the stock won't get credited back the abandoned orders are cancelled.

if ($this->getStatusId() !== self::STATUS_CANCELED) {
    $order_status = $this->getOrder()->getStatus();
    if($order_status != 'abandoned_payment'){
        Mage::dispatchEvent('sales_order_item_cancel', array('item'=>$this));
    }
    $this->setQtyCanceled($this->getQtyToCancel());
    $this->setTaxCanceled(
        $this->getTaxCanceled() +
        $this->getBaseTaxAmount() * $this->getQtyCanceled() / $this->getQtyOrdered()
    );
    $this->setHiddenTaxCanceled(
        $this->getHiddenTaxCanceled() +
        $this->getHiddenTaxAmount() * $this->getQtyCanceled() / $this->getQtyOrdered()
    );
}

abandoned_payment is my order status for the abandoned orders.

Related Topic