Nie można użyć żadnego zdarzenia związanego z modelem towaru magazynowego, ponieważ Magento używa zoptymalizowanego zapytania SQL, aby zmniejszyć zapasy wszystkich zamówionych towarów jednocześnie, omijając model.
Rozwiązałem to, przepisując, Mage_CatalogInventory_Model_Stock
gdzie dodałem dodatkowe wydarzenie:
<?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;
}
}
Wtedy obserwator cataloginventory_stock_item_correct_qty_after
może wyglądać następująco:
/**
* @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
}
Odradzam intensywne przetwarzanie lub dodatkowe wywołania bazy danych (które są niezbędne do wykrycia, na przykład, czy produktu nie ma na magazynie), ale dodawanie produktów do kolejki przetwarzanej przez cronjob, aby zminimalizować dodatkowy czas ładowania użytkownik.