Magento 2: How to Automatically Create Invoice from Order Observer
As pointed out, the answer to this is that I was using the wrong event. With the event sales_order_save_after
the order hasn't been committed to the Database yet.
I changed my event to fire on checkout_submit_all_after
and my observer is now working.
Automatically Create Invoice after place the order from Order Observer using event checkout_submit_all_after
. Follow below file path to create custom module and makes auto invoice after place order.
File path: magento/app/code/Vendor/AutoInvoice/registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Vendor_AutoInvoice',
__DIR__
);
File path: magento/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="2.1.0" />
</config>
File path: magento/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="checkout_submit_all_after">
<observer name="vendor_checkout_submit_all_after" instance="Vendor\AutoInvoice\Observer\OrderObserver" />
</event>
</config>
File path: magento/app/code/Vendor/AutoInvoice/Observer/OrderObserver.php
<?php
namespace Vendor\AutoInvoice\Observer;
use Magento\Framework\Event\ObserverInterface;
class OrderObserver implements ObserverInterface
{
/**
* @var \Magento\Sales\Model\ResourceModel\Order\Invoice\CollectionFactory
*/
protected $_invoiceCollectionFactory;
/**
* @var \Magento\Sales\Api\InvoiceRepositoryInterface
*/
protected $_invoiceRepository;
/**
* @var \Magento\Sales\Model\Service\InvoiceService
*/
protected $_invoiceService;
/**
* @var \Magento\Framework\DB\TransactionFactory
*/
protected $_transactionFactory;
/**
* @var \Magento\Sales\Api\OrderRepositoryInterface
*/
protected $_orderRepository;
/**
* @param \Magento\Sales\Model\ResourceModel\Order\Invoice\CollectionFactory $invoiceCollectionFactory
* @param \Magento\Sales\Model\Service\InvoiceService $invoiceService
* @param \Magento\Framework\DB\TransactionFactory $transactionFactory
* @param \Magento\Sales\Api\InvoiceRepositoryInterface $invoiceRepository
* @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
*/
public function __construct(
\Magento\Sales\Model\ResourceModel\Order\Invoice\CollectionFactory $invoiceCollectionFactory,
\Magento\Sales\Model\Service\InvoiceService $invoiceService,
\Magento\Framework\DB\TransactionFactory $transactionFactory,
\Magento\Sales\Api\InvoiceRepositoryInterface $invoiceRepository,
\Magento\Sales\Api\OrderRepositoryInterface $orderRepository
) {
$this->_invoiceCollectionFactory = $invoiceCollectionFactory;
$this->_invoiceService = $invoiceService;
$this->_transactionFactory = $transactionFactory;
$this->_invoiceRepository = $invoiceRepository;
$this->_orderRepository = $orderRepository;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$orderId = $observer->getEvent()->getOrder()->getId();
$this->createInvoice($orderId);
}
protected function createInvoice($orderId)
{
try
{
$order = $this->_orderRepository->get($orderId);
if ($order)
{
$invoices = $this->_invoiceCollectionFactory->create()
->addAttributeToFilter('order_id', array('eq' => $order->getId()));
$invoices->getSelect()->limit(1);
if ((int)$invoices->count() !== 0) {
$invoices = $invoices->getFirstItem();
$invoice = $this->_invoiceRepository->get($invoices->getId());
return $invoice;
}
if(!$order->canInvoice()) {
return null;
}
$invoice = $this->_invoiceService->prepareInvoice($order);
$invoice->setRequestedCaptureCase(\Magento\Sales\Model\Order\Invoice::CAPTURE_ONLINE);
$invoice->register();
$invoice->getOrder()->setCustomerNoteNotify(false);
$invoice->getOrder()->setIsInProcess(true);
$order->addStatusHistoryComment(__('Automatically INVOICED'), false);
$transactionSave = $this->_transactionFactory->create()->addObject($invoice)->addObject($invoice->getOrder());
$transactionSave->save();
return $invoice;
}
} catch (\Exception $e) {
throw new \Magento\Framework\Exception\LocalizedException(
__($e->getMessage())
);
}
}
}