Magento is a wonderful open source eCommerce platform written in PHP that provides are rich inventory management system that lacks a few features that if implemented and save time and money. One of those features missing is the ability to import Orders from CSV. In this post I will show off a crude method I’ve used in the past to accomplish this feat.

For many people using Magento as an eccomerce platform they would like to export orders on a daily basis as part of the fulfillment process. Luckly there is a great module for that purpose available here:
http://www.magentocommerce.com/magento-connect/slandsbek/extension/1350/simple-order-export

Using the Simple Export module you can export your orders to a CSV, but Magento doesn’t do a good job of allowing you to import orders that have been shipped back into the system.

The script below will take a CSV with “OrderNumber,Email,TrackingNumber ,Carrier” and import the orders back into Magento and mark them as Shipped/Complete and include Tracking Numbers that are sent to the customer.

I’ve segregated the PHP function into 3 files. You can download a zip file here.

File: form.php
This file allows you to browse for the CSV you wish to import. Make sure your directory has write permissions to upload the CSV files.


<form enctype="multipart/form-data" action="" method="POST">
  <p>
    <input type="hidden" name="MAX_FILE_SIZE" value="1000000000" />
	CSV File:
    <input name="uploadedfile" type="file" />
  </p>
  <p>
    <input type="submit" name="upload" id="upload" value="Submit" />
  </p>
</form>

File: Import.php
Make sure that wherever you upload the files to you reference the correct location of Mage.php


<?php
	require_once("app/Mage.php");
	Mage::app();
	
	include('updateOrder.php');
  
	if (isset($_POST['MAX_FILE_SIZE'])) {

		$email = true;
  
		$target_path = basename( $_FILES['uploadedfile']['name']); 
		$_FILES['uploadedfile']['tmp_name'];  
		$target_path = basename( $_FILES['uploadedfile']['name']); 
		  
		if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
?>

<div style="font-size: 13px; font-family: Arial, Helvetica, sans-serif; color: #060; font-weight: bold; background-color:#FFC; padding:10px;">
Order Import Succesfully!
<br />
<span style="font-size: 10px; font-style:italic; font-family: Arial, Helvetica, sans-serif; color: #333; padding:15px;">
The file <?php echo basename( $_FILES['uploadedfile']['name']); ?> has been uploaded.
</span>
</div>


<?php	
		  	ini_set("auto_detect_line_endings", 1); 
		  	$current_row = 1; 
		  	$handle = fopen($target_path, "r"); 
		  	$csvData = array();
		  
			while ( ($data = fgetcsv($handle, 10000, ",") ) !== FALSE ) 
			{ 
				$number_of_fields = count($data); 
				if ($current_row == 1) { 	//Header line 
					for ($c=0; $c < $number_of_fields; $c++) 
					{ 
						$header_array[$c] = $data[$c];
					} 
				} else { 	//Data line 
					for ($c=0; $c < $number_of_fields; $c++) 
					{ 
						$data_array[$header_array[$c]] = $data[$c];
					}
					$csvData[] = $data_array;
				} 
				$current_row++; 
			} 
			
			fclose($handle); 
		  
		  	foreach($csvData as $rec) {
			  updateOrder($rec['OrderNumber'], 
								  $rec['Email'],
								  $rec['Carrier'],
								  $rec['TrackingNumber']);
			}
		  
		} //end if statment for file upload check
		
	} else { // end if statement for post check for upload

		include('form.php');
	
	}

?>

File: updateOrder.php


<?php
  function updateOrder($orderId, $email, $carrier, $trackingNum) {
	$includeComment = false;
	$comment = NULL;
	
	$order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
	
	//This converts the order to "Completed".
	$convertor = Mage::getModel('sales/convert_order');
	$shipment = $convertor->toShipment($order);
	
	//other methods to investigate
	// $convertor->toInvoice
	// $convertor->toCreditmemo($order)
	
	// for information on how these methods are ran I usually run a find in SSH:
	// find -name '*.php' -print0 | xargs -0 grep '$convertor->to'

	
	foreach ($order->getAllItems() as $orderItem) {
		
		if (!$orderItem->getQtyToShip()) {
			continue;
		}
		if ($orderItem->getIsVirtual()) {
			continue;
		}
		
		$item = $convertor->itemToShipmentItem($orderItem);
	
		$qty = $orderItem->getQtyToShip();
	
		$item->setQty($qty);
		$shipment->addItem($item);
	}
	
	$carrierTitle = NULL;
	
	// Reference the Magento admin
	// Look for the shipping information by selecting an order that is completed
	// Click the Shipments tab
	// Click on the Shipment
	// Scroll down to Shipping and Tracking Information box
	// The $carrier variable must match what magento uses for its shortname.
	// An easy way to find out what magento uses is to view HTML source code of the Shipping page in your browser
	// Do a Search for "Custom Value"
	// You will find the form like this:
	
	//	 <select name="carrier" class="select" style="width:110px" onchange="selectCarrier(this)">
	//                                        <option value="custom">Custom Value</option>
	//                                        <option value="dhl">DHL</option>
	//                                        <option value="fedex">Federal Express</option>
	//                                        <option value="ups">United Parcel Service</option>
	//                                        <option value="usps">United States Postal Service</option>
	//                                    </select>
	
	// $carrier = whatever the <option value=XXX is
	// $carrierTitle = whatever the text is for that option
	
	if ($carrier == 'ups') {
		$carrierTitle = 'United Parcel Service';
	}
	
	if ($carrier == 'usps') {
		$carrierTitle = 'United States Postal Service';
	}
	
	if ($carrier == 'some_other_carrier') {
		$carrierTitle = 'Some other carrier';
	}
	
	$data = array();
	$data['carrier_code'] = $carrier;
	$data['title'] = $carrierTitle; 
	$data['number'] = $trackingNum;
	
	$track = Mage::getModel('sales/order_shipment_track')->addData($data);
	$shipment->addTrack($track);
	
	// Other methods to investigate and reverse engineer
	// Mage::register('current_shipment', $shipment);
	// Mage::register('current_order', $order);
	// Mage::register('current_invoice', $invoice);

	
	$shipment->register();
	$shipment->addComment($comment, $email && $includeComment);
	$shipment->setEmailSent(true);
	$shipment->getOrder()->setIsInProcess(true);
	
	
	$transactionSave = Mage::getModel('core/resource_transaction')
		->addObject($shipment)
		->addObject($shipment->getOrder())
		->save();
	
	$shipment->sendEmail($email, ($includeComment ? $comment : ''));
	
	$shipment->save();
	
	return;
	
  }
?>