3

I have found mass Invoice in the following link,

How to create invoices for more than one order via mass action?

Similarly, how to create shipment for more than one order via mass action drop down ?

  • Hi, Will it support Magento 2.1.7 version? Because I am getting the following error. a:4:{i:0;s:172:"Invalid XML in file demo/app/code/Ship/ordermass/etc/adminhtml/routes.xml: Premature end of data in tag config line 2 <?xml version="1.0"?> <config xmlns:xsi="w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> <router id="admin"> <route id="ordermass" frontName="ordermass"> <module name="Ship_ordermass" /> </route> </router> – user2618314 Jan 30 at 8:31
  • Hi, Its fixed now, I have changed the routeid and frontName as ship_ordermass. Its working as expected. Thank you Hasham. – user2618314 Jan 30 at 9:26
1

First Made the ui component in your module

app\code\Vendor\Module\view\adminhtml\ui_component\sales_order_grid.xml

<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<listingToolbar name="listing_top">
        <massaction name="listing_massaction">
        <action name="order_ship">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="type" xsi:type="string">order_ship_mass</item>
                        <item name="label" xsi:type="string" translate="true">Ship</item>
                        <item name="url" xsi:type="url" path="ordermass/order/massShip"/>
                        <item name="confirm" xsi:type="array">
                            <item name="title" xsi:type="string" translate="true">Ship</item>
                            <item name="message" xsi:type="string" translate="true">Are you sure you want to create shipment for selected items?</item>
                        </item>
                    </item>
                </argument>
            </action>
            </massaction>
</listingToolbar>
</listing>

Then added route file in your module

app\code\Vendor\Module\etc\adminhtml\routes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
    <route id="ordermass" frontName="ordermass">
        <module name="Vendor_Module" />
    </route>
</router>

After that add Mass Ship Adminhtml Controller in your module

app\code\Vendor\Module\Controller\Adminhtml\Order\MassShip.php

<?php
namespace Vendor\Module\Controller\Adminhtml\Order;

use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
use Magento\Backend\App\Action\Context;
use Magento\Ui\Component\MassAction\Filter;
use Magento\Sales\Model\ResourceModel\Order\CollectionFactory;
use Magento\Sales\Api\OrderManagementInterface;

class MassShip extends \Magento\Sales\Controller\Adminhtml\Order\AbstractMassAction
{

    protected $orderManagement;

    public function __construct(
        Context $context,
        Filter $filter,
        CollectionFactory $collectionFactory,
        OrderManagementInterface $orderManagement,
        \Magento\Backend\Model\Auth\Session $authSession

    ) {
        parent::__construct($context, $filter);
        $this->authSession = $authSession;
        $this->collectionFactory = $collectionFactory;
        $this->orderManagement = $orderManagement;
    }

    protected function massAction(AbstractCollection $collection)
    {
        $countShipOrder = 0; $NonShipOrdernuumbers = '';
        $model = $this->_objectManager->create('Magento\Sales\Model\Order');

        $username = $this->authSession->getUser()->getUsername();
        $appendusername = "(".$username.")";

        foreach ($collection->getItems() as $order) {
            if (!$order->getEntityId()) {
                continue;
            }
            $loadedOrder = $model->load($order->getEntityId());

            if($loadedOrder->canShip()) {


            $convertOrder = $this->_objectManager->create('Magento\Sales\Model\Convert\Order');
            $shipment = $convertOrder->toShipment($loadedOrder);

            // Loop through order items
            foreach ($order->getAllItems() AS $orderItem) {
                // Check if order item has qty to ship or is virtual
                if (! $orderItem->getQtyToShip() || $orderItem->getIsVirtual()) {
                    continue;
                }
                $qtyShipped = $orderItem->getQtyToShip();
                // Create shipment item with qty
                $shipmentItem = $convertOrder->itemToShipmentItem($orderItem)->setQty($qtyShipped);
                // Add shipment item to shipment
                $shipment->addItem($shipmentItem);
            }

            // Register shipment
            $shipment->register();
            $shipment->getOrder()->setIsInProcess(true);

            try {
                // Save created shipment and order
                $shipment->save();
                $shipment->getOrder()->save();
                //send notification code
                $loadedOrder->addStatusHistoryComment(
                __('Notified customer about shipment #%1. '.$appendusername, $shipment->getId())
                )->setIsCustomerNotified(false)->save();

                $itemsCheck = $loadedOrder->getItemsCollection()->addAttributeToSelect('*')->load();
                foreach ($itemsCheck as $item) {
                    if (! $item->getQtyToShip() || $item->getIsVirtual()) { 
                    continue;
                    }
                    $item->setQtyShipped($item->getQtyToShip());
                    $item->save();
                    $Norder = $shipment->getOrder()->load( $shipment->getOrder()->getId() );
                    $Norder->save();
                }

                // Send email
                $this->_objectManager->create('Magento\Shipping\Model\ShipmentNotifier')
                    ->notify($shipment);

                $shipment->save();
            } catch (\Exception $e) {
                $this->messageManager->addError(__($e->getMessage()));
            }

            if ($loadedOrder->canInvoice()) {
            $loadedOrder->setState(\Magento\Sales\Model\Order::STATE_PROCESSING, true);
            $loadedOrder->setStatus('shipped');
            $loadedOrder->addStatusToHistory('shipped', 'Order status set to shipped using Mass Ship action. '.$appendusername);
            $loadedOrder->save();
            }

            $countShipOrder++;
            }
            else {
                if (empty($NonShipOrdernuumbers)){
                $NonShipOrdernuumbers = $NonShipOrdernuumbers.$loadedOrder->getIncrementId();
                }
                else{
                $NonShipOrdernuumbers = $NonShipOrdernuumbers.", ".$loadedOrder->getIncrementId();  
                }
            }
        }
        $countNonShipOrder = $collection->count() - $countShipOrder;

        if ($countNonShipOrder && $countShipOrder) {
            $this->messageManager->addSuccess(__('%1 order(s) Shipment created successfully.', $countShipOrder));
            $this->messageManager->addError(__('Shipment already created for %1 order(s).', $NonShipOrdernuumbers));
        } elseif ($countNonShipOrder) {
            $this->messageManager->addError(__('Shipment already created for %1 order(s).', $NonShipOrdernuumbers));
        }

        if ($countShipOrder) {
            $this->messageManager->addSuccess(__('%1 order(s) Shipment created successfully.', $countShipOrder));
        }

        $resultRedirect = $this->resultRedirectFactory->create();
        $resultRedirect->setPath($this->getComponentRefererUrl());
        return $resultRedirect;
    }
}

I wrote this code, I already tested this code. If you still find any difficulty then please tell me on comment section

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.