Magento пересчитать итоговую сумму в наблюдателе - PullRequest
11 голосов
/ 03 октября 2011

У меня есть наблюдатель, который удаляет товары из корзины, если их нет в наличии (т. Е. Покупатель возвращается к своей корзине часто x раз, а товара в корзине нет в наличии), и показывает сообщение пользователю .

Удаление товара (ов) работает, но обновление общей корзины - нет. Любая помощь будет принята с благодарностью!

Мой наблюдатель наблюдает за событием sales_quote_save_before:

public function checkStockStatus($observer)
{
    // return if disabled or observer already executed on this request
    if (!Mage::helper('stockcheck')->isEnabled() || Mage::registry('stockcheck_observer_executed')) {
        return $this;
    }

    $quote = $observer->getEvent()->getQuote();
    $outOfStockCount = 0;

    foreach ($quote->getAllItems() as $item) {
        $product = Mage::getModel('catalog/product')->load($item->getProductId());
        $stockItem = $product->getStockItem();
        if ($stockItem->getIsInStock()) {
            // in stock - for testing only
            $this->_getSession()->addSuccess(Mage::helper('stockcheck')->__('in stock'));
            $item->setData('calculation_price', null);
            $item->setData('original_price', null);
        }
        else {
            //remove item 
            $this->_getCart()->removeItem($item->getId());
            $outOfStockCount++; 
            $this->_getSession()->addError(Mage::helper('stockcheck')->__('Out of Stock'));
        }
    }

    if ($outOfStockCount) > 0) {       
        $quote->setTotalsCollectedFlag(false)->collectTotals();
    } 

    Mage::register('stockcheck_observer_executed', true);

    return $this;         
}

protected function _getCart()
{
    return Mage::getSingleton('checkout/cart');
}

protected function _getSession()
{
    return Mage::getSingleton('checkout/session');
}  

Ответы [ 3 ]

21 голосов
/ 04 октября 2011

Совет на день: , наблюдая за * _ save_after и пытаясь заставить тот же объект измениться, обычно вызывается сохранить снова , и выокажется в бесконечном цикле .oO

Однако если вы наблюдаете метод collectTotals () в классе цитат, то вы заметите, что пропускаете важный флаг ->setTotalsCollectedFlag(false)->collectTotals()чтобы сделать вычисление возможным после того, как оно уже рассчитано.

Жизнь была бы чем-то другим, если бы на пути к славе не было ошибок, поэтому помните о следующей проблеме в Magento: Issue # 26145

4 голосов
/ 05 октября 2011

Спасибо @Антон за помощь!

Ответ, который закончил работать для меня, состоял в том, чтобы позвонить на session_write_close(); перед перенаправлением (в наблюдателе):

if (// products are out-of-stock and were removed...) {
    $this->_getSession()->addError('Error message here.');
    $this->_getSession()->getQuote()->setTotalsCollectedFlag(false)->collectTotals();
    session_write_close();
    Mage::app()->getResponse()->setRedirect('index');
}
0 голосов
/ 05 октября 2011

А как насчет следующего потока:

  1. Удалить элементы в обозревателе на sales_quote_save_before и добавить флаг в реестр: Mage::register('ooops_we_need_a_redirect', $url)

  2. В обозревателе на sales_quote_save_after выполните перенаправление, если необходимо:

    if (Mage :: registry ('ooops_we_need_a_redirect')) {// do redirect}

...