Frage

I have got a custom extension, to track stock movements. So, keep a record of when x amount stock is added for a given product and/or when x amount of stock is removed.

However, Even if I don't edit a products stock level and hit save in admin, it will still add an entry for it in the history table. How can I get it to work so it will only add an entry if there is a change to the stock level?

I tried wrapping the saveStockItemAfter function into an if statement that checked if stock status was changed via $stockItem->getStockStastusChanged(). But, this returns null so the if statement is failing. How can I check if the stock level was adjusted in any way?

My extensions Config.xml:

<?xml version="1.0"?>
<config>
    <modules>
        <JR_StockHistory>
            <version>1.0.0</version>
        </JR_StockHistory>
    </modules>
    <adminhtml>
        <translate>
            <modules>
                <JR_StockHistory>
                    <files>
                        <default>JR_StockHistory.csv</default>
                    </files>
                </JR_StockHistory>
            </modules>
        </translate>
    </adminhtml>
    <global>
        <resources>
            <jr_stockhistory_setup>
                <setup>
                    <module>JR_StockHistory</module>
                </setup>
            </jr_stockhistory_setup>
        </resources>
        <blocks>
            <jr_stockhistory>
                <class>JR_StockHistory_Block</class>
            </jr_stockhistory>
        </blocks>
        <helpers>
            <jr_stockhistory>
                <class>JR_StockHistory_Helper</class>
            </jr_stockhistory>
        </helpers>
        <models>
            <jr_stockhistory>
                <class>JR_StockHistory_Model</class>
                <resourceModel>jr_stockhistory_resource</resourceModel>
            </jr_stockhistory>
            <jr_stockhistory_resource>
                <class>JR_StockHistory_Model_Resource</class>
                <entities>
                    <stock_history>
                        <table>cataloginventory_stock_history</table>
                    </stock_history>
                </entities>
            </jr_stockhistory_resource>
            <cataloginventory>
                <rewrite>
                    <stock>JR_StockHistory_Model_CatalogInventory_Stock</stock>
                </rewrite>
            </cataloginventory>
        </models>
        <events>
            <checkout_submit_all_after>
                <observers>
                    <stock_history>
                        <class>jr_stockhistory/stock_observer</class>
                        <method>checkoutAllSubmitAfter</method>
                    </stock_history>
                </observers>
            </checkout_submit_all_after>
            <cataloginventory_stock_item_save_after>
                <observers>
                    <stock_history>
                        <type>singleton</type>
                        <class>jr_stockhistory/stock_observer</class>
                        <method>saveStockItemAfter</method>
                    </stock_history>
                </observers>
            </cataloginventory_stock_item_save_after>
            <cataloginventory_stock_revert_products_sale>
                <observers>
                    <stock_history>
                        <class>jr_stockhistory/stock_observer</class>
                        <method>stockRevertProductsSale</method>
                    </stock_history>
                </observers>
            </cataloginventory_stock_revert_products_sale>
            <catalog_product_import_finish_before>
                <observers>
                    <stock_history>
                        <class>jr_stockhistory/stock_observer</class>
                        <method>catalogProductImportFinishBefore</method>
                    </stock_history>
                </observers>
            </catalog_product_import_finish_before>
            <controller_action_layout_render_before_adminhtml_catalog_product_edit>
                <observers>
                    <stock_history>
                        <class>jr_stockhistory/stock_observer</class>
                        <method>addStockHistoryTab</method>
                    </stock_history>
                </observers>
            </controller_action_layout_render_before_adminhtml_catalog_product_edit>
            <sales_order_item_cancel>
                <observers>
                    <inventory><type>disabled</type></inventory>
                    <stock_history>
                        <class>jr_stockhistory/stock_observer</class>
                        <method>cancelOrderItem</method>
                    </stock_history>
                </observers>
            </sales_order_item_cancel>
        </events>
    </global>
</config>

My Model/Stock/Observer.php file:

class JR_StockHistory_Model_Stock_Observer
{
    public function addStockHistoryTab()
    {
        $layout = Mage::getSingleton('core/layout');
        $layout->getBlock('product_tabs')
            ->addTab('stock_history', array(
                'after' => 'inventory',
                'label' => Mage::helper('jr_stockhistory')->__('Stock History'),
                'content' => $layout->createBlock('jr_stockhistory/adminhtml_stock_history_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->insertStockHistory($stockItem, sprintf(
                'Product restocked after order cancellation (order: %s)',
                $item->getOrder()->getIncrementId())
            );
        }

        return $this;
    }

    public function catalogProductImportFinishBefore($observer)
    {
        $adapter = $observer->getEvent()->getAdapter();
        Mage_ImportExport_Model_Import::getDataSourceModel()->getIterator()->rewind();
        $model = Mage::getModel('catalog/product');
        $skus = array();
        while ($bunch = $adapter->getNextBunch()) {
            foreach ($bunch as $rowData) {
                if (null !== $rowData['sku']) {
                    $skus[] = $rowData['sku'];
                }
            }
        }

        if (!empty($skus)) {
            $resource = Mage::getResourceModel('jr_stockhistory/stock_history');
            $productIds = $resource->getProductsIdBySku($skus);
            if (!empty($productIds)) {
                $stock = Mage::getSingleton('cataloginventory/stock');
                $stocks = Mage::getResourceModel('cataloginventory/stock')->getProductsStock($stock, $productIds);
                $stocksHistory = array();
                $datetime = Varien_Date::formatDate(time());
                foreach ($stocks as $stockData) {
                    $stocksHistory[] = 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($stocksHistory)) {
                    $resource->insertStocksHistory($stocksHistory);
                }
            }
        }
    }

    public function checkoutAllSubmitAfter($observer)
    {
        if ($observer->getEvent()->hasOrders()) {
            $orders = $observer->getEvent()->getOrders();
        } else {
            $orders = array($observer->getEvent()->getOrder());
        }
        $stockItems = array();
        foreach ($orders as $order) {
            foreach ($order->getAllItems() as $orderItem) {
                if ($orderItem->getQtyOrdered()) {
                    $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->insertStockHistory($stockItem, sprintf(
                    'Product ordered (order%s: %s)',
                    count($data['orders']) > 1 ? 's' : '',
                    implode(', ', $data['orders'])
                ));
            }
        }
    }

    public function insertStockHistory(Mage_CatalogInventory_Model_Stock_Item $stockItem, $message = '')
    {
        Mage::getModel('jr_stockhistory/stock_history')
            ->setItemId($stockItem->getId())
            ->setUser($this->_getUsername())
            ->setUserId($this->_getUserId())
            ->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()) {
       if($stockItem->getStockStastusChanged()){
        if (! $message = $stockItem->getSaveHistoryMessage()) {
            if (Mage::getSingleton('api/session')->getSessionId()) {
                $message = Mage::helper('jr_stockhistory')->__('Stock saved from Magento API');
            } else {
                $message = Mage::helper('jr_stockhistory')->__('Stock saved manually');
            }
        }
        $this->insertStockHistory($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->insertStockHistory($stockItem, $message);
            }
        }
    }

    protected function _getUserId()
    {
        $userId = null;
        if (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('admin/session')->isLoggedIn()) {
            $username = Mage::getSingleton('admin/session')->getUser()->getUsername();
        }

        return $username;
    }
}
War es hilfreich?

Lösung

The solution was to change $stockItem->getStockStastusChanged() to instead check for stock change via:

(int)$stockItem->getData('qty') != (int)$stockItem->getOrigData('qty')

Which checks if quantity value in the current data array is not equal to the original data array.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit magento.stackexchange
scroll top