Vous ne pouvez utiliser aucun événement lié au modèle d'article en stock, car Magento utilise une requête SQL optimisée pour réduire le stock de tous les articles commandés en même temps, en contournant le modèle.
J'ai résolu cela avec une réécriture de l' Mage_CatalogInventory_Model_Stock
endroit où j'ai ajouté un événement supplémentaire:
<?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;
}
}
L'observateur cataloginventory_stock_item_correct_qty_after
peut alors ressembler à ceci:
/**
* @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
}
Je recommande de ne pas effectuer de traitement lourd ou d'appels de base de données supplémentaires (qui sont nécessaires pour détecter si le produit est en rupture de stock par exemple), mais pour ajouter les produits à une file d'attente qui est traitée par un cronjob, pour minimiser le temps de chargement supplémentaire pour le utilisateur.