Magento: Adding Items to Existing Orders

Modifying existing orders is always going to be a risky task, especially since orders have multiple states and statuses. Be careful when doing anything like this.

I recently had a need to add an item to a bunch of orders that had not yet been shipped. Fortunately, it was a bit easier for me, because the situation I had to work from is that all orders with a specific SKU were missing another item (it should have been included in a bundle, but they forgot it when creating the bundle). So, it was easy to look up all orders that had that specific sku.

However you get your orders is up to you. I will walk you through what to do when you have your orders and are ready to loop through them and add the item.

I had to add the same exact item to all the orders I needed to modify. So first I loaded up a product object, and I had to set the price to zero because it would have been included for free in the bundle anyway:

// Load the Order
$product = Mage::getModel('catalog/product')->load($productId);
$product->setPrice(0);

In my case, I had an array of order ids that I looped through, so I had to load up each order:

// Load the Order
$order = Mage::getModel('sales/order')->load($orderId);

Then I had to get the quote. For some reason (not sure if a bug or something), $order->getQuote() did not work. Try that first. If that doesn’t work, try this:

// Load the Quote
$quote = Mage::getModel('sales/quote')->getCollection()->addFieldToFilter("entity_id", $order->getQuoteId())->getFirstItem();

In our case, we were finding that some orders did not have a corresponding quote (maybe a bug, maybe some of them got purged for some reason), so I had to add in some code to convert the current order to a quote:

// Create quote if no quote was found
if (!$quote->getId()) {
    $quote = Mage::getModel('sales/convert_order')
        ->toQuote($order)
        ->setIsActive(false)
        ->setReservedOrderId($order->getIncrementId())
        ->save();
}

Once we have the quote object, we can then add an item to it. Make sure you’ve loaded up your product object, because you will pass it in here. The method setProduct accepts a product object. You can also specify the qty if you need to add more than one:

// Create the item for the quote
$quoteItem = Mage::getModel('sales/quote_item')
    ->setProduct($product)
    ->setQuote($quote)
    ->setQty($qty)
    ->save();

Now that the item has been added to the quote, we need to convert the quote back to the order:

// Convert the quote item to an order item for this order
$orderItem = Mage::getModel('sales/convert_quote')
    ->itemToOrderItem($quoteItem)
    ->setOrderID($order->getId())
    ->save($orderId);

At that point, the order will then have the new item.

I couldn’t find a better way to add items to existing orders, so if you happen to know how to improve this, or a better way to do it, please let me know.

This entry was posted in Magento, PHP. Bookmark the permalink.

5 Responses to Magento: Adding Items to Existing Orders

  1. Kalpesh says:

    Hi Josh, I wrote an article for this same topic last year. You can check that and make modification if needed. FYI, I have not added product to quote and then converted it to order, I directly added the item to placed order instead.
    http://ka.lpe.sh/2012/10/22/magento-add-products-to-placed-order-programatically/

    You did nice work :)

    • Josh Pratt says:

      Yes – the problem with your method is that the quote remains unmodified (as you mentioned in your post). I would not recommend doing it the way you’ve done it unless absolutely necessary.

  2. Dan says:

    Josh: What version did you test this on? I’m trying to do something similar but getting complaints about the object type for the $quoteItem after the save() call.

    • Josh Pratt says:

      Dan – We recently used it on EE 1.9, which I believe is equivalent to CE 1.4. But, I definitely thought it would have worked for later versions.

      • Dan says:

        Hey. I managed to get it to work in the end.

        I’m using EE 1.12 and there seems to be an issue with the $quoteItem not being returned as the correct entity type.

        I got round it by adding an additional loop through the quote after you’ve added the items, keeping track of whats been added and then ignoring those items when adding to the order. This creates the correct entity type for the itemToOrderItem() call.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>