2

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?

  • james.i can give you solution ...but important.this stock of deducated when you have goes to success page.Cofirm ths – Amit Bera Oct 7 '14 at 7:07
  • @AmitBera Is there a way to skip the stock being added back when an order is cancelled? – James Oct 7 '14 at 7:23
  • by default magento is do this,if order is cancel – Amit Bera Oct 7 '14 at 7:25
  • Is there a way to overwrite this? Because if we deduct the stock at success page as per your method and the cron cancels any abandoned orders the quantity will be added back to the product stock which will spoil the product inventory. As I mentioned in my question there will be lot of abandoned transactions in my site. If I use your method with the problem of order cancellation be solved? – James Oct 7 '14 at 7:29
  • i guess that your order place time from return from online payment is less than cron time then it works perfectly for you – Amit Bera Oct 7 '14 at 7:40
3

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.

  • 1
    Could you refactor into a module? Putting this code into the controller files is not good practices. – Joseph at SwiftOtter Dec 17 '14 at 1:07
  • @SwiftOtterStudios the controller I used is the one in my custom payment module. – James Dec 17 '14 at 6:09
  • Ok. I was curious, so thank you for clarifying. – Joseph at SwiftOtter Dec 17 '14 at 18:04
0

Magento

Create an module which prevent to stock deducate when order place using event checkout_submit_all_after and function

Mage_Cataloginventory_Model_Observer

Step1: Create file config.xml at app/code/local/Amit/Preventstock/etc/ and code

<?xml version="1.0" ?>
<config>
    <modules>
        <Amit_Preventstock>
            <version>1.0.0</version>
        </Amit_Preventstock>    
    </modules>
    <global>

        <models>
            <preventstock>
                <class>Amit_Preventstock_Model</class>
            </preventstock>
        </models>   
    </global>

    <frontend>

                <!-- event to prevent to stock deducate when order place -->
        <events>
                <checkout_submit_all_after>
                    <observers>
                        <prevent_stock_minus_on_order_place>
                            <class>cataloginventory/observer</class>
                            <method>revertQuoteInventory</method>
                        </prevent_stock_minus_on_order_place>
                    </observers>
                </checkout_submit_all_after>
        </events>   
    <events>
            <checkout_onepage_controller_success_action>
                <observers>
                    <stock_deducated_on_success_page>
                        <class>preventstock/observer</class>
                        <method>triggermyevent</method>
                    </stock_deducated_on_success_page>  
                </observers>                
            </checkout_onepage_controller_success_action>
            <final_qty_reduce_on_checkout_sucess>
                <observers>
                    <at_last_qty_reduce_event>
                       <class>cataloginventory/observer</class>
                        <method>checkoutAllSubmitAfter</method>     
                    </at_last_qty_reduce_event> 
                </observers>
            </final_qty_reduce_on_checkout_sucess>      
        </events>   
    </frontend> 
</config>

Step2: Observer.php code at

app/code/local/Amit/Preventstock/Model

and code is

<?php
class Amit_Preventstock_Model_Observer{
    public function triggermyevent(Varien_Event_Observer $observer){
        $order_ids=$observer->getEvent()->getOrderIds();
        if(!is_array($order_ids)):
            return;
        endif;
        foreach ($order_ids as $eachOrderId) {

            $Order=Mage::getModel('sales/order')->load($eachOrderId);
            $Quote=Mage::getModel('sales/quote')->load($Order->getQuoteId());

             Mage::dispatchEvent('final_qty_reduce_on_checkout_sucess',
                array('order'=>$Order, 'quote'=>$Quote));

        }


    }

}

you need create Amit_Preventstock.xml at app/etc/modules and my

Code only work on fronted not backend

If you have any issue let me know at any time

  • Thanks. But where are revertQuoteInventory and checkoutAllSubmitAfter methods used? – James Oct 7 '14 at 8:46
  • @AmithBera I think you missed out some code while pasting it here – James Oct 8 '14 at 5:38
  • Does in this case the customer have to visit success page? Or does a payment confirmation via Api that sets order to status new also trigger it? – snh_nl Oct 30 '15 at 18:00
  • it decrease qty whenever customer is come to success page – Amit Bera Oct 30 '15 at 18:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.