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.

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

<?php
/**
* @var \Magento\Sales\Model\Order\Shipment\TrackFactory
*/
protected $_shipmentTrackFactory;

/**
* @var \Magento\Sales\Model\Order\ShipmentFactory
*/
protected $_shipmentFactory;

/**
 * @var \Magento\Framework\DB\TransactionFactory
 */
protected $_transactionFactory;

/**
* @var \Magento\Sales\Api\OrderRepositoryInterface
*/
protected $_orderRepository;

/**
* @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
    ) {
      $this->_shipmentTrackFactory = $shipmentTrackFactory;
      $this->_shipmentFactory = $shipmentFactory;
      $this->_transactionFactory = $transactionFactory;
      $this->_orderRepository = $orderRepository;
}

/**
 * @param int $orderId
 * @param string $trackingNumber
 * @return \Magento\Sales\Model\Shipment $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 \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;
}

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.

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.

Scommerce

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.