Magento – “Undefined property: Interceptor::$invoiceService” while overriding controller in magento2

magento2

I am trying to override "Adminhtml\Order\Invoice\Save" controller, So I made changes in di.xml as below –

<preference for="Magento\Sales\Controller\Adminhtml\Order\Invoice\Save" type="Customcode\Productserialno\Controller\Sales\Adminhtml\Order\Invoice\Save" />

And create as save.php controller at location –
Customcode\Productserialno\Controller\Sales\Adminhtml\Order\Invoice\Save.php

and overide its execute function like below –

namespace Customcode\Productserialno\Controller\Sales\Adminhtml\Order\Invoice;

    class Save extends \Magento\Sales\Controller\Adminhtml\Order\Invoice\Save
    {

        public function execute()
        {
           /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
            ====
            ....................
            ........................
            default code............
            ......................

            try {
                $invoiceData = $this->getRequest()->getParam('invoice', []);
                $invoiceItems = isset($invoiceData['items']) ? $invoiceData['items'] : [];

                /** @var \Magento\Sales\Model\Order $order */
                $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
                if (!$order->getId()) {
                    throw new \Magento\Framework\Exception\LocalizedException(__('The order no longer exists.'));
                }

                if (!$order->canInvoice()) {
                    throw new \Magento\Framework\Exception\LocalizedException(
                        __('The order does not allow an invoice to be created.')
                    );
                }
                //====on below line its giving error========     
                $invoice = $this->invoiceService->prepareInvoice($order, $invoiceItems);

                if (!$invoice) {
                    throw new LocalizedException(__('We can\'t save the invoice right now.'));
                }

                if (!$invoice->getTotalQty()) {
                    throw new \Magento\Framework\Exception\LocalizedException(
                        __('You can\'t create an invoice without products.')
                    );
                }
                $this->registry->register('current_invoice', $invoice);
                if (!empty($data['capture_case'])) {
                    $invoice->setRequestedCaptureCase($data['capture_case']);
                }

                if (!empty($data['comment_text'])) {
                    $invoice->addComment(
                        $data['comment_text'],
                        isset($data['comment_customer_notify']),
                        isset($data['is_visible_on_front'])
                    );

                    $invoice->setCustomerNote($data['comment_text']);
                    $invoice->setCustomerNoteNotify(isset($data['comment_customer_notify']));
                }

                $invoice->register();

                $invoice->getOrder()->setCustomerNoteNotify(!empty($data['send_email']));
                $invoice->getOrder()->setIsInProcess(true);

                $transactionSave = $this->_objectManager->create(
                    'Magento\Framework\DB\Transaction'
                )->addObject(
                    $invoice
                )->addObject(
                    $invoice->getOrder()
                );
                $shipment = false;
                if (!empty($data['do_shipment']) || (int)$invoice->getOrder()->getForcedShipmentWithInvoice()) {
                    $shipment = $this->_prepareShipment($invoice);
                    if ($shipment) {
                        $transactionSave->addObject($shipment);
                    }
                }
                $transactionSave->save();
                //=================
                //===My custom code========
                //=================
                //....................
                ........................
                default code............
                ......................

                return $resultRedirect->setPath('sales/order/view', ['order_id' => $orderId]);
            } catch (LocalizedException $e) {
                $this->messageManager->addError($e->getMessage());
            } catch (\Exception $e) {
                echo "<pre>"; 
                print_r($e->getMessage()); die;
                $this->messageManager->addError(__('We can\'t save the invoice right now.'));
                $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
            }
            return $resultRedirect->setPath('sales/*/new', ['order_id' => $orderId]);
        }
    }

On this line its giving me error –

$invoice = $this->invoiceService->prepareInvoice($order, $invoiceItems);

Error – : Notice: Undefined property: Customcode\Productserialno\Controller\Sales\Adminhtml\Order\Invoice\Save\Interceptor::$invoiceService in /var/www/html/git_projects/testbeat/app/code/Customcode/Productserialno/Controller/Sales/Adminhtml/Order/Invoice/Save.php on line 51

Please let me know what I am doing wrong .

Thanks

Best Answer

The scope of this variable is private. Hence you can't use this in your overriding (inherited) class. please inject Magento\Sales\Model\Service\InvoiceService class for this variable in your constructor as it is injected into the main class.

Don't forget to run upgrade and di:compile commands after DI.

Edit: try this in your class

<?php

namespace Customcode\Productserialno\Controller\Sales\Adminhtml\Order\Invoice;


use Magento\Backend\App\Action;
use Magento\Framework\Registry;
use Magento\Sales\Model\Order\Email\Sender\InvoiceSender;
use Magento\Sales\Model\Order\Email\Sender\ShipmentSender;
use Magento\Sales\Model\Order\ShipmentFactory;
use Magento\Sales\Model\Service\InvoiceService;

class Save extends \Magento\Sales\Controller\Adminhtml\Order\Invoice\Save
{
    /**
     * @var InvoiceService
     */
    private $invoiceService;

    public function __construct
    (
        Action\Context $context,
        Registry $registry,
        InvoiceSender $invoiceSender,
        ShipmentSender $shipmentSender,
        ShipmentFactory $shipmentFactory,
        InvoiceService $invoiceService
    )
    {
        $this->invoiceService = $invoiceService;
        parent::__construct($context, $registry, $invoiceSender, $shipmentSender, $shipmentFactory, $invoiceService);
    }

    /**
     * Save invoice
     * We can save only new invoice. Existing invoices are not editable
     *
     * @return \Magento\Framework\Controller\ResultInterface
     *
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
     */
    public function execute()
    {
        ..........................
        .......All code with customization------
    }
}

=================My Code is this ===================

namespace Customcode\Productserialno\Controller\Sales\Adminhtml\Order\Invoice;

class Save extends \Magento\Sales\Controller\Adminhtml\Order\Invoice\Save
{
    /**
     * @var InvoiceService
     */
    private $invoiceService;

    public function __construct(
        \Magento\Backend\App\Action $context,
        Registry $registry,
        InvoiceSender $invoiceSender,
        ShipmentSender $shipmentSender,
        ShipmentFactory $shipmentFactory,
        InvoiceService $invoiceService
    ) {
        parent::__construct($context, $registry, $invoiceSender, $shipmentSender, $shipmentFactory, $invoiceService);
    }

  public function execute() { 
..........................
.......All code with customization------
}

}

Plz check because my code still giving same error. Recoverable Error: Argument 1 passed to Customcode\Productserialno\Controller\Sales\Adminhtml\Order\Invoice\Save::__construct() must be an instance of Magento\Backend\App\Action,

Plz let me know what I m doing wrong.

Related Topic