5

I am basically trying to implement the scenario where certain special products can only be brought once in customer's lifetime. So need to make sure that if they are added again after being purchased in past, they are swapped with another regular product.

All this is working on checkout_cart_product_add_after except the problem that the product which has been just added doesn't have Item ID assigned to it yet. My understanding is that the item ID hasn't been assigned to it since I am in middle of the saving process.

This is what it looks like inside the observer:

enter image description here

How can I remove an item at this point of execution without itemID being available? I studied Cart & Quote classes in Core and I don't see any way of removing item without knowing its ItemID since its basically just an element of array.

Should I be using another event to do this where this is available? My only concern is that I need to implement the whole swapping in place, not just removed the just added item in cart. So need a combination that works for both (removing the just added product + add more as its replacement).

Any pointers?

2 Answers 2

2

In short, the product has been added to the cart at this point, If you're trying to swap in-place and prevent the cart add I suggest you call within your current observer's cart item setQty(0) which will trigger the removal.

In-depth:

The only thing not completed before the call to checkout_cart_product_add_after is to add the product id to the checkout's session. If you'd like to investigate this method further, check out Mage_Checkout_Model_Cart::addProduct.

So, the dispatch gives us two things in addProduct -

Mage::dispatchEvent('checkout_cart_product_add_after', array('quote_item' => $result, 'product' => $product));

We have access to the quote item itself, meaning, that it is already on the quote; so it needs to have an ID. Handling it prior to the add seems like the reasonable thing to do here, though, one could conceive that calling removeItem would also probably work:

$cartItem = $observer->getEvent()->getQuoteItem();
$cartItem->getQuote()->removeItem($cartItem->getId())->save();

Though, you said you can't do getId, which I find strange. If that's the case, use the setQty I describe above.

4
  • So it is supposed to have an itemID at this point? I have added a screenshot of values inside the observer. And I also tried setting setQty(0) to remove it, but that didn't work. The qty value in the object stays 1 even after calling setQty(0)
    – Ashfame
    Commented Jul 30, 2013 at 10:01
  • There is a _prepareQty() in Mage_Sales_Model_Quote_Item which is called when we call setQty() and it sets the quantity as 1 if its not greater than 0.
    – Ashfame
    Commented Jul 30, 2013 at 10:08
  • Setting it directly $item->setData('qty', 0); helps me achieve what I want but is that an ok thing to do, like I know I will be missing out the dispatch of event sales_quote_item_qty_set_after or should I just call dispatchEvent() in my code?
    – Ashfame
    Commented Jul 30, 2013 at 10:16
  • As mentioned by @Ashfame, you don't have an ID for the quote item when hooking into checkout_cart_product_add_after. See magento.stackexchange.com/questions/10662/… Commented May 19, 2014 at 8:34
0

Finally i managed to alter qty on cart_product_add_after observer. I agree item id is not available in this observer.

$quoteItem = $observer->getEvent()->getQuoteItem();
$avl_qty = 1; //Set or fetch available qty as per your need. I am fetching it using webservice from a third party
if ($avl_qty == '0') {
  $quoteItem->getQuote()->removeItem($quoteItem->getItemId());
  throw new LocalizedException(__("This product is currently out of stock."));                    
} 
elseif ($order_qty > $avl_qty) {                   
  $quoteItem->setData('qty', $avl_qty);
  $this->_cart->save();
  $this->messageManager->addNoticeMessage('Sorry we have only '.$avl_qty.' qty of this product available');                    
} 
else {                   
} 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.