Retrieve Quote Item ID After Added to Cart – Magento 1.9

checkoutmagento-1.9quote

I am running an observer on Magento 1.9 on the following event:

sales_quote_merge_after

This event occurs when a guest customer with items in their cart logs into their account. When doing this the quote item IDs are dropped from the current session and the products are re-added with new IDs. What I need to know (using an observer or otherwise), is what each quote item ID was before, and what it has changed into.

I have tried countless observers on the Mage_Sale_Model_Quote::addItem method, but Magento does not return the new quote item ID on any method I have seen.

In the observer above I have managed to make it pass the original quote and new quote into the observer, but there's no way of matching the quote item IDs.

I have tried adding the original quote item ID as an option to the quote item which works, but as soon as the merge is carried out the options are wiped!

$item->addOption(array(
                'code' => 'original_quote_item_id',
                'product' => $item->getProduct()->getId(),
                'value' => $item->getId()
            ));

I'm left perplexed on where to try next – any advice or suggestions would be greatly appreciated!

Best Answer

So based on what you said I have now got a solution that I belive works 100% of the time and matched the items nicely.

When merging there are 3 things that can happen.

  1. When the item is in both quotes it's qty is merged into the logged in customers item.
  2. When the item is in the guest quote but not the logged in customer quote a new item is cloned into the logged in customer quote, and the item_id is added at some later time (that I couldn't pin point)
  3. The item is in just the logged in customer quote nothing changes.

Because the for the first two possibilitys the item is in both the quotes I used the compare function to find when the items matched and populated the newIds and OriginalIds at that point.

We can then say if there was no match this item was not in the guest quote so just use the newId as there was no originalId.

protected $_source;

/**
 * @param Varien_Event_Observer $observer
 * @return Training_Merge_Model_Observer
 */
public function salesQuoteMergeAfter(Varien_Event_Observer $observer)
{
    $this->_source = $observer->getEvent()->getSource();
}

public function controllerFrontSendResponseAfter(Varien_Event_Observer $observer){
    if($this->_source) {
        $newOldArray = array();

        //Quote = Customer Quote
        //Source = Guest Quote
        $quote = Mage::getSingleton('checkout/session')->getQuote();
        $source = $this->_source;

        foreach ($source->getAllVisibleItems() as $item) {
            foreach ($quote->getAllItems() as $quoteItem) {
                if ($quoteItem->compare($item)) {

                    $newId = $quoteItem->getData('item_id');
                    $originalId = $item->getData('item_id');

                    $newOldArray[] = array(
                        "newId" => $newId,
                        "originalId" => $originalId
                    );

                    $quoteItem->setIsMatch(1);

                }
            }
        }

        //If there was no match so far then it's a new item and there was
        //no similar item in the old quote, we can therefore just take the
        //newId and set the original to null
        foreach ($quote->getAllItems() as $quoteItem) {
            if (!$quoteItem->getIsMatch()) {
                $newId = $quoteItem->getData('item_id');

                $newOldArray[] = array(
                    "newId" => $newId,
                    "originalId" => null
                );

            }
        }
    }


    return $this;
}