Phát hiện thay đổi hàng tồn kho


18

Tôi cần phát hiện bất cứ khi nào mức tồn kho của sản phẩm thay đổi. Tôi đã thành công khi sử dụng cataloginventory_stock_item_save_aftersự kiện được kích hoạt khi hàng tồn kho được thay đổi trong phần phụ trợ hoặc khi đơn hàng bị hủy trên giao diện (qua Paypal), nhưng không được kích hoạt khi sản phẩm được mua từ giao diện.

Tôi đang tham gia vào cataloginventory_stock_item_save_aftersự kiện như thế này:

<global>
    <events>
        <cataloginventory_stock_item_save_after>
            <observers>
                <cataloginventory_stock_item_save_after_handler>
                    <type>model</type>
                    <class>stockchange/observer</class>
                    <method>stockChange</method>
                </cataloginventory_stock_item_save_after_handler>
            </observers>
        </cataloginventory_stock_item_save_after>
    </events>

<?php
class FashionBunker_StockChange_Model_Observer {
    public function stockChange(Varien_Event_Observer $observer) {

Tôi có cần sử dụng một sự kiện khác để nắm bắt sự thay đổi hàng tồn kho khi khách hàng mua thứ gì đó không, hay có gì đó không đúng với cách tôi đã tham gia vào sự kiện?

Câu trả lời:


26

Cách đây một thời gian, tôi đã xây dựng một cái gì đó cho việc này, tôi đã phải lắng nghe nhiều nhà quan sát bởi vì họ không phải là tất cả được xử lý bởi lưu danh mục, tôi phải tuân theo mã:

    <events>
        <cataloginventory_stock_item_save_commit_after>
            <observers>
                <genmato_stockupdate>
                    <class>genmato_stockupdate/observer</class>
                    <method>catalogInventorySave</method>
                </genmato_stockupdate>
            </observers>
        </cataloginventory_stock_item_save_commit_after>
        <sales_model_service_quote_submit_before>
            <observers>
                <genmato_stockupdate>
                    <class>genmato_stockupdate/observer</class>
                    <method>subtractQuoteInventory</method>
                </genmato_stockupdate>
            </observers>
        </sales_model_service_quote_submit_before>
        <sales_model_service_quote_submit_failure>
            <observers>
                <genmato_stockupdate>
                    <class>genmato_stockupdate/observer</class>
                    <method>revertQuoteInventory</method>
                </genmato_stockupdate>
            </observers>
        </sales_model_service_quote_submit_failure>
        <sales_order_item_cancel>
            <observers>
                <genmato_stockupdate>
                    <class>genmato_stockupdate/observer</class>
                    <method>cancelOrderItem</method>
                </genmato_stockupdate>
            </observers>
        </sales_order_item_cancel>
        <sales_order_creditmemo_save_after>
            <observers>
                <genmato_stockupdate>
                    <class>genmato_stockupdate/observer</class>
                    <method>refundOrderInventory</method>
                </genmato_stockupdate>
            </observers>
        </sales_order_creditmemo_save_after>
    </events>

Và trong trình quan sát mã sau đây:

public function catalogInventorySave(Varien_Event_Observer $observer)
{
    if ($this->isEnabled()) {
        $event = $observer->getEvent();
        $_item = $event->getItem();

        if ((int)$_item->getData('qty') != (int)$_item->getOrigData('qty')) {
            $params = array();
            $params['product_id'] = $_item->getProductId();
            $params['qty'] = $_item->getQty();
            $params['qty_change'] = $_item->getQty() - $_item->getOrigData('qty');
        }
    }
}

public function subtractQuoteInventory(Varien_Event_Observer $observer)
{
    if ($this->isEnabled()) {
        $quote = $observer->getEvent()->getQuote();
        foreach ($quote->getAllItems() as $item) {
            $params = array();
            $params['product_id'] = $item->getProductId();
            $params['sku'] = $item->getSku();
            $params['qty'] = $item->getProduct()->getStockItem()->getQty();
            $params['qty_change'] = ($item->getTotalQty() * -1);
        }
    }
}

public function revertQuoteInventory(Varien_Event_Observer $observer)
{
    if ($this->isEnabled()) {
        $quote = $observer->getEvent()->getQuote();
        foreach ($quote->getAllItems() as $item) {
            $params = array();
            $params['product_id'] = $item->getProductId();
            $params['sku'] = $item->getSku();
            $params['qty'] = $item->getProduct()->getStockItem()->getQty();
            $params['qty_change'] = ($item->getTotalQty());
        }
    }
}

public function cancelOrderItem(Varien_Event_Observer $observer)
{
    if ($this->isEnabled()) {
        $item = $observer->getEvent()->getItem();
        $qty = $item->getQtyOrdered() - max($item->getQtyShipped(), $item->getQtyInvoiced()) - $item->getQtyCanceled();
        $params = array();
        $params['product_id'] = $item->getProductId();
        $params['sku'] = $item->getSku();
        $params['qty'] = $item->getProduct()->getStockItem()->getQty();
        $params['qty_change'] = $qty;
    }
}

public function refundOrderInventory(Varien_Event_Observer $observer)
{
    if ($this->isEnabled()) {
        $creditmemo = $observer->getEvent()->getCreditmemo();
        foreach ($creditmemo->getAllItems() as $item) {
            $params = array();
            $params['product_id'] = $item->getProductId();
            $params['sku'] = $item->getSku();
            $params['qty'] = $item->getProduct()->getStockItem()->getQty();
            $params['qty_change'] = ($item->getQty());
       }
    }
}

Hy vọng đây là một chút những gì bạn đang tìm kiếm.


Khi tôi sử dụng nó, nó đã tạo ra một lỗi máy chủ 500 khi hủy đơn hàng và đặt đơn hàng không hoạt động. Tôi đã phải xóa điều kiện if ($ this-> isEnables ()) khỏi các hàm để nó hoạt động. Bất kỳ lý do tại sao đây là trường hợp? Có phải vì tôi đang sử dụng loại singleton? Cảm ơn
Moustaha Elqabbany

5

Bạn không thể sử dụng bất kỳ sự kiện nào liên quan đến mô hình vật phẩm chứng khoán, vì Magento sử dụng truy vấn SQL được tối ưu hóa để giảm chứng khoán cho tất cả các mặt hàng được đặt cùng một lúc, bỏ qua mô hình.

Tôi đã giải quyết điều này bằng cách viết lại Mage_CatalogInventory_Model_Stocknơi tôi đã thêm một sự kiện bổ sung:

<?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_AFTER, array(
            'stock'          => $this,
            'items'          => $items,
            'fullsave_items' => $result,
            'operator'       => '+'
        ));
        return $result;
    }
}

Sau đó, người quan sát cataloginventory_stock_item_correct_qty_aftercó thể trông như thế này:

    /**
     * @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

    }

Tôi khuyên bạn không nên thực hiện xử lý nặng hoặc các cuộc gọi cơ sở dữ liệu bổ sung (cần thiết để phát hiện xem sản phẩm hết hàng chẳng hạn), nhưng để thêm các sản phẩm vào hàng đợi được xử lý bởi cronjob, để giảm thiểu thời gian tải bổ sung cho người sử dụng.


$stockItem->canSubtractQty()không làm việc trong người quan sát cũng không phải là $stockItem->getId().. bất kỳ lời khuyên? Có vẻ như tôi không thể truy cập các phương thức
snh_nl

Fabian, mục đích của việc thêm các sự kiện tùy chỉnh ở đây là gì khi bạn có thể thêm tính năng với chính chức năng được ghi đè? Đây chỉ là để tách rời? Xin hướng dẫn.
Học viên Magento

@MagentoLearner vâng, nó giúp tôi dễ dàng sử dụng lại và thêm các tính năng khác nhau. Về mặt kỹ thuật, bạn cũng có thể giới thiệu một phương pháp riêng thay thế
Fabian Schmengler

Điều này có thể liên quan đến việc viết lại một lớp lõi, nhưng nó vẫn là giải pháp hoàn chỉnh nhất ở đây. Đôi khi bạn chỉ cần thêm các sự kiện của riêng mình vào M1: P
Brian
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.