0

for creating an invoice normally you have to open the order an create the invoice for that one order.

But is it possible to select more than one order in the overview grid and create the invoices for the selected orders in one mass action. Like you can do for e.g. printing invoices?

Or do we have to use an extension for such a mass action? Can you recommend any extension for that problem?

2 Answers 2

1

Since there's still no default way in Magento 2.2.x to accomplish this, I've created a basic mass action that will create an invoice for each selected order, which:

  • Will be set to "Capture offline"
  • Change the order status to "Processing"
  • (Optional) Sends out the invoice e-mail (see commented code)

Of course this can also be extended upon to meet your wishes.

Assuming that you know how to create a custom module (Remember to change all instances of Vendor and Module with your own module details):

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="vendor_module_mass_invoice">
                <argument name="data" xsi:type="array">
                    <item name="config" xsi:type="array">
                        <item name="type" xsi:type="string">vendor_module_mass_invoice</item>
                        <item name="label" xsi:type="string" translate="true">Invoice</item>
                        <item name="url" xsi:type="url" path="myroute/order/massInvoice"/>                            
                    </item>
                </argument>
            </action>
        </massaction>
    </listingToolbar>
</listing>

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="myroute" frontName="myroute">
            <module name="Vendor_Module" />
        </route>
    </router>
</config>

**Vendor\Module\Controller\Adminhtml\Order\MassInvoice.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\Model\Order\Email\Sender\InvoiceSender;
use Magento\Sales\Model\Order\Invoice;
use Magento\Sales\Model\Order;

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

    /**
     * @var InvoiceSender
     */
    protected $_invoiceSender;

    /**
     * @var object
     */
    protected $collectionFactory;

    public function __construct(
        Context $context, 
        Filter $filter, 
        CollectionFactory $collectionFactory,
        InvoiceSender $invoiceSender    
    ) {
        parent::__construct($context, $filter); 
        $this->collectionFactory = $collectionFactory;
        $this->_invoiceSender = $invoiceSender;    
    }

    protected function massAction(AbstractCollection $collection) {

        $countInvoice = 0;

        foreach ($collection->getItems() as $order) {

            // Check if order can be invoiced
            if (!$order->canInvoice()) {
                $this->messageManager->addError(__('Cannot create invoice for order %1', $order->getIncrementId()));
                continue;
            }

            try {

                $invoice = $order->prepareInvoice();
                $invoice->getOrder()->setIsInProcess(true);

                // Offline only
                $invoice->setRequestedCaptureCase(Invoice::CAPTURE_OFFLINE);

                // Save & set paid
                $invoice->register()->pay();
                $invoice->save();

                // Uncomment if you also want to send an e-mail
                //$this->_invoiceSender->send($invoice);

                // Change order status
                $order->setState(Order::STATE_PROCESSING)->setStatus(Order::STATE_PROCESSING);
                $order->save();

                $countInvoice++;

            } catch (\Exception $e) {
                $this->messageManager->addError(__('Error creating invoice for order %1', $order->getIncrementId()));
            }
        }    

        if ($countInvoice) {
            $this->messageManager->addSuccess(__('Created invoice for %1 order(s)', $countInvoice));
        }

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

Be sure to run php bin/magento cache:clean after making these changes to your module. You should now have an "Invoice" option available in your order grid. This text can be changed in sales_order_grid.xml if you so desire.

1
  • It added shipping charges on the first order in invoice, ignore shipping charges for other orders in bulk orders Commented Jan 31, 2019 at 10:14
0

You have 2 options:

  1. Make a script to create invoices programmaticaly (http://inchoo.net/magento/how-to-create-magento-invoice-from-order/)

  2. Buy a extension with massaction invoice (http://www.magentocommerce.com/magento-connect/mass-order-actions-by-amasty.html)

I recommend you this extensions. Works fine!

1
  • Neither of these answer the op. Commented Sep 22, 2016 at 16:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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