I have added a mass action to Sales->Invoice Grid. It is working fine when I select a single item from the grid. But on multiple selects it throws the following error:
Fatal error: Uncaught TypeError: Argument 1 passed to Magento\Sales\Model\Order\Invoice\Item::setOrderItem() must be an instance of Magento\Sales\Model\Order\Item, null given, called in /var/www/html/magento/vendor/magento/module-sales/Model/ResourceModel/Order/Invoice/Relation.php on line 54 and defined in /var/www/html/magento/vendor/magento/module-sales/Model/Order/Invoice/Item.php on line 129
Here is the mass action controller:
<?php
namespace Vendor\MassActionCancel\Controller\Adminhtml\Invoice;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
use Magento\Backend\App\Action\Context;
use Magento\Ui\Component\MassAction\Filter;
use Magento\Sales\Model\ResourceModel\Order\CollectionFactory;
use Magento\Sales\Api\OrderManagementInterface;
class CancelInvoice extends \Magento\Sales\Controller\Adminhtml\Order\AbstractMassAction
{
protected $orderManagement;
public function __construct(
Context $context,
Filter $filter,
CollectionFactory $collectionFactory,
OrderManagementInterface $orderManagement,
\Magento\Framework\App\RequestInterface $request,
\Magento\Sales\Model\Order\Invoice $invoiceModel,
\Magento\Framework\Message\ManagerInterface $messageManager
) {
parent::__construct($context, $filter);
$this->collectionFactory = $collectionFactory;
$this->orderManagement = $orderManagement;
$this->request = $request;
$this->invoiceModel = $invoiceModel;
$this->messageManager = $messageManager;
}
protected function massAction(AbstractCollection $collection)
{
$invoice_not_canceled = array();
$invoice_canceled = array();
$itemsArray = $this->request->getPostValue('selected');
foreach ($itemsArray as $key => $invoiceId) {
$invoice = $this->invoiceModel->load($invoiceId);
if(!$invoice->isCanceled()){
$invoice->cancel();
$invoice->setState(\Magento\Sales\Model\Order\Invoice::STATE_CANCELED);
$invoice->save();
$invoice_canceled[] = $invoiceId;
}
else{
$invoice_not_canceled[] = $invoiceId;
}
}
if(!empty($invoice_not_canceled)){
$this->messageManager->addSuccess(__('Following Invoices could not be canceled: '.implode(',', $invoice_not_canceled)));
}
if(!empty($invoice_canceled)){
$this->messageManager->addSuccess(__('Following Invoices canceled: '.implode(',', $invoice_canceled)));
}
return $this->resultRedirectFactory->create()->setPath('sales/invoice/');
}
}
It is called when save() method is called for the second item. Also the error is not thrown always but at random times.