Magento – How to Merge Quote Items

cartee-1.12magento-enterprisequote

I'm trying to merge like items in the cart by taking the total quantity of an item by SKU (the ID field is unreliable as multiple items may return as empty/null), setting the first instance to the total quantity, then either deleting or changing the rest to 0. This doesn't seem to work, however. This runs in an observer for the events checkout_cart_product_add_after and checkout_cart_product_update_after.

Edit: Brought in the code from removeItem() directly since it only works by ID, which may sometimes be blank. Now I'm unable to add items to the cart at all.

$version = floatval(Mage::getVersion());
$quantities = array();

foreach($quote->getAllVisibleItems() as $item) {
    if(!array_key_exists($item->getSku(),$quantities))
        { $quantities[$item->getSku()] = $item->getQty(); }
    else {
        $quantities[$item->getSku()] += $item->getQty();

        if($version >= 1.13)
            { $quote->deleteItem($item); }
        else {
            $item->isDeleted(true);
            if($item->getHasChildren()) {
                foreach($item->getChildren() as $child)
                    { $child->isDeleted(true); }
            }
            $parent = $item->getParentItem();
            if($parent)
                { $parent->isDeleted(true); }
            Mage::dispatchEvent('sales_quote_remove_item',array('quote_item'=>$item));
        }
    }
}

$quote->setTotalsCollectedFlag(false)->collectTotals()->save();

What am I doing wrong?

Best Answer

The function Mage_Sales_Model_Quote::removeItem() expects $itemId as a parameter, not an $item object.

So, your first foreach statement should be:

foreach($quote->getAllVisibleItems() as $item) {
    if(!array_key_exists($item->getSku(),$quantities))
        { $quantities[$item->getSku()] = $item->getQty(); }
    else {
        $quantities[$item->getSku()] += $item->getQty();
        $quote->removeItem($item->getId());
    }
}

This function is available in Enterprise 1.13. It gives the option to delete a quote item that doesn't have an id:

public function deleteItem(Mage_Sales_Model_Quote_Item $item)
{
    if ($item->getId()) {
        $this->removeItem($item->getId());
    } else {
        $quoteItems = $this->getItemsCollection();
        $items = array($item);
        if ($item->getHasChildren()) {
            foreach ($item->getChildren() as $child) {
                $items[] = $child;
            }
        }
        foreach ($quoteItems as $key => $quoteItem) {
            foreach ($items as $item) {
                if ($quoteItem->compare($item)) {
                    $quoteItems->removeItemByKey($key);
                }
            }
        }
    }

    return $this;
}
Related Topic