i am trying to get tracking from csv and save to magento 2 order programmatically. i grabbed the create shipment & add tracking code from here https://www.scommerce-mage.com/blog/magento-2-how-to-create-shipment-programatically.html, and add an execute function (line 142) to load data from csv. but i'm not sure how to create an shipment object (line 179).
<?php
$file = fopen('track.csv', 'r', '"'); // set path to the CSV file
if ($file !== false)
{
require __DIR__ . '/app/bootstrap.php';
$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$state = $objectManager->get('Magento\Framework\App\State');
$state->setAreaCode('adminhtml');
// add logging capability
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/import-update.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
class ShipmentObject{
/*There are two main functions
prepareShipment of \Magento\Sales\Model\Order\ShipmentFactory class which prepare invoice and
addObject of \Magento\Framework\DB\TransactionFactory class which helps to create shipment and associate the shipment with original order in Magento 2.
*/
/**
* @var \Magento\Sales\Model\Order\Shipment\TrackFactory
*/
protected $_shipmentTrackFactory;
/**
* The ShipmentFactory is used to create a new Shipment.
*
* @var \Magento\Sales\Model\Order\ShipmentFactory
*/
protected $_shipmentFactory;
/**
* @var \Magento\Framework\DB\TransactionFactory
*/
protected $_transactionFactory;
/**
* @var \Magento\Sales\Api\OrderRepositoryInterface
*/
protected $_orderRepository;
protected $_file;
/**
* @param \Magento\Sales\Model\Order\Shipment\TrackFactory $shipmentTrackFactory
* @param \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory
* @param \Magento\Framework\DB\TransactionFactory $transactionFactory
* @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
*/
public function __construct(
\Magento\Sales\Model\Order\Shipment\TrackFactory $shipmentTrackFactory,
\Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory,
\Magento\Framework\DB\TransactionFactory $transactionFactory,
\Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
\Magento\Sales\Model\OrderFactory $orderFactory
) {
$this->_shipmentTrackFactory = $shipmentTrackFactory;
$this->_shipmentFactory = $shipmentFactory;
$this->_transactionFactory = $transactionFactory;
$this->_orderRepository = $orderRepository;
$this->orderFactory = $orderFactory;
}
/**
* @param int $orderId
* @param string $trackingNumber
* @return \Magento\Sales\Model\Shipment $shipment
*/
protected function createShipment($orderId, $trackingNumber)
{
try {
//$order = $this->_orderRepository->get($orderId); // this is increment id
$order = $this->orderFactory->create()->loadByIncrementId($orderId);
if ($order){
$data = array(array(
'carrier_code' => 'fedex', //$order->getShippingMethod(), //'carrier_code' => 'fedex', // need to lower case
'title' => 'Federal Express', //$order->getShippingDescription(), //'title' => 'Federal Express', // how to set here 'Federal Express' or 'United Parcel Service'
'number' => $trackingNumber, //$trackingnumber,
));
$shipment = $this->prepareShipment($order, $data);
/*
if ($shipment) {
$order->setIsInProcess(true);
$order->addStatusHistoryComment('Automatically SHIPPED', false);
$transactionSave = $this->_transactionFactory->create()->addObject($shipment)->addObject($shipment->getOrder());
$transactionSave->save();
}
*/
if ($shipment) {
$order->setIsInProcess(true);
$order->addStatusHistoryComment('Automatically SHIPPED', false);
$transactionSave = $this->_transactionFactory->create();
$transactionSave->addObject($shipment);
$transactionSave->addObject($shipment->getOrder());
$transactionSave->save();
}
//return $shipment; //original
//return $shipment->save(); //magefms
return $order; //helgeB
}
} catch (\Exception $e) {
throw new \Magento\Framework\Exception\LocalizedException(
__($e->getMessage())
);
}
}
/**
* @param $order \Magento\Sales\Model\Order
* @param $track array
* @return $this
*/
protected function prepareShipment($order, $track)
{
$shipment = $this->_shipmentFactory->create(
$order,
$this->prepareShipmentItems($order),
$track
);
return $shipment->getTotalQty() ? $shipment->register() : false;
}
/**
* @param $order \Magento\Sales\Model\Order
* @return array
*/
protected function prepareShipmentItems($order)
{
$items = [];
foreach($order->getAllItems() as $item) {
$items[$item->getItemId()] = $item->getQtyOrdered();
}
return $items;
}
//after prepareShipmentItems function
/**
* @param $file
*/
public function setFile($file)
{
$this->_file = $file;
}
/**
* @param null
* @return ordersave
*/
public function execute()
{
// enter the number of data fields you require the product row inside the CSV file to contain
$required_data_fields = 3; //number of column in csv
//$header = fgetcsv($file); // get data headers and skip 1st row
while (($row = fgetcsv($this->_file, 100, ",")) !== FALSE)
//while (($row = fgetcsv($file, 100, ",")) !== FALSE)
//while ( $row = fgetcsv($file, 100, ",") )
//while (($row = fgetcsv($file)) !== FALSE)
{
$data_count = count($row);
if ($data_count < 1) {
continue;
}
$data = array();
//$data = array_combine($header, $row);
$data = array($row);
$ponumber = $row[0]; //$data['ponumber']; // column A
if ($data_count < $required_data_fields) {
$logger->info("Skipping Order Number " . $ponumber . ". Not enough data to import.");
continue;
}
//$shipvia = trim($data[1]); //trim($data['shipvia']); // column B
//$trackingnumber = trim($data[2]);//trim($data['trackingnumber']); // column C
$shipvia = isset($row[1]) ? $row[1] : null;
$trackingnumber = isset($row[2]) ? $row[2] : null;
switch ($shipvia) {
case "FEDEX":
$shipvia = "fedex";
break;
case "UPS":
$shipvia = "ups";
break;
case "USPS":
$shipvia = "usps";
break;
default:
$shipvia = "fedex";
}
///////////////////////////////start adding tracking///////////////////////////////
echo 'Updating Order: '.$ponumber.', with '.$shipvia.':'.$trackingnumber."\r\n";
//print_r($row);
$order = $this->createShipment($ponumber, $trackingnumber); /* @param int $orderId@param | @param string $trackingNumber */
if ($order){ //HelgeB
$order->save();
}
///////////////////////////////end of adding tracking///////////////////////////////
//magefms return $order->save();
}// end of while loop
}//end of execute function
} // end of class shipmentobject
/**
* @param \Magento\Sales\Model\Order\Shipment\TrackFactory $shipmentTrackFactory
* @param \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory
* @param \Magento\Framework\DB\TransactionFactory $transactionFactory
* @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
*/
$shipmentTrackFactory = $objectManager->get('\Magento\Sales\Model\Order\Shipment\TrackFactory');
$shipmentFactory = $objectManager->get('\Magento\Sales\Model\Order\ShipmentFactory');
$transactionFactory = $objectManager->get('\Magento\Framework\DB\TransactionFactory');
$orderRepository = $objectManager->get('\Magento\Sales\Api\OrderRepositoryInterface');
$orderFactory = $objectManager->get('\Magento\Sales\Model\OrderFactory');
//create new class object
$test = new ShipmentObject($shipmentTrackFactory,$shipmentFactory,$transactionFactory,$orderRepository,$orderFactory);
$test->setFile($file);
$test->execute();
fclose($file);
}// if file not exist, then do nothing
new error tracking information does not copy to (shipment tab) "sales_shipment_grid"
it is showing like this in admin panel, the shipment tab is empty, though the tracking is in there with no carrier assign.