Read More
Read More
Menu Close

    How to programmatically create invoice in magento2

    If want to programmatically create invoice for an order then solution is here you can learn here how to create a invoice for an order or a part of your order.

    Create invoice for a new order-

    <?php
    /**
     * Webkul Software.
     *
     * @category  Webkul
     * @package   Webkul_Grid
     * @author    Webkul
     * @copyright Copyright (c) 2010-2016 Webkul Software Private Limited (https://webkul.com)
     * @license   https://store.webkul.com/license.html
     */
    
    namespace Webkul\Grid\Controller;
    
    class CreateInvoice extends Magento\Framework\App\Action\Action
    {
        /**
         * @var \Magento\Sales\Api\OrderRepositoryInterface
         */
        protected $_orderRepository;
    
        /**
         * @var \Magento\Sales\Model\Service\InvoiceService
         */
        protected $_invoiceService;
    
        /**
         * @var \Magento\Framework\DB\Transaction
         */
        protected $_transaction;
    
        public function __construct(
            \Magento\Framework\App\Action\Context $context,
            \Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
            \Magento\Sales\Model\Service\InvoiceService $invoiceService,
            \Magento\Framework\DB\Transaction $transaction
        ) {
            $this->_orderRepository = $orderRepository;
            $this->_invoiceService = $invoiceService;
            $this->_transaction = $transaction;
            parent::__construct($context);
        }
        /**
         * Marketplace order invoice controller.
         *
         * @return \Magento\Framework\View\Result\Page
         */
        public function execute()
        {
            $orderId = 1; //order id for which want to create invoice
            $order = $this->_orderRepository->get($orderId);
            if($order->canInvoice()) {
                $invoice = $this->_invoiceService->prepareInvoice($order);
                $invoice->register();
                $invoice->save();
                $transactionSave = $this->_transaction->addObject(
                    $invoice
                )->addObject(
                    $invoice->getOrder()
                );
                $transactionSave->save();
                $this->invoiceSender->send($invoice);
                //send notification code
                $order->addStatusHistoryComment(
                    __('Notified customer about invoice #%1.', $invoice->getId())
                )
                ->setIsCustomerNotified(true)
                ->save();
            }
        }
    }
    

    Create invoice for a part of order

    <?php
    /**
     * Webkul Software.
     *
     * @category  Webkul
     * @package   Webkul_Grid
     * @author    Webkul
     * @copyright Copyright (c) 2010-2016 Webkul Software Private Limited (https://webkul.com)
     * @license   https://store.webkul.com/license.html
     */
    
    namespace Webkul\Grid\Controller;
    
    class CreateInvoice extends Magento\Framework\App\Action\Action
    {
        /**
         * @var \Magento\Sales\Api\OrderRepositoryInterface
         */
        protected $_orderRepository;
    
        /**
         * @var \Magento\Sales\Model\Service\InvoiceService
         */
        protected $_invoiceService;
    
        /**
         * @var \Magento\Framework\DB\Transaction
         */
        protected $_transaction;
    
        public function __construct(
            \Magento\Framework\App\Action\Context $context,
            \Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
            \Magento\Sales\Model\Service\InvoiceService $invoiceService,
            \Magento\Framework\DB\Transaction $transaction
        ) {
            $this->_orderRepository = $orderRepository;
            $this->_invoiceService = $invoiceService;
            $this->_transaction = $transaction;
            parent::__construct($context);
        }
        /**
         * Marketplace order invoice controller.
         *
         * @return \Magento\Framework\View\Result\Page
         */
        public function execute()
        {
            $orderId = 1; //order id for which want to create invoice
            $order = $this->_orderRepository->get($orderId);
            if($order->canInvoice()) {
                $itemsArray = ['80'=>2]; //here 80 is order item id and 2 is it's quantity to be invoice
                $shippingAmount = '10.00';
                $subTotal = '110.00';
                $baseSubtotal = '110.00';
                $grandTotal = '110.00';
                $baseGrandTotal = '110.00';
                $invoice = $this->_invoiceService->prepareInvoice($order, $itemsArray);
                $invoice->setShippingAmount($shippingAmount);
                $invoice->setSubtotal($subTotal);
                $invoice->setBaseSubtotal($baseSubtotal);
                $invoice->setGrandTotal($grandTotal);
                $invoice->setBaseGrandTotal($baseGrandTotal);
                $invoice->register();
                $transactionSave = $this->_transaction->addObject(
                    $invoice
                )->addObject(
                    $invoice->getOrder()
                );
                $transactionSave->save();
                $this->invoiceSender->send($invoice);   
                //send notification code
                $order->addStatusHistoryComment(
                    __('Notified customer about invoice #%1.', $invoice->getId())
                )
                ->setIsCustomerNotified(true)
                ->save();
            }
        }
    }
    

    In this way you can create invoice for a particular product in a order or for a complete order. After creation of the invoice you can check it in admin panel sales order grid.

    Searching for an experienced
    Magento 2 Company ?
    Read More
    . . .
    Discuss on Helpdesk

    Leave a Comment

    Your email address will not be published. Required fields are marked*


    12 comments

  • Mujahidh Haseem
    Thanks for the great article, this help me lot.
    • Hari Narayan Bairwa (Moderator)
      Thanks for your Appreciation. Further, if you have any other query then feel free to contact us at [email protected]
  • Er Mohit Řajput
    HI,

    This is working fine. I am creating invoice using ajax request.
    I am using try catch in my controller.
    But I am having problem with this code :
    $this->invoiceSender->send($invoice);

    When I removed this code ajax response in successful. Please suggest.

    • Webkul Support
      Hi There,
      Sure we will try to add the blog in future for the topic asked. Thanks
  • Srinivasan P
    Hi,

    We are working on warehouse management integration for our client.

    While we receive order updates from warehouse, we are doing the following activities:
    1. invoice creation
    2. capture invoice amount that was authorized during order placement
    3. create shipment
    4. send notification email
    5. order cancellation (if applicable)
    6. create credit memo (if applicable, while cancelling invoices)

    We have to do this process in a loop, for each order updates that we receive.

    While doing this process for n number of orders, the script always process the 1st order on the collection.
    When it tries to process for the 2nd order, we are getting the below error:

    “set order for existing transactions not allowed”

    Could you please highlight the cause for this error and solution to fix this error.

  • Rea Zack
    HI,

    I tried the same solution for partial invoice but when i checked from sales_order_item table it shows other products as well. and when i open invoice from admin it does’t shows the invoice items. It shows blank under invoice items

    • Manish Mishra
      I am also facing the same issue. Can anyone help us on the same?
  • Franck
    Thanks for this. A couple questions:
    1. Why, in the first example, you save the invoice twice ? first with the $invoice->save() statement, then with the $transactionSave
    2. Is there a point to setting the isInProcess flag on the Order before saving it ? $invoice->getOrder()->setIsInProcess(true);
  • Wei He
    I am new to Magento2 and looking for a solution of automatic invoice. Your code seems complete and neat. Could you tell me where should I put this code and how to run it? Thank you very much!
    • Pooja Sahu
      Hello,
      Like you want to create invoice for an order using a controller file (which we used in this post), then you will need to create a controller file CreateInvoice.php (as created in this post) in the path magnetoroot/app/code/VendorDirectory/ModuleName/Controller.
      Thanks!
  • Izzy
    Hi, I’m still new to magento 2, can you please tell me how and where do I initiate _objectManager? and is it ok to use it? cause I read couple of articles warning of using the _objectManager
    • Pooja Sahu
      Hello, I have updated this post I hope now you will better understand the process.
      Thanks!
  • Back to Top