2

I'm looking for plugin that send invoice automatically when order is in status completed.

0

1 Answer 1

2

I can't point you towards any existing modules. But if you're up to it, you could fairly easily implement this yourself by adding an Observer to the sales_order_save_after event.

Note that this code assumes that you've already created the invoice (either automatically or manually), and that it hasn't been emailed before.

app/code/Vendor/AutoInvoice/registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_AutoInvoice',
    __DIR__
);

app/code/Vendor/AutoInvoice/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_AutoInvoice" setup_version="1.0.0"/>
</config>

app/code/Vendor/AutoInvoice/etc/events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name='sales_order_save_after'>
        <observer name='vendor_autoinvoice_send_invoice' instance='Vendor\AutoInvoice\Model\Observer\AutoInvoice'
        />
    </event>
</config>

app\code\Vendor\AutoInvoice\Model\Observer\AutoInvoice.php

<?php

namespace Vendor\AutoInvoice\Model\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Email\Sender\InvoiceSender;

class AutoInvoice implements ObserverInterface
{
    protected $_invoiceSender;

    public function __construct(
        InvoiceSender $invoiceSender
    ) {
        $this->_invoiceSender = $invoiceSender;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $order = $observer->getEvent()->getOrder();
        if (!$order) {
            // Dont send invoice if order is not provided 
            return; 
        }

        if($order->getState() == Order::STATE_COMPLETE) {

            $invoices = $order->getInvoiceCollection();

            foreach ($invoices as $invoice) {

                if (!$invoice->getEmailSent()) {
                    try {
                        $this->_invoiceSender->send($invoice);
                    } catch (\Exception $e) {
                        // Do something if failed to send                          
                    }
                }

            }               

        }
    }
}

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