11

在庫がない場合(つまり、顧客が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');
}  
4

3 に答える 3

21

今日のヒント: *_save_afterを観察し、同じオブジェクトを強制的に変更しようとすると、通常、save が再度呼び出され、無限ループ.oOに陥ります。

->setTotalsCollectedFlag(false)->collectTotals()ただし、quote クラスの collectTotals() メソッドを観察すると、計算が完了したら計算を可能にするための重要なフラグが欠落していることに気付くでしょう。

栄光への道にいくつかのバグがなければ、人生は何か違うものになるので、Magento の次の問題に注意してください:問題 #26145

于 2011-10-04T07:37:52.360 に答える
6

@アントン、助けてくれてありがとう!

私にとってうまくいった答えは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');
}
于 2011-10-04T23:27:20.893 に答える
0

次のフローはどうですか?

  1. オブザーバーのアイテムを削除しsales_quote_save_before、レジストリにフラグを追加します。Mage::register('ooops_we_need_a_redirect', $url)

  2. オブザーバーでsales_quote_save_afterは、必要に応じてリダイレクトを実行します。

    if(Mage :: registerry('ooops_we_need_a_redirect')){//リダイレクトする}

于 2011-10-04T21:11:46.653 に答える