1

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?

1 Answer 1

1

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;
}
5
  • What if some of the items have an empty or null ID? Commented Mar 24, 2014 at 14:30
  • You could try this function Mage_Sales_Model_Quote::deleteItem(Mage_Sales_Model_Quote_Item $item). This is the comment that goes with it "Delete quote item. If it does not have identifier then it will be only removed from collection". That might do the trick.
    – Vicky
    Commented Mar 24, 2014 at 14:40
  • Used it and the server got stuck in a loop. Checked out the method and it doesn't exist. For the time being I'm just using the raw code from removeItem() as it pertains to a cached quote item. Commented Mar 24, 2014 at 14:53
  • Sorry, it seems that function is new in magento 1.13. I've added the code of that function to my answer. Hopefully it'll help you or give you some inspiration to solve your problem.
    – Vicky
    Commented Mar 24, 2014 at 15:01
  • It doesn't seem to permit anything to be added to the cart now instead of just merging duplicates. Commented Mar 24, 2014 at 15:24

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.