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.