We just need to pass order id in generateShipment($orderId) function from template.
below code snippet is used for generating Shipment in Magento 2, After generating Shipment automatically send the Shipment mail to a customer who has placed the order.
<?php namespace Rbj\Shipment\Block; class Shipment extends \Magento\Framework\View\Element\Template { public function __construct( \Magento\Framework\View\Element\Template\Context $context, \Magento\Sales\Api\OrderRepositoryInterface $orderRepository, \Magento\Sales\Model\Convert\OrderFactory $convertOrderFactory, \Magento\Framework\DB\TransactionFactory $transactionFactory, \Magento\Sales\Model\Order\Email\Sender\ShipmentSender $shipmentSender, \Magento\Framework\Message\ManagerInterface $messageManager, array $data = [] ) { $this->orderRepository = $orderRepository; $this->orderConverter = $convertOrderFactory->create(); $this->transactionFactory = $transactionFactory; $this->messageManager = $messageManager; $this->shipmentSender = $shipmentSender; parent::__construct($context, $data); } /** * Create Shipment Based on Order Object * @param \Magento\Sales\Model\Order $order * @return $this */ public function generateShipment($orderId) { try { $order = $this->orderRepository->get($orderId); if (!$order->getId()) { throw new \Magento\Framework\Exception\LocalizedException(__('The order no longer exists.')); } /* check shipment exist for order or not */ if ($order->canShip()) { // Initialize the order shipment object $shipment = $this->orderConverter->toShipment($order); foreach ($order->getAllItems() AS $orderItem) { // Check if order item has qty to ship or is order is virtual if (! $orderItem->getQtyToShip() || $orderItem->getIsVirtual()) { continue; } $qtyShipped = $orderItem->getQtyToShip(); // Create shipment item with qty $shipmentItem = $this->orderConverter->itemToShipmentItem($orderItem)->setQty($qtyShipped); // Add shipment item to shipment $shipment->addItem($shipmentItem); } // Register shipment $shipment->register(); $shipment->getOrder()->setIsInProcess(true); try { $transaction = $this->transactionFactory->create()->addObject($shipment) ->addObject($shipment->getOrder()) ->save(); echo $shipmentId = $shipment->getIncrementId(); } catch (\Exception $e) { $this->messageManager->addError(__('We can\'t generate shipment.')); } if ($shipment) { try { $this->shipmentSender->send($shipment); } catch (\Exception $e) { $this->messageManager->addError(__('We can\'t send the shipment right now.')); } } return $shipmentId; } } catch (\Exception $e) { $this->messageManager->addError($e->getMessage()); } return true; }
Call function from the template,
$orderId = 1; $shipment = $block->generateInvoice($orderId);
Now Check from Admin panel.
Sales -> Order, Order with Id 1 has generated Shipment.
Thank you rakesh, but i got the below error :
Fatal error: Uncaught Exception: User Error: Some transactions have not been committed or rolled back in /public_html/vendor/magento/framework/DB/Adapter/Pdo/Mysql.php on line 3769 in /public_html/vendor/magento/framework/App/ErrorHandler.php:61 Stack trace: #0 [internal function]: MagentoFrameworkAppErrorHandler->handler(256, ‘Some transactio…’, ‘/home/…’, 3769, Array) #1 /public_html/vendor/magento/framework/DB/Adapter/Pdo/Mysql.php(3769): trigger_error(‘Some transactio…’, 256) #2 [internal function]: MagentoFrameworkDBAdapterPdoMysql->__destruct() #3 {main} thrown in /public_html/vendor/magento/framework/App/ErrorHandler.php on line 61
And how to select sourceCode for shipment? We have multiple source for all websites. I have setup static sorucecode like below.
$shipment->getExtensionAttributes()->setSourceCode('default');
How to get SourceCode from Order object?This extension generates the shipment automatically on order creation
https://webpanda-solutions.com/auto-invoice-shipment.html