Magento – Attach Products to Orders Programmatically

I’ve been heads down on a project recently where I’ve had to migrate a ton of legacy data from two cart systems into Magento.  The client discontinued use of the Cart A two years ago, but there were ~21,000 orders in that system that were imported into Cart B, which holds the remaining ~15,000 orders.

When Cart A was imported into Cart B, the orders had products that did not yet exist in Cart B.  The programmer responsible for that move didn’t see it necessary to create the missing products in Cart B, so Cart B ended up with around 6,000 orders with no product line items.  In other words, people called in to the client’s customer service and if that customer inquired about one of the aforementioned orders, then the client couldn’t even see what items were ordered.

I was able to achieve a 1-to-1 migration of all data in Cart B to Magento, but that meant I still had the problem of orders with no product line items.

I still had the legacy orders from Cart A in a 15 mb Excel file.  Each line in the Excel file represented one order.  All of the data on one line, fully de-normalized.  Anyway, after writing a script to parse the Excel file, find the missing products, and insert the missing products into Magento, I was ready to attach those products to their respective orders.  Here’s how that’s done.

// Load the order however you wish. I had the $increment_id already.
$order = Mage::getModel('sales/order')->loadByIncrementId($increment_id);
 
$rowTotal = $product->getPrice() * $qty;
$order_item = Mage::getModel('sales/order_item')
	->setStoreId(NULL)
	->setQuoteItemId(NULL)
	->setQuoteParentItemId(NULL)
	->setProductId($product_id)
	->setProductType($product->getTypeId())
	->setQtyBackordered(NULL)
	->setTotalQtyOrdered($qty)
	->setQtyOrdered($qty)
	->setName($product->getName())
	->setSku($product->getSku())
	->setPrice($product->getPrice())
	->setBasePrice($product->getPrice())
	->setOriginalPrice($product->getPrice())
	->setRowTotal($rowTotal)
	->setBaseRowTotal($rowTotal)
	->setOrder($order);
echo "Saving order item...\n";
$order_item->save();

I had tried at first to use the addItem() method on the $order object itself, but calling $order->save() did nothing. No error was thrown either.  I didn’t look into it much further, but this might be due to something in the Mage core code that prevents data from being saved if the request isn’t of type Front_Controller_Action.  That’s happened to me before when attempting to save product ratings programmatically.

Hope this helps people out there!

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> <pre lang="" line="" escaped="" highlight="">