We sacrifice by not doing any other technology, so that you get the best of Magento.

We sacrifice by not doing any other technology, so that you get the best of Magento.

    This could happen when bundled products and simple products are mixed in the order.

    To solve this, override the Invoiceservice.php from vendor/magento/module-sales/Model/Service/InvoiceService.php and change the below functions codes.

    public function prepareInvoice(Order $order, array $qtys = [])
    {
        $isQtysEmpty = empty($qtys);
        $invoice = $this->orderConverter->toInvoice($order);
        $totalQty = 0;
        $qtys = $this->prepareItemsQty($order, $qtys);
        foreach ($order->getAllItems() as $orderItem) {
            if (!$this->_canInvoiceItem($orderItem, $qtys)) {
                continue;
            }
            if (isset($qtys[$orderItem->getId()])) {
                $qty = (double) $qtys[$orderItem->getId()];
            } elseif ($orderItem->isDummy()) {
                $qty = $orderItem->getQtyOrdered() ? $orderItem->getQtyOrdered() : 1;
            } elseif ($isQtysEmpty) {
                $qty = $orderItem->getQtyToInvoice();
            } else {
                $qty = 0;
            }
            $item = $this->orderConverter->itemToInvoiceItem($orderItem);
            $this->setInvoiceItemQuantity($item, $qty);
            $invoice->addItem($item);
            $totalQty += $qty;
        }
        $invoice->setTotalQty($totalQty);
        $invoice->collectTotals();
        $order->getInvoiceCollection()->addItem($invoice);
        return $invoice;
    }
    private function prepareItemsQty(Order $order, array $qtys = [])
    {
        foreach ($order->getAllItems() as $orderItem) {
            if (isset($qtys[$orderItem->getId()])) {
                if ($orderItem->isDummy() && $orderItem->getHasChildren()) {
                    $qtys = $this->prepareItemQty($orderItem, $qtys);
                }
            } else {
                if (isset($qtys[$orderItem->getParentItemId()])) {
                    $qtys[$orderItem->getId()] = $qtys[$orderItem->getParentItemId()];
                }
            }
        }
        return $qtys;
    }
    private function prepareItemQty(MagentoSalesApiDataOrderItemInterface $orderItem, &$qtys)
    {
        /** @var OrderItemInterface $childOrderItem */
        foreach ($orderItem->getChildrenItems() as $childOrderItem) {
            if (!isset($qtys[$childOrderItem->getItemId()])) {
                $productOptions = $childOrderItem->getProductOptions();
                if (isset($productOptions['bundle_selection_attributes'])) {
                    $bundleSelectionAttributes = $this->serializer
                        ->unserialize($productOptions['bundle_selection_attributes']);
                    $qtys[$childOrderItem->getItemId()] =
                        $bundleSelectionAttributes['qty'] * $qtys[$orderItem->getItemId()];
                }
            }
        }
        return $qtys;
    }

    Once the changes will go live, the customer will have a complete invoice. None items will be missed.

    field_5bfb909c5ccae

      Get a Free Quote