I’ve been looking over Magento’s code (1.6.2 Community Edition), and OMG is it a terribly executed mess, but I won’t rant here about that.
Looking at this code:
// Delete error from item and its quote, if it was set due to qty lack
$this->_removeErrorsFromQuoteAndItem($quoteItem, Mage_CatalogInventory_Helper_Data::ERROR_QTY);
Which is in Mage_CatalogInventory_Model_Observer class in
/app/code/core/Mage/CatalogInventory/Model/Observer.php
Line: 489
This produces a peculiar bug to me, try this (make sure “no backorders” is set in backend):
- Add a product to the cart
- Add another product to the cart.
- Go in admin and change first product quantity such that the requested quantity in the cart is not enough.
- Go back to shopping cart page.
Result
The first product added shows the “requested item not available in this quantity” error, but the Checkout methods are still shown ! Continuing forward, eventually gives an ugly js alert saying “Not all items are available in the requested qty”.
Digging deeper I see that it seems every quote item (cart item) added to the quote (cart) resets the error state for the whole quote.
Is this intentional ? Have I stumbled upon a genuine bug ?
What does this useless comment mean ?
Thanks in advance.
EDIT: See answer below for workaround and explanation.
I have to post a follow up, My core hack had an unfortunate side effect (another bug):
So apparently this particular logic is necessary for that scenario.
The actual flaw is that the quote error info collection does not differentiate between quote items. So the _removeErrorsFromQuoteAndItem function removes all quantity related errors from the cart including those that came from another quote item (that is still in error).
I found a workaround that works without any core hacks, attach this event observer to the sales_quote_item_qty_set_after event.
Note: The module that has this event handler must add to the tag of the module XML file in /app/etc/modules/ (eg: /app/etc/modules/MyCompany_MyModule.xml) to ensure that this handler is called after Mage_CatalogInventory_Model_Observer::checkQuoteItemQty which has the bug.
The real solution is to fix the quote errorInfo system to maintain quote item identity, but this workaround will do without any core hacks.