Você não pode usar nenhum evento relacionado ao modelo de item de estoque, porque o Magento usa uma consulta SQL otimizada para diminuir o estoque de todos os itens pedidos de uma só vez, ignorando o modelo.
Resolvi isso reescrevendo Mage_CatalogInventory_Model_Stock
onde adicionei um evento adicional:
<?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;
}
}
Então o observador para cataloginventory_stock_item_correct_qty_after
pode ficar assim:
/**
* @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
}
Eu recomendo não fazer processamento pesado ou chamadas adicionais ao banco de dados (que são necessárias para detectar se o produto está fora de estoque, por exemplo), mas adicionar os produtos a uma fila que é processada por um cronjob, para minimizar o tempo de carregamento adicional para o do utilizador.