You need to keep in mind that each order can have multiple shipments and that each shipment can have multiple tracking numbers with multiple products.
Solution 1
After looking at app/code/core/Mage/Sales/Model/Order/Shipment.php
you see that there are two methods of interest:
getAllItems()
and
getAllTracks()
Which you can then use on your $order
object
$order = Mage::getModel('sales/order')->load($your_order_id);
$shipment_collection = Mage::getResourceModel('sales/order_shipment_collection')
->setOrderFilter($order)
->load();
foreach($shipment_collection as $shipment){
echo "Tracking number(s) for shipment:<br/>";
foreach($shipment->getAllTracks() as $tracking_number){
echo $tracking_number->getNumber() . "<br/>";
}
echo "Product(s) on shipment:<br/>";
foreach ($shipment->getAllItems() as $product){
echo $product->getName() . "<br/>";
}
}
Solution 2 - Direct SQL Statements
The reason I'm including this is because I always find it very useful to check the database structure when I'm struggling with something. After a quick glance at the database, you see some notable tables namely:
sales_flat_shipment
,
sales_flat_shipment_item
and
sales_flat_shipment_track
Immediately with these tables in mind, you know pretty much exactly how to find what you are looking for by simply looking at their column names.
$order = Mage::getModel('sales/order')->load($your_order_id);
$sales_flat_shipment = $this->_getTableName('sales_flat_shipment');
$sales_flat_shipment_track = $this->_getTableName('sales_flat_shipment_track');
$sales_flat_shipment_item = $this->_getTableName('sales_flat_shipment_item');
$connection = $this->_getConnection('core_read');
$sql = 'SELECT entity_id FROM ' . $sales_flat_shipment . ' WHERE order_id = ?';
$shipments = $connection->fetchAll($sql, $your_order_id);
foreach($shipments as $shipment){
$sql = 'SELECT * FROM ' . $sales_flat_shipment_track . ' WHERE parent_id = ?';
$tracking = $connection->fetchAll($sql, $shipment['entity_id']);
echo "Tracking number(s) for the order:<br/>";
foreach ($tracking as $track){
echo $track['track_number'] . "<br/>";
}
$sql = 'SELECT * FROM ' . $sales_flat_shipment_item . ' WHERE parent_id = ?';
$items = $connection->fetchAll($sql, $shipment['entity_id']);
echo "Product(s) on shipment:<br/>";
foreach ($items as $item){
echo $item['name'] . "<br/>";
}
}
public function _getConnection($type = 'core_read'){
return Mage::getSingleton('core/resource')->getConnection($type);
}
public function _getTableName($tableName){
return Mage::getSingleton('core/resource')->getTableName($tableName);
}
If you have the $orderItem
, you can easily get all the ShipmentItems:
$shipmentItems = Mage::getResourceModel('sales/order_shipment_item_collection')
->addFieldToFilter('order_item_id', $orderItem->getId());
foreach ($shipmentItems as $shipment_item) {
if ($shipment_id = $shipment_item->getParentId()) {
$shipment = Mage::getModel('sales/order_shipment')->load($shipment_id);
}
}
if this doesn't work, you need to load the shipment based on the $item->getParentId()
Best Answer
First you need to load the shipment:
If you're using the increment id, you'll have to use:
Once you have the shipment loaded, you can retrieve the items collection:
Finally to get the product from the items you can loop through the item collections: