3

How to send sms when an item quantity is out of stock in magento ? i have used :

<catalog_product_save_before>
    <observers>
        <Metro_Notify>
            <type>singleton</type>
            <class>notify/Productobserver</class>
            <method>productSaveBefore</method>
        </Metro_Notify>
    </observers>
</catalog_product_save_before>

in my observer

private function lowStockReportSendEmail($product,$toEmailAddress)
{
    $stockItem = $observer->getEvent();
    Mage::log($stockItem,null,'stockitem.null');

    if($stockItem->getQty() < $stockItem->getNotifyStockQty())
    {
       //stock is lower than the notify amount, send email
       $product = $observer->getProduct();  
       $productName =  $product->getName();
       $productId =  $product->getId();
       $supplierId = $product->getSeller_id();
       $supplierData = $this->_getSupplierData($supplierId);

       // $product = Mage::getModel('catalog/product')->load($stockItem->getProductId());

        $body = "{$productName} :: {$product->getSku()} just Ran out of stock:\n\n";
        $body .= "Current Qty: {$stockItem->getQty()}\n";
        $body .= "Low Stock Date: {$stockItem->getLowStockDate()}\n";

        $vars['PRODUCTID'] = $productData->getId();
        $vars['PRODUCTNAME'] = $productData->getName();
        $vars['SUPPLIERNAME'] = $supplierData->getFirstname();          
        $vars['SUPPLIERNO'] = $supplierData->getSupplier_no();
        $vars['QTY'] = $stockItem->getQty();
        $vars['PREVIOUSQTY'] = $stockItem->getQty() - $stockItem->getOrigData('qty');

        $categoryManagerTemplateId = 'categorymanager_template_lowstock_report';
        $adminTemplateId = 'admin_template_lowstock_report';
        $fromEmailId = $supplierData->getEmail();
        $sender = array('name' => $fromEmailId,'email' => $fromEmailId);    

        if(!empty($toEmailAddress))
        {
            $categoryManagerEmail = $toEmailAddress;                
            $adminEmail = $toEmailAddress;  
        }   
        else
        {
            $categoryManagerEmail = $supplierData->getSupplier_cat_manager_email();
            $adminEmail = $this->_getAdminEmailAddress();                           
            $this->log('categoryManagerEmail',$categoryManagerEmail);
            $this->log('adminEmail',$adminEmail);
        }

        /* $storeId = Mage::app()->getStore()->getId();
        $templateId = 'supplier_product_stock_update';
        $fromEmailId = $supplierData->getEmail();               
        $sender = array('name' => $fromEmailId,'email' => $fromEmailId);
        $toEmail = $supplierData->getSupplier_cat_manager_email();
        $name = $supplierData->getFirstname();
        $mailSubject = "Supplier Low Stock Notification"; */
        $name = $supplierData->getFirstname();

        $mailCategorySubject = "Out of Stock".$productName."(".$productId.")";
        $mailAdminSubject="Out of Stock".$supplierName;

        $this->_sendNotifyEmail($categoryManagerTemplateId, $sender, $categoryManagerEmail, $name, $mailCategorySubject,$vars, $storeId);
        $this->_sendNotifyEmail($adminTemplateId, $sender, $adminEmail, $name, $mailAdminSubject,$vars, $storeId);
        $this->log('LowStockReportEmail',$vars);
    }
}
5
  • Can you please share what you get in your log fiel when you Mage::log($stockItem,null,'stockitem.null'); please? Commented Apr 14, 2015 at 15:07
  • Hi, Its not entering into tat function itself, i have used the event <cataloginventory_stock_item_save_after>
    – Sushivam
    Commented Apr 14, 2015 at 15:08
  • sorry mate, didn't see your response and posted my answer already... So is the problem that the function is not called at all, or it is called ut not getting anything? can you edit and supply your function that calls lowStockReportSendEmail please? I believve it is productSaveBefore from your config.xml Commented Apr 14, 2015 at 15:11
  • wait, your using the cataloginventory_stock_item_save_after event?? your xml snipped says your hooking the catalog_product_save_before event? Commented Apr 14, 2015 at 15:13
  • namespace/module/Model/Notifier.php. In my namespace/module/Model/Productobserver.php , i am using the same function with $observer as parameter
    – Sushivam
    Commented Apr 14, 2015 at 15:19

2 Answers 2

2

catalog_product_save_before is only triggered when the product is saved from the backend, not when stock decreases after ordering. You need to observe sales_order_place_after as well (unfortunately you cannot use any event related to the stock item model, because Magento uses an optimized SQL query to decrease stock for all ordered items at once, bypassing the model).

An alternative (that's how I solved it), is to rewrite Mage_CatalogInventory_Model_Stock and add an additional event:

<?php
/**
 * Add events to observe stock qty change
 * 
 * @author Fabian Schmengler
 *
 */
class SGH_ShippingExpress_Model_CatalogInventory_Stock
    extends Mage_CatalogInventory_Model_Stock
{
    const EVENT_CORRECT_STOCK_ITEMS_QTY_BEFORE = 'cataloginventory_stock_item_correct_qty_before';
    const EVENT_CORRECT_STOCK_ITEMS_QTY_AFTER = 'cataloginventory_stock_item_correct_qty_after';

    /**
     * (non-PHPdoc)
     * @see Mage_CatalogInventory_Model_Stock::registerProductsSale()
     */
    public function registerProductsSale($items)
    {
        Mage::dispatchEvent(self::EVENT_CORRECT_STOCK_ITEMS_QTY_BEFORE, array(
            'stock'     => $this,
            'items_obj' => (object)array('items' => &$items),
            'operator'  => '+'
        ));
        $result = parent::registerProductsSale($items);
        Mage::dispatchEvent(self::EVENT_CORRECT_STOCK_ITEMS_QTY_AFTER, array(
            'stock'          => $this,
            'items'          => $items,
            'fullsave_items' => $result,
            'operator'       => '+'
        ));
        return $result;
    }
    /**
     * (non-PHPdoc)
     * @see Mage_CatalogInventory_Model_Stock::revertProductsSale()
     */
    public function revertProductsSale($items)
    {
        Mage::dispatchEvent(self::EVENT_CORRECT_STOCK_ITEMS_QTY_BEFORE, array(
            'stock'     => $this,
            'items_obj' => (object)array('items' => &$items),
            'operator'  => '-'
        ));
        $result = parent::revertProductsSale($items);
        Mage::dispatchEvent(self::EVENT_CORRECT_STOCK_ITEMS_QTY_BEFORE, array(
            'stock'          => $this,
            'items'          => $items,
            'fullsave_items' => $result,
            'operator'       => '-'
        ));
        return $result;
    }
}

Then the observer for cataloginventory_stock_item_correct_qty_after can look like this:

    /**
     * @var $items array array($productId => array('qty'=>$qty, 'item'=>$stockItem))
     */
    $items = $observer->getItems();
    foreach ($items as $productId => $item) {
        $stockItem = $item['item'];
        $product = $stockItem->getProduct();

        // Do anything you need with $stockItem and $product here

    }

I recommend not to check if they are out of stock at this point, but to add the products to a queue that is processed by a cronjob, to minimize additional load time for the user.

4
  • it will be nice if you can show how can we fetch inventory data using this event.+1 for this awesomeness Commented Sep 3, 2015 at 6:26
  • I added some more awesomeness instead ;) Commented Sep 3, 2015 at 6:40
  • this is what I call Perfection. You are a Mage Hero... I love this. I wish I can upvote this 5 times more. Kudos :D Commented Sep 3, 2015 at 6:44
  • sales_order_place_after is there any way to fetch getNotifyStockQty() in this event observer
    – inrsaurabh
    Commented Oct 16, 2017 at 9:53
0

You are getting your stockItem from the $observer however you've changed the parameters of your function, therefor $stockItem = $observer->getEvent(); can't get anything because $observer does not exist...

From your OP we can see you are using the $observer inside the lowStockReportSendEmail function, however the observer is not present here!

Assuming you have the observer, and in that function you create $product and $toEmailAddress before calling lowStockReportSendEmail you should have :

private function lowStockReportSendEmail($observer, $product, $toEmailAddress)
{
    $stockItem = $observer->getEvent();
[...]

And in the code that calls the funtion, obviously $this->lowStockReportSendEmail($observer, $product, $toEmailAddress);

9
  • i have changed it as : if(!empty($product)) { ... since i want those mentioned parameters only. pls help
    – Sushivam
    Commented Apr 14, 2015 at 15:12
  • I'm sure we can fix this (fyi, I have edited your OP as your code blocks where broken, it's wating for peer review). Can you please confirm your config.xml snippet is 100% correct, also can you check lowStockReportSendEmail is up to date and if this function is called from the observer method can you add that snippet please? It seems that you're not passing the observer on, see my edit above. Commented Apr 14, 2015 at 15:16
  • in namespace/module/Model/Notifier.php.i have used $productId as parameter.. In my namespace/module/Model/Productobserver.php , i am using the same function with $observer as parameter.Config is correct
    – Sushivam
    Commented Apr 14, 2015 at 15:20
  • sorry my event is: cataloginventory_stock_item_save_after in config <cataloginventory_stock_item_save_after> <observers> <Metro_Notify> <type>singleton</type> <class>notify/observer</class> <method>lowStockReport</method> </Metro_Notify> </observers> </cataloginventory_stock_item_save_after>
    – Sushivam
    Commented Apr 14, 2015 at 15:22
  • Ok, so in lowStockReport method (I asume you get here?) You load the product and work out the toEmailAddress right? Then you call lowStockReportSendEmail right? Well in the later function you use the $observer again, but you didn't pass it along! see my answer. If your observer function lowStockReport($observer) is not getting called this is a different question! Commented Apr 14, 2015 at 15:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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