0

I have a custom module that will track stock changes on products, but if the "Manage Stock" is set to "No" then I do not want to track any changes nor display the "Stock Movements" tab. Thus, how can I only track changes when the manage stock is set to yes?

The Stock Movement Tab

My config.xml

<?xml version="1.0"?>
<config>
    <modules>
        <Vish_StockMovements>
            <version>1.1.0</version>
        </Vish_StockMovements>
    </modules>
    <global>
        <resources>
            <vish_stockmovements_setup>
                <setup>
                    <module>Vish_StockMovements</module>
                </setup>
            </vish_stockmovements_setup>
        </resources>
        <blocks>
            <vish_stockmovements>
                <class>Vish_StockMovements_Block</class>
            </vish_stockmovements>
        </blocks>
        <helpers>
            <vish_stockmovements>
                <class>Vish_StockMovements_Helper</class>
            </vish_stockmovements>
        </helpers>
        <models>
            <vish_stockmovements>
                <class>Vish_StockMovements_Model</class>
                <resourceModel>vish_stockmovements_resource</resourceModel>
            </vish_stockmovements>
            <vish_stockmovements_resource>
                <class>Vish_StockMovements_Model_Resource</class>
                <entities>
                    <stock_movement>
                        <table>vish_stock_movement</table>
                    </stock_movement>
                </entities>
            </vish_stockmovements_resource>
            <cataloginventory>
                <rewrite>
                    <stock>Vish_StockMovements_Model_CatalogInventory_Stock</stock>
                </rewrite>
            </cataloginventory>
        </models>
        <events>
            <checkout_submit_all_after>
                <observers>
                    <vish_stockmovements>
                        <class>vish_stockmovements/stock_observer</class>
                        <method>checkoutAllSubmitAfter</method>
                    </vish_stockmovements>
                </observers>
            </checkout_submit_all_after>
            <cataloginventory_stock_item_save_after>
                <observers>
                    <vish_stockmovements>
                        <type>singleton</type>
                        <class>vish_stockmovements/stock_observer</class>
                        <method>saveStockItemAfter</method>
                    </vish_stockmovements>
                </observers>
            </cataloginventory_stock_item_save_after>
            <cataloginventory_stock_revert_products_sale>
                <observers>
                    <vish_stockmovements>
                        <class>vish_stockmovements/stock_observer</class>
                        <method>stockRevertProductsSale</method>
                    </vish_stockmovements>
                </observers>
            </cataloginventory_stock_revert_products_sale>
            <catalog_product_import_finish_before>
                <observers>
                    <vish_stockmovements>
                        <class>vish_stockmovements/stock_observer</class>
                        <method>catalogProductImportFinishBefore</method>
                    </vish_stockmovements>
                </observers>
            </catalog_product_import_finish_before>
            <controller_action_layout_render_before_adminhtml_catalog_product_edit>
                <observers>
                    <vish_stockmovements>
                        <class>vish_stockmovements/stock_observer</class>
                        <method>addStockMovementsTab</method>
                    </vish_stockmovements>
                </observers>
            </controller_action_layout_render_before_adminhtml_catalog_product_edit>
            <sales_order_item_cancel>
                <observers>
                    <inventory><type>disabled</type></inventory>
                    <vish_stockmovements>
                        <class>vish_stockmovements/stock_observer</class>
                        <method>cancelOrderItem</method>
                    </vish_stockmovements>
                </observers>
            </sales_order_item_cancel>
        </events>
    </global>
    <adminhtml>
        <translate>
            <modules>
                <Vish_StockMovements>
                    <files>
                        <default>Vish_StockMovements.csv</default>
                    </files>
                </Vish_StockMovements>
            </modules>
        </translate>
    </adminhtml>
    <admin>
        <routers>
            <adminhtml>
                <args>
                    <modules>
                        <Vish_StockMovements before="Mage_Adminhtml">Vish_StockMovements_Adminhtml</Vish_StockMovements>
                    </modules>
                </args>
            </adminhtml>
        </routers>
    </admin>
