Envanter değişikliğini algılama


18

Bir ürünün envanter seviyesi değiştiğinde tespit etmem gerekir. cataloginventory_stock_item_save_afterEnvanter arka uçta değiştirildiğinde veya bir siparişin ön uçta (Paypal aracılığıyla) iptal edildiğinde tetiklenen olayı kullanarak bazı başarılar yaşadım , ancak ön uçtan bir ürün satın alındığında tetiklenmedi.

cataloginventory_stock_item_save_afterBöyle bir etkinliğe katılıyorum :

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

Bir müşteri bir şey satın aldığında envanter değişikliğini yakalamak için başka bir etkinlik kullanmam gerekir mi yoksa etkinliğe bağlanma şeklimde bir sorun mu var?

Yanıtlar:


26

Bir süre önce bunun için bir şeyler inşa ettim, çünkü birden fazla gözlemciyi dinlemek zorunda kaldım çünkü hepsi kataloj envanterin kaydedilmesiyle ele alınmadı, aşağıdaki kodu yapmak zorundayı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>

Ve gözlemcide aşağıdaki kod:

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

Umarım bu aradığınız şeydir.


Bunu olduğu gibi kullandığımda, siparişleri iptal ederken ve sipariş verirken 500 sunucu hatası üretti. Bunun çalışması için if ($ this-> isEnabled ()) koşulunu silmek zorunda kaldı. Durumun böyle olmasının bir nedeni var mı? Singleton türünü kullandığım için mi? Teşekkürler
— Moustafa Elqabbany

5

Stok öğesi modeliyle ilgili hiçbir olayı kullanamazsınız, çünkü Magento, modeli atlayarak sipariş edilen tüm öğelerin stokunu bir kerede azaltmak için optimize edilmiş bir SQL sorgusu kullanır.

Bunu Mage_CatalogInventory_Model_Stockek bir etkinlik eklediğim yeri yeniden yazarak çözdüm :

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

Sonra için gözlemci cataloginventory_stock_item_correct_qty_afterşöyle görünebilir:

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

    }

Ağır işlem veya ek veritabanı çağrıları yapmamayı (ürünün stokta olup olmadığını tespit etmek için gereklidir), ancak ürünleri bir cronjob tarafından işlenen bir kuyruğa eklemeyi, kullanıcı.


$stockItem->canSubtractQty()gözlemcide çalışmıyor ne de $stockItem->getId().. herhangi bir ipucu? Yöntemlere erişemiyorum
— snh_nl

Fabian, buraya özel etkinlikler eklemenin amacı nedir, çünkü üzerine yazılan fonksiyonun kendisi ile özelliği ekleyebilirsiniz? bu sadece ayrıştırmak için mi? Lütfen yönlendirin.
— Magento Öğrenci

@MagentoLearner evet, farklı özellikleri tekrar kullanmamı ve eklememi kolaylaştırdı. Teknik olarak bunun yerine özel bir yöntem de
— sunabilirsiniz

Bu, çekirdek bir sınıfın yeniden yazılmasını içerebilir, ancak yine de buradaki en eksiksiz çözümdür. Bazen sadece kendi etkinliklerinizi M1: P
— Brian
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.