1

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

3
  • remvoe var folder and check Commented Sep 1, 2017 at 8:30
  • Hi Rakesh, I removed all directories of var, pub/static then again run upgrade, content deploy n flush cache but still giving same issue....
    – Atul
    Commented Sep 1, 2017 at 10:41
  • did you solve the problem?
    – Mohit Rane
    Commented Aug 2, 2019 at 6:57

1 Answer 1

0

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.

7
  • I tried like this inside class - private $invoiceService; public function __construct( Magento\Sales\Model\Service\InvoiceService $invoiceService ) { $this->invoiceService = $invoiceService; } but its giving 500 error ....
    – Atul
    Commented Sep 2, 2017 at 10:16
  • did you run upgrade and compile commands afterwards?? Commented Sep 2, 2017 at 10:36
  • yes I have run Upgrade command but not compile because i m already in developer mode, >>>> now defined it as - public function __construct( \Magento\Framework\App\Action\Context $context, \Magento\Sales\Model\Service\InvoiceService $invoiceService, array $data = [] ) { $this->invoiceService = $invoiceService; parent::__construct($context, $data); } Now its giving - Argument 2 passed to Magento\Sales\Controller\Adminhtml\Order\Invoice\Save::__construct() must be an instance of Magento\Framework\Registry, error...
    – Atul
    Commented Sep 2, 2017 at 10:46
  • -> can you plz add respective live of code via update your answer.
    – Atul
    Commented Sep 2, 2017 at 11:39
  • @Atul I have made an edit. please give it a shot. Commented Sep 2, 2017 at 12:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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