</config>

My Observer.php

<?php
/**
 * @category    Vish
 * @package     Vish_StockMovements
 * @version     1.0.0
 */
class Vish_StockMovements_Model_Stock_Observer
{
    public function addStockMovementsTab()
    {
        $layout = Mage::getSingleton('core/layout');
        /** @var Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs $block */
        $block = $layout->getBlock('product_tabs');
        if ($block && $block->getProduct() && $block->getProduct()->getTypeId() == 'simple') {
            $block->addTab('stock_movements', array(
                'after' => 'inventory',
                'label' => Mage::helper('vish_stockmovements')->__('Stock Movements'),
                'content' => $layout->createBlock('vish_stockmovements/adminhtml_stock_movement_grid')->toHtml(),
            ));
        }
    }

    public function cancelOrderItem($observer)
    {
        $item = $observer->getEvent()->getItem();

        $children = $item->getChildrenItems();
        $qty = $item->getQtyOrdered() - max($item->getQtyShipped(), $item->getQtyInvoiced()) - $item->getQtyCanceled();

        if ($item->getId() && ($productId = $item->getProductId()) && empty($children) && $qty) {
            Mage::getSingleton('cataloginventory/stock')->backItemQty($productId, $qty);
            $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($item->getProductId());
            $this->insertStockMovement($stockItem, sprintf(
                'Product restocked after order cancellation (order: %s)',
                $item->getOrder()->getIncrementId())
            );
        }

        return $this;
    }

    public function catalogProductImportFinishBefore($observer)
    {
        $productIds = array();
        $adapter = $observer->getEvent()->getAdapter();
        $resource = Mage::getResourceModel('vish_stockmovements/stock_movement');

        if ($adapter instanceof Mage_Catalog_Model_Convert_Adapter_Product) {
            $productIds = $adapter->getAffectedEntityIds();
        } else {
            Mage_ImportExport_Model_Import::getDataSourceModel()->getIterator()->rewind();
            $skus = array();
            while ($bunch = $adapter->getNextBunch()) {
                foreach ($bunch as $rowData) {
                    if (null !== $rowData['sku']) {
                        $skus[] = $rowData['sku'];
                    }
                }
            }
            if (!empty($skus)) {
                $productIds = $resource->getProductsIdBySku($skus);
            }
        }

        if (!empty($productIds)) {
            $stock = Mage::getSingleton('cataloginventory/stock');
            $stocks = Mage::getResourceModel('cataloginventory/stock')->getProductsStock($stock, $productIds);
            $stocksMovements = array();
            $datetime = Varien_Date::formatDate(time());
            foreach ($stocks as $stockData) {
                $stocksMovements[] = array(
                    'item_id'     => $stockData['item_id'],
                    'user'        => $this->_getUsername(),
                    'user_id'     => $this->_getUserId(),
                    'qty'         => $stockData['qty'],
                    'is_in_stock' => (int) $stockData['is_in_stock'],
                    'message'     => 'Product import',
                    'created_at'  => $datetime,
                );
            }

            if (!empty($stocksMovements)) {
                $resource->insertStocksMovements($stocksMovements);
            }
        }
    }

    public function checkoutAllSubmitAfter($observer)
    {
        if ($observer->getEvent()->hasOrders()) {
            $orders = $observer->getEvent()->getOrders();
        } else {
            $orders = array($observer->getEvent()->getOrder());
        }
        $stockItems = array();
        foreach ($orders as $order) {
            if ($order) {
                foreach ($order->getAllItems() as $orderItem) {
                    /** @var Mage_Sales_Model_Order_Item $orderItem */
                    if ($orderItem->getQtyOrdered() && $orderItem->getProductType() == 'simple') {
                        $stockItem = Mage::getModel('cataloginventory/stock_item')
                            ->loadByProduct($orderItem->getProductId());
                        if (!isset($stockItems[$stockItem->getId()])) {
                            $stockItems[$stockItem->getId()] = array(
                                'item' => $stockItem,
                                'orders' => array($order->getIncrementId()),
                            );
                        } else {
                            $stockItems[$stockItem->getId()]['orders'][] = $order->getIncrementId();
                        }
                    }
                }
            }
        }

        if (!empty($stockItems)) {
            foreach ($stockItems as $data) {
                $this->insertStockMovement($data['item'], sprintf(
                    'Product ordered (order%s: %s)',
                    count($data['orders']) > 1 ? 's' : '',
                    implode(', ', $data['orders'])
                ));
            }
        }
    }

