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

  • remvoe var folder and check – Rakesh Jesadiya Sep 1 '17 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 Sep 1 '17 at 10:41
  • did you solve the problem? – Mohit Rane Aug 2 at 6:57
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.

  • 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 Sep 2 '17 at 10:16
  • did you run upgrade and compile commands afterwards?? – Yogesh Agarwal Sep 2 '17 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 Sep 2 '17 at 10:46
  • -> can you plz add respective live of code via update your answer. – Atul Sep 2 '17 at 11:39
  • @Atul I have made an edit. please give it a shot. – Yogesh Agarwal Sep 2 '17 at 12:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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