ตรวจจับการเปลี่ยนแปลงสินค้าคงคลัง


18

ฉันต้องการตรวจสอบเมื่อใดก็ตามที่ระดับสินค้าคงคลังของผลิตภัณฑ์เปลี่ยนแปลง ฉันประสบความสำเร็จในการใช้cataloginventory_stock_item_save_afterงานเหตุการณ์ที่เกิดขึ้นเมื่อมีการเปลี่ยนแปลงสินค้าคงคลังในแบ็กเอนด์หรือเมื่อมีการยกเลิกคำสั่งซื้อในส่วนหน้า (ผ่าน Paypal) แต่ไม่ได้ถูกทริกเกอร์เมื่อซื้อผลิตภัณฑ์จากส่วนหน้า

ฉันขอเข้าร่วมcataloginventory_stock_item_save_afterกิจกรรมเช่นนี้:

<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) {

ฉันจำเป็นต้องใช้กิจกรรมอื่นเพื่อจับภาพการเปลี่ยนแปลงสินค้าคงคลังเมื่อลูกค้าสั่งซื้อบางอย่างหรือมีบางอย่างผิดปกติกับวิธีที่ฉันติดเข้ากับกิจกรรมหรือไม่

คำตอบ:


26

เมื่อไม่นานมานี้ที่ฉันได้สร้างบางสิ่งบางอย่างขึ้นมาฉันต้องฟังผู้สังเกตการณ์หลายคนเพราะพวกเขาไม่ได้จัดการบันทึกรายการสินค้าทั้งหมดฉันไม่ต้องใช้รหัสต่อไปนี้:

    <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>

และในผู้สังเกตการณ์รหัสต่อไปนี้:

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());
       }
    }
}

หวังว่านี่เป็นสิ่งที่คุณกำลังมองหา


เมื่อฉันใช้สิ่งนี้ตามที่เป็นอยู่มันสร้างข้อผิดพลาดเซิร์ฟเวอร์ 500 ครั้งเมื่อยกเลิกคำสั่งซื้อและการสั่งซื้อไม่ทำงาน ฉันต้องลบเงื่อนไข if ($ this-> isEnabled ()) จากฟังก์ชั่นนี้เพื่อให้ใช้งานได้ เหตุผลใดที่เป็นกรณีนี้? เป็นเพราะฉันใช้ประเภทซิงเกิล? ขอบคุณ
Moustafa Elqabbany

5

คุณไม่สามารถใช้เหตุการณ์ใด ๆ ที่เกี่ยวข้องกับรูปแบบรายการสต็อกได้เนื่องจาก Magento ใช้แบบสอบถาม SQL ที่ปรับให้เหมาะสมเพื่อลดสต็อกสำหรับรายการที่สั่งซื้อทั้งหมดในครั้งเดียวโดยข้ามรุ่น

ฉันแก้ไขสิ่งนี้ด้วยการเขียนMage_CatalogInventory_Model_Stockว่าฉันเพิ่มเหตุการณ์เพิ่มเติมที่ไหน:

<?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;
    }
}

จากนั้นผู้สังเกตการณ์cataloginventory_stock_item_correct_qty_afterสามารถมีลักษณะดังนี้:

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

    }

ฉันไม่แนะนำให้ทำการประมวลผลหนักหรือเรียกฐานข้อมูลเพิ่มเติม (ซึ่งจำเป็นต่อการตรวจสอบว่าผลิตภัณฑ์หมดสต็อก) แต่เพื่อเพิ่มผลิตภัณฑ์ในคิวที่ประมวลผลโดย cronjob เพื่อลดเวลาในการโหลดเพิ่มเติมสำหรับ ผู้ใช้งาน


$stockItem->canSubtractQty()ไม่ทำงานในผู้สังเกตการณ์และไม่$stockItem->getId().. เคล็ดลับใด ๆ ดูเหมือนว่าฉันไม่สามารถเข้าถึงวิธีการได้
snh_nl

เฟเบียน, อะไรคือวัตถุประสงค์ของการเพิ่มเหตุการณ์ที่กำหนดเองที่นี่ในขณะที่คุณสามารถเพิ่มคุณสมบัติด้วยฟังก์ชั่นการเขียนทับตัวเอง? นี่เป็นเพียงการแยกออกเท่านั้น กรุณาแนะนำ
Magento Learner

@MagentoLearner ใช่มันทำให้ฉันสามารถนำกลับมาใช้ใหม่และเพิ่มคุณสมบัติที่แตกต่างได้ง่ายขึ้น ในทางเทคนิคคุณสามารถแนะนำวิธีส่วนตัวแทนได้
Fabian Schmengler

สิ่งนี้อาจเกี่ยวข้องกับการเขียนคลาสหลักอีกครั้ง แต่ก็ยังคงเป็นโซลูชันที่สมบูรณ์ที่สุดที่นี่ บางครั้งคุณต้องเพิ่มกิจกรรมของคุณเองใน M1: P
Brian
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.