    public function insertStockMovement(Mage_CatalogInventory_Model_Stock_Item $stockItem, $message = '')
    {
        if ($stockItem->getId()) {
            Mage::getModel('vish_stockmovements/stock_movement')
                ->setItemId($stockItem->getId())
                ->setUser($this->_getUsername())
                ->setUserId($this->_getUserId())
                ->setIsAdmin((int) Mage::getSingleton('admin/session')->isLoggedIn())
                ->setQty($stockItem->getQty())
                ->setIsInStock((int) $stockItem->getIsInStock())
                ->setMessage($message)
                ->save();
            Mage::getModel('catalog/product')->load($stockItem->getProductId())->cleanCache();
        }
    }

    public function saveStockItemAfter($observer)
    {
        $stockItem = $observer->getEvent()->getItem();
        if (!$stockItem->getStockStatusChangedAutomaticallyFlag() && $stockItem->getOriginalInventoryQty() != $stockItem->getQty()) {
            if (!$message = $stockItem->getSaveMovementMessage()) {
                if (Mage::getSingleton('api/session')->getSessionId()) {
                    $message = 'Stock saved from Magento API';
                } else {
                    $message = 'Stock saved manually';
                }
            }
            $this->insertStockMovement($stockItem, $message);
        }
    }

    public function stockRevertProductsSale($observer)
    {
        $items = $observer->getEvent()->getItems();
        foreach ($items as $productId => $item) {
            $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($productId);
            if ($stockItem->getId()) {
                $message = 'Product restocked';
                if ($creditMemo = Mage::registry('current_creditmemo')) {
                    $message = sprintf(
                        'Product restocked after credit memo creation (credit memo: %s)',
                        $creditMemo->getIncrementId()
                    );
                }
                $this->insertStockMovement($stockItem, $message);
            }
        }
    }

    protected function _getUserId()
    {
        $userId = null;
        if (Mage::getSingleton('customer/session')->isLoggedIn()) {
            $userId = Mage::getSingleton('customer/session')->getCustomerId();
        } elseif (Mage::getSingleton('admin/session')->isLoggedIn()) {
            $userId = Mage::getSingleton('admin/session')->getUser()->getId();
        }

        return $userId;
    }

    protected function _getUsername()
    {
        $username = '-';
        if (Mage::getSingleton('api/session')->isLoggedIn()) {
            $username = Mage::getSingleton('api/session')->getUser()->getUsername();
        } elseif (Mage::getSingleton('customer/session')->isLoggedIn()) {
            $username = Mage::getSingleton('customer/session')->getCustomer()->getName();
        } elseif (Mage::getSingleton('admin/session')->isLoggedIn()) {
            $username = Mage::getSingleton('admin/session')->getUser()->getUsername();
        }

        return $username;
    }
}

Update:

Okay I believe I have got the tab adding only if manage stock is set to yes, by amending the addStockMovementsTab() like so:

    $manageStock = $block->getProduct()->getStockItem()->getManageStock();
    if ($block && $manageStock && $block->getProduct() && $block->getProduct()->getTypeId() == 'simple') {
        //same as above in here
    }

However, I am not sure if this is the best way to go about. Also, will I have to replicate this in each method?

0

The solution for this was fairly straightforward. I declared a flag to check if manage stock is true ("1") or if false ("0"). Then incorporated this into the if statement, so would only run if the value was true.

$manageStock = $item->getProduct()->getStockItem()->getManageStock();

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.