Magento 2 : How to create shipment programatically?

Create shipment programatically
Today we are going to cover how to create shipment and adding tracking information programatically in Magento 2. This could help if you are creating shipment in Magento 2 from your ERP or WMS or any third party systems.

As usual we did our research and managed to find the best of way of achieving this so we thought we should follow with our Magento 2 Developers.

Let’s crack on with creating shipment model class to create shipment in Magento 2 along with tracking number-:

<?php
/**
* @var MagentoSalesModelOrderShipmentTrackFactory
*/
protected $_shipmentTrackFactory; /**
* @var MagentoSalesModelOrderShipmentFactory
*/
protected $_shipmentFactory; /** * @var MagentoFrameworkDBTransactionFactory */
protected $_transactionFactory; /**
* @var MagentoSalesApiOrderRepositoryInterface
*/
protected $_orderRepository; /**
* @param MagentoSalesModelOrderShipmentTrackFactory $shipmentTrackFactory
* @param MagentoSalesModelOrderShipmentFactory $shipmentFactory
* @param MagentoFrameworkDBTransactionFactory $transactionFactory
* @param MagentoSalesApiOrderRepositoryInterface $orderRepository
*/
public function __construct( MagentoSalesModelOrderShipmentTrackFactory $shipmentTrackFactory, MagentoSalesModelOrderShipmentFactory $shipmentFactory, MagentoFrameworkDBTransactionFactory $transactionFactory, MagentoSalesApiOrderRepositoryInterface $orderRepository ) { $this->_shipmentTrackFactory = $shipmentTrackFactory; $this->_shipmentFactory = $shipmentFactory; $this->_transactionFactory = $transactionFactory; $this->_orderRepository = $orderRepository;
} /** * @param int $orderId * @param string $trackingNumber * @return MagentoSalesModelShipment $shipment */
protected function createShipment($orderId, $trackingNumber)
{ try { $order = $this->_orderRepository->get($orderId); if ($order){ $data = array(array( 'carrier_code' => $order->getShippingMethod(), 'title' => $order->getShippingDescription(), 'number' => $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(); } return $shipment; } } catch (Exception $e) { throw new MagentoFrameworkExceptionLocalizedException( __($e->getMessage()) ); }
} /**
* @param $order MagentoSalesModelOrder
* @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 MagentoSalesModelOrder
* @return array
*/
protected function prepareShipmentItems($order)
{ $items = []; foreach($order->getAllItems() as $item) { $items[$item->getItemId()] = $item->getQtyOrdered(); } return $items;
}

There are two main functions prepareShipment of MagentoSalesModelOrderShipmentFactory class which prepare shipment and addObject of MagentoFrameworkDBTransactionFactory class which helps to create shipment and associate the shipment with original order in Magento 2.
That’s it, Hope this article helped you in some way. Please leave us your comment and let us know what do you think? Thanks.