Magento 2 : How to create invoice programatically?

Our team has been busy doing integration with JDA (formerly RedPrairie) from last few months. You might know it is quite popular warehouse management system (WMS) which allows you to sync catalog and transaction data between both Magento 2 and JDA systems.

As part of the JDA integration, we were fetching order status data back from JDA and creating invoice in Magento 2 programatically.

We did our research and managed to find the best of way of achieving this so we thought we should follow with our Magento 2 Developers.

Let’s crack on with the implementation, here is the Model class which allows you to create invoice automatically in Magento 2 -:

<?php

/**
 * @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;
}

/**
 * @param int $orderId
 * @return \Magento\Sales\Model\Invoice $invoice
 */
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())
        );
    }
}

There are two main functions prepareInvoice of \Magento\Sales\Model\Service\InvoiceService class which prepare invoice and addObject of \Magento\Framework\DB\TransactionFactory class which helps to create invoice and associate the invoice with original order in Magento 2.

That’s it, Hope this article helped you in some way. Please leave us your comment and let us know what do you think? Thanks.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.