<?php
/**
 * Mageplaza
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Mageplaza.com license that is
 * available through the world-wide-web at this URL:
 * https://www.mageplaza.com/LICENSE.txt
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade this extension to newer
 * version in the future.
 *
 * @category    Mageplaza
 * @package     Mageplaza_EditOrder
 * @copyright   Copyright (c) Mageplaza (https://www.mageplaza.com/)
 * @license     https://www.mageplaza.com/LICENSE.txt
 */

namespace Mageplaza\EditOrder\Model;

use Exception;
use Magento\Backend\Model\Session\Quote as QuoteSession;
use Magento\Bundle\Model\Product\Type as BundleProductType;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Product\Type;
use Magento\Catalog\Model\Product\Type as ProductType;
use Magento\CatalogInventory\Api\Data\StockItemInterface;
use Magento\CatalogInventory\Api\StockRegistryInterface;
use Magento\Checkout\Model\Session as CheckoutSession;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable as Configurable;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException as NoSuchEntityException;
use Magento\Framework\Model\AbstractModel;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\InventoryConfigurationApi\Exception\SkuIsNotAssignedToStockException;
use Magento\InventoryReservationsApi\Model\ReservationInterface;
use Magento\InventorySalesApi\Model\GetStockItemDataInterface;
use Magento\Quote\Model\Quote\Item;
use Magento\Quote\Model\Quote\ItemFactory as QuoteItemFactory;
use Magento\Quote\Model\QuoteFactory;
use Magento\Quote\Model\QuoteManagement;
use Magento\Sales\Api\OrderManagementInterface as OrderManagement;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\ItemFactory as OrderItemFactory;
use Magento\Sales\Model\OrderFactory;
use Magento\Sales\Model\ResourceModel\Order\Item\CollectionFactory as OrderItemCollectionFactory;
use Magento\Sales\Model\ResourceModel\Order\Tax\Item as TaxItem;
use Mageplaza\EditOrder\Helper\Data;
use Mageplaza\EditOrder\Helper\Data as HelperData;
use Mageplaza\EditOrder\Model\PreviousCartFactory as PreviousCartFactory;
use Psr\Log\LoggerInterface;

class ItemComparison extends AbstractModel
{
    const NEW_ITEMS    = 'new_items';
    const REMOVE_ITEMS = 'removed_items';

    /**
     * @var HelperData
     */
    protected $_helperData;

    /**
     * @var QuoteFactory
     */
    protected $quoteFactory;

    /**
     * @var QuoteManagement
     */
    protected $quoteManagement;

    /**
     * @var OrderFactory
     */
    protected $orderFactory;

    /**
     * @var OrderItemCollectionFactory
     */
    protected $orderItemCollectionFactory;

    /**
     * @var ProductRepositoryInterface
     */
    protected $productRepository;

    /**
     * @var QuoteSession
     */
    protected $quoteSession;

    /**
     * @var CheckoutSession
     */
    protected $checkoutSession;

    /**
     * @var OrderRepositoryInterface
     */
    protected $orderRepository;

    /**
     * @var OrderItemFactory
     */
    protected $orderItemFactory;

    /**
     * @var QuoteItemFactory
     */
    protected $quoteItemFactory;

    /**
     * @var Configurable
     */
    protected $configurableProductType;

    /**
     * @var BundleProductType
     */
    protected $bundleProductType;

    /**
     * @var PreviousCartFactory
     */
    protected $previousCartFactory;

    /**
     * @var LoggerInterface
     */
    protected $_logger;

    /**
     * @var TaxItem
     */
    protected $taxItem;

    /**
     * @var ResourceConnection
     */
    private $resourceConnection;

    /**
     * @var StockRegistryInterface
     */
    protected $stockRegistry;

    /**
     * @var StockItemInterface
     */
    protected $stockItem;

    /**
     * @var OrderManagement
     */
    protected $orderManagement;

    /**
     * @var PriceCurrencyInterface
     */
    protected $priceCurrency;

    /**
     * @var GetStockItemDataInterface
     */
    protected $getStockItemData;

    /**
     * @param QuoteFactory $quoteFactory
     * @param QuoteManagement $quoteManagement
     * @param OrderFactory $orderFactory
     * @param OrderItemCollectionFactory $orderItemCollectionFactory
     * @param ProductRepositoryInterface $productRepository
     * @param HelperData $helperData
     * @param QuoteSession $quoteSession
     * @param CheckoutSession $checkoutSession
     * @param OrderRepositoryInterface $orderRepository
     * @param OrderItemFactory $orderItemFactory
     * @param QuoteItemFactory $quoteItemFactory
     * @param Configurable $configurableProductType
     * @param BundleProductType $bundleProductType
     * @param PreviousCartFactory $previousCartFactory
     * @param LoggerInterface $logger
     * @param TaxItem $taxItem
     * @param ResourceConnection $resourceConnection
     * @param StockRegistryInterface $stockRegistry
     * @param StockItemInterface $stockItem
     * @param OrderManagement $orderManagement
     * @param PriceCurrencyInterface $priceCurrency
     * @param GetStockItemDataInterface $getStockItemData
     */
    public function __construct(
        QuoteFactory $quoteFactory,
        QuoteManagement $quoteManagement,
        OrderFactory $orderFactory,
        OrderItemCollectionFactory $orderItemCollectionFactory,
        ProductRepositoryInterface $productRepository,
        HelperData $helperData,
        QuoteSession $quoteSession,
        CheckoutSession $checkoutSession,
        OrderRepositoryInterface $orderRepository,
        OrderItemFactory $orderItemFactory,
        QuoteItemFactory $quoteItemFactory,
        Configurable $configurableProductType,
        BundleProductType $bundleProductType,
        PreviousCartFactory $previousCartFactory,
        LoggerInterface $logger,
        TaxItem $taxItem,
        ResourceConnection $resourceConnection,
        StockRegistryInterface $stockRegistry,
        StockItemInterface $stockItem,
        OrderManagement $orderManagement,
        PriceCurrencyInterface $priceCurrency,
        GetStockItemDataInterface $getStockItemData,
    ) {
        $this->quoteFactory               = $quoteFactory;
        $this->quoteManagement            = $quoteManagement;
        $this->orderFactory               = $orderFactory;
        $this->orderItemCollectionFactory = $orderItemCollectionFactory;
        $this->productRepository          = $productRepository;
        $this->_helperData                = $helperData;
        $this->quoteSession               = $quoteSession;
        $this->checkoutSession            = $checkoutSession;
        $this->orderRepository            = $orderRepository;
        $this->orderItemFactory           = $orderItemFactory;
        $this->quoteItemFactory           = $quoteItemFactory;
        $this->configurableProductType    = $configurableProductType;
        $this->bundleProductType          = $bundleProductType;
        $this->previousCartFactory        = $previousCartFactory;
        $this->_logger                    = $logger;
        $this->taxItem                    = $taxItem;
        $this->resourceConnection         = $resourceConnection;
        $this->stockRegistry              = $stockRegistry;
        $this->stockItem                  = $stockItem;
        $this->orderManagement            = $orderManagement;
        $this->priceCurrency              = $priceCurrency;
        $this->getStockItemData           = $getStockItemData;
    }

    /**
     * Compare items between order and new items data
     *
     * @param $quote
     * @param $order
     *
     * @return array
     */
    public function compareItemsInQuote($quote, $order)
    {
        $result = [
            self::NEW_ITEMS    => [],
            self::REMOVE_ITEMS => [],
        ];

        try {
            $currentItems = [];
            foreach ($quote->getAllItems() as $item) {
                $currentItems[$item->getItemId()] = $item;
            }

            $previousCart  = $this->previousCartFactory->create();
            $previousItems = $previousCart->getQuoteItemsByOrderId($order->getId());

            foreach ($currentItems as $itemId => $item) {
                if (!isset($previousItems[$itemId])) {
                    $result['new_items'][$item->getItemId()] = $item;
                }
            }
            foreach ($previousItems as $itemId => $item) {
                if (!isset($currentItems[$itemId])) {
                    $result['removed_items'][$item['item_id']] = $item;
                }
            }
        } catch (Exception $e) {
            $this->_logger->critical($e->getMessage());
        }

        return $result;
    }

    /**
     * @param $order
     *
     * @return array|array[]
     * @throws Exception
     */
    public function reSetUpdateOrder($order)
    {
        $quoteId         = $this->quoteSession->getQuoteId();
        $quote           = $this->quoteFactory->create()->load($quoteId);
        $diffItemInQuote = $this->compareItemsInQuote($quote, $order);
        $previousCart    = $this->previousCartFactory->create();
        $oldItemOrder    = $previousCart->getItemIdOrderByOrderId($order->getId());

        if ($diffItemInQuote[self::NEW_ITEMS] && !empty($diffItemInQuote[self::NEW_ITEMS])) {
            $this->addQuoteItemsToOrder($order, $quote, $diffItemInQuote[self::REMOVE_ITEMS]);
        }
        if ($diffItemInQuote[self::REMOVE_ITEMS] && !empty($diffItemInQuote[self::REMOVE_ITEMS])) {
            $removeItem = [];
            foreach ($diffItemInQuote[self::REMOVE_ITEMS] as $item) {
                $removeItem[] = $item['item_id'];
            }
            $this->removeQuoteItemsToOrder($order, $removeItem, $oldItemOrder);
        }

        //set quote id by orderRepository
        $order->setQuoteId($quoteId);
        $this->orderRepository->save($order);

        return $diffItemInQuote;
    }

    /**
     * @param $order
     * @param $quote
     * @param $removedItems
     *
     * @return $this
     * @throws InputException
     * @throws LocalizedException
     * @throws NoSuchEntityException
     * @throws SkuIsNotAssignedToStockException
     */
    public function addQuoteItemsToOrder($order, $quote, $removedItems)
    {
        $parentItemId             = null;
        $parentProductId          = null;
        $qtyOrder                 = null;
        $taxPercent               = null;
        $quoteParentItem          = null;
        $updateAfterEditingConfig = (int) $this->_helperData->getUpdateAfterEditing()[0];
        $skuList                  = array_column($removedItems, 'sku');
        foreach ($quote->getAllItems() as $quoteItem) {
            $orderItem = $this->orderItemFactory->create();
            if (!$this->checkStockBackOrder($quoteItem) && !in_array(
                $quoteItem->getProduct()->getSku(),
                $skuList
            ) && $quoteItem->getProductType() != ProductType::TYPE_BUNDLE) {
                continue;
            }
            foreach ($quoteItem->getData() as $key => $dataItem) {
                if (!in_array($key, ['item_id', 'parent_item'])) {
                    if ($updateAfterEditingConfig === 0) {
                        $qty_invoiced = $orderItem->getQtyInvoiced();
                        $qty_shipped  = $orderItem->getQtyShipped();
                        $qty_refunded = $orderItem->getQtyRefunded();
                        $orderItem->setData($key, $quoteItem->getData($key));
                        $orderItem->setQtyInvoiced($qty_invoiced);
                        $orderItem->setQtyShipped($qty_shipped);
                        $orderItem->setQtyRefunded($qty_refunded);
                    } else {
                        $orderItem->setData($key, $quoteItem->getData($key));
                    }
                }
            }
            $originalPrice = $quoteItem->getProduct()->getPrice();
            $orderItem->setOriginalPrice($this->priceCurrency->convert($originalPrice, $order->getOrderCurrencyCode()));
            $orderItem->setBaseOriginalPrice($originalPrice);
            $orderItem->setQtyOrdered($this->getCustomQty($quoteItem, $order));
            $orderItem->setOrderId($order->getId())
                ->setQuoteItemId($quoteItem->getItemId())
                ->setStoreId($order->getStoreId());
            $productOptions = $quoteItem->getProduct()->getTypeInstance(true)
                ->getOrderOptions($quoteItem->getProduct()) ?? [];

            //get option child in the product bundle
            if ($quoteItem->getOptionByCode('bundle_selection_attributes')) {
                $bundle_selection_attributes = $quoteItem->getOptionByCode('bundle_selection_attributes')
                   ? json_decode($quoteItem->getOptionByCode('bundle_selection_attributes')->getValue(), true)
                   : [];
                $productOptions['bundle_selection_attributes'] = json_encode($bundle_selection_attributes);
            }

            $orderItem->setProductOptions($productOptions);
            $orderItem->setData('quote_item_id', $quoteItem->getId());
            $orderItem->setData('quote_id', $quoteItem->getQuoteId());

            if ($quoteItem->getProductType() === Configurable::TYPE_CODE ||
                $quoteItem->getProductType() === ProductType::TYPE_BUNDLE) {
                $quoteParentItem = $quoteItem->getItemId();
                $order->addItem($orderItem);

                $this->orderRepository->save($order);
                $parentItemId    = $orderItem->getItemId();
                $parentProductId = $orderItem->getProductId();

                $taxPercent = $orderItem->getTaxPercent();
                $qtyOrder   = $orderItem->getQtyOrdered();

            } else {
                $chillProductId = $this->getParentProductId($quoteItem->getProductId());

                if ($chillProductId === $parentProductId && $quoteParentItem === $quoteItem->getParentItemId() &&
                    $quoteItem->getParentItemId()) {

                    $discountAmount        = $quoteItem->getDiscountAmount();
                    $subtotalAfterDiscount = ($quoteItem->getProduct()->getPrice() * $quoteItem->getQty() * $qtyOrder) - $discountAmount;
                    $taxAmount             = $subtotalAfterDiscount * ($taxPercent / 100);

                    $orderItem->setTaxPercent($taxPercent);
                    $orderItem->setTaxAmount($taxAmount);
                    $orderItem->setParentItemId($parentItemId);
                }

                // Add the order item to the order
                $order->addItem($orderItem);
                $this->changeStockProduct($order, $orderItem, false);
            }
        }
        $this->orderRepository->save($order);

        return $this;
    }

    /**
     * @param $childProductId
     *
     * @return false|mixed|null
     */
    public function getParentProductId($childProductId = null)
    {
        try {
            $childProduct = $this->productRepository->getById($childProductId);

            if ($childProduct->getTypeId() === 'simple') {
                // Check for configurable parent
                $parentIds = $this->configurableProductType->getParentIdsByChild($childProductId);

                if (!empty($parentIds)) {
                    // Assuming only one parent product
                    return reset($parentIds);
                }

                // Check for bundle parent
                $bundleParentIds = $this->bundleProductType->getParentIdsByChild($childProductId);

                if (!empty($bundleParentIds)) {
                    // Assuming only one parent product
                    return reset($bundleParentIds);
                }
            }
        } catch (NoSuchEntityException $e) {
            $this->_logger->critical($e->getMessage());
        }

        return null;
    }

    /**
     * @param $order
     * @param $removeItem
     * @param $oldItemOrder
     *
     * @return $this
     * @throws Exception
     */
    public function removeQuoteItemsToOrder($order, $removeItem, $oldItemOrder)
    {
        foreach ($order->getAllItems() as $orderItem) {
            if (in_array($orderItem->getQuoteItemId(), $oldItemOrder) ||
                in_array($orderItem->getQuoteItemId(), $removeItem)) {
                $this->changeStockProduct($order, $orderItem, true);
                $orderItem->isDeleted(true);
            }
        }
        $this->orderRepository->save($order);

        return $this;
    }

    /**
     * @param Order $order
     *
     * @return ItemComparison
     */
    public function calculateAndSaveOrderTotals($order)
    {
        $totalPaid     = 0;
        $totalRefunded = 0;
        foreach ($order->getItems() as $orderItem) {
            $qtyOrdered     = $orderItem->getQtyOrdered();
            $qtyInvoiced    = $orderItem->getQtyInvoiced();
            $qtyRefunded    = $orderItem->getQtyRefunded();
            $basePrice      = $orderItem->getBasePrice();
            $taxAmount      = $orderItem->getTaxAmount();
            $discountAmount = $orderItem->getDiscountAmount();

            $totalPaid += $qtyInvoiced > 0
                ? ($qtyInvoiced * $basePrice) + ($taxAmount * ($qtyInvoiced / $qtyOrdered)) - ($discountAmount * ($qtyInvoiced / $qtyOrdered))
                : 0;

            $totalRefunded += $qtyRefunded > 0
                ? ($qtyRefunded * $basePrice) + ($taxAmount * ($qtyRefunded / $qtyOrdered)) - ($discountAmount * ($qtyRefunded / $qtyOrdered))
                : 0;

        }

        $order->setTotalPaid($totalPaid);
        $order->setTotalRefunded($totalRefunded);
        $this->orderRepository->save($order);

        return $this;
    }

    /**
     * @param Order $order
     *
     * @return void
     */
    public function setTaxSalesItems($order)
    {
        $taxId         = '';
        $orderTaxItems = $this->taxItem->getTaxItemsByOrderId($order->getId());
        foreach ($orderTaxItems as $item) {
            $taxId = $item['tax_id'];
        }
        $connection = $this->resourceConnection->getConnection();
        $amount     = $order->getBaseTaxAmount();

        $orderTaxItem      = [
            'amount'           => $amount,
            'real_amount'      => $amount,
            'real_base_amount' => $amount
        ];
        $orderTax          = [
            'amount'           => $amount,
            'base_amount'      => $amount,
            'base_real_amount' => $amount
        ];
        $where             = ['tax_id = ?' => (int) $taxId];
        $tableOrderTaxItem = $this->resourceConnection->getTableName("sales_order_tax_item");
        $tableOrderTax     = $this->resourceConnection->getTableName("sales_order_tax");
        $connection->update($tableOrderTaxItem, $orderTaxItem, $where);
        $connection->update($tableOrderTax, $orderTax, $where);
    }

    /**
     * @param $productId
     * @param $qty
     *
     * @return float|int
     * @throws NoSuchEntityException
     */
    public function weightCalculate($productId, $qty)
    {
        $weight  = 0;
        $product = $this->productRepository->getById($productId);
        if ($product->getTypeId() === Type::TYPE_SIMPLE) {
            $weight = $qty * $product->getWeight();
        }

        return $weight;
    }

    /**
     * @param $order
     *
     * @return float
     */
    public function getSubtotalByItems($order)
    {
        $subtotal = 0;

        foreach ($order->getAllItems() as $item) {
            if ($item->getProductType() === Type::TYPE_BUNDLE) {
                continue;
            }

            $subtotal += $item->getBaseRowTotal();
        }

        return $subtotal;
    }

    /**
     * @param $data
     * @param $order
     * @param $total
     * @param $origItems
     * @param $qty
     * @param $isChanged
     * @param $oldShippedQty
     *
     * @return array|void
     * @throws NoSuchEntityException
     */
    public function changeSubTotalOrder($data, $order, $total)
    {
        if (count($total)) {
            $storeId = $order->getStore()->getStoreId();

            if (isset($total['ship_amount'])) {
                $order
                    ->setShippingMethod($data['method'])
                    ->setShippingDescription($total['ship_description'])
                    ->setBaseShippingAmount($total['ship_amount'])
                    ->setBaseShippingTaxAmount($total['ship_tax_amount'])
                    ->setBaseShippingDiscountAmount($total['ship_discount_amount'])
                    ->setBaseShippingInclTax($data['total_fee'])
                    ->setShippingAmount($this->priceCurrency->convert($total['ship_amount'], $storeId))
                    ->setShippingTaxAmount($this->priceCurrency->convert($total['ship_tax_amount'], $storeId))
                    ->setShippingDiscountAmount($this->priceCurrency->convert($total['ship_discount_amount'], $storeId))
                    ->setShippingInclTax($this->priceCurrency->convert($data['total_fee'], $storeId));
            }

            $order
                ->setBaseTaxAmount($total['tax_amount'])
                ->setBaseDiscountAmount(-$total['discount_amount'])
                ->setBaseGrandTotal($total['grand_total']);

            $order
                ->setTaxAmount($this->priceCurrency->convert($total['tax_amount'], $storeId))
                ->setDiscountAmount($this->priceCurrency->convert(-$total['discount_amount'], $storeId))
                ->setGrandTotal($this->priceCurrency->convert($total['grand_total'], $storeId));
            $this->setTaxSalesItems($order);
            if (isset($total['subtotal'])) {
                $order->setSubtotal($this->priceCurrency->convert($total['subtotal'], $storeId));
                $order->setBaseSubtotal($total['subtotal'])
                    ->setSubtotalInclTax($this->priceCurrency->convert($total['subtotal_incl_tax'], $storeId))
                    ->setBaseSubtotalInclTax($total['subtotal_incl_tax']);
            }
        }
    }

    /**
     * @param $order
     * @param $orderItem
     * @param $type
     *
     * @return void
     * @throws Exception
     */
    public function changeStockProduct($order, $orderItem, $type)
    {
        if ($orderItem->getParentItemId() || $orderItem->getProductType() === Type::TYPE_BUNDLE) {
            return;
        }

        $stockItem   = $this->stockRegistry->getStockItem($orderItem->getProductId());
        $stockStatus = (bool) $stockItem->getIsInStock();

        $requestedQty = $type ? (float) $orderItem->getQtyOrdered() : -(float) $orderItem->getQtyOrdered();

        if ($stockStatus === false && $requestedQty < 0) {
            $stockItem->setIsInStock(1);
            $stockItem->setQty($stockItem->getQty() + 1);
            $stockItem->save();
        }
        if ($order->getStatus() === 'pending') {
            $this->resetSalableQuantity($orderItem, $requestedQty);
        }
    }

    /**
     * @param $item
     * @param $qty
     */
    public function resetSalableQuantity($item, $qty)
    {
        if (!$this->isEnableInventorySales()) {
            return;
        }
        $connection = $this->resourceConnection->getConnection();
        $tableName  = $this->resourceConnection->getTableName('inventory_reservation');

        $columns = [
            ReservationInterface::STOCK_ID,
            ReservationInterface::SKU,
            ReservationInterface::QUANTITY,
            ReservationInterface::METADATA,
        ];

        $data = [[$this->stockItem->getStockId(), $item->getSku(), $qty, '{}']];
        $connection->insertArray($tableName, $columns, $data);
    }

    /**
     * @return bool
     */
    public function isEnableInventorySales()
    {
        return $this->_helperData->isEnableInventorySales();
    }

    /**
     * Check if the item in the order has been invoiced
     *
     * @param int $orderId
     * @param int $itemId
     *
     * @return array
     */
    public function isItemInvoiced($order, $itemId)
    {
        $invoicedQty = 0;
        $shippedQty  = 0;
        $refundedQty = 0;

        foreach ($order->getAllItems() as $orderItem) {
            if ($orderItem->getItemId() == $itemId) {
                $invoicedQty = $orderItem->getQtyInvoiced();
                $shippedQty  = $orderItem->getQtyShipped();
                $refundedQty = $orderItem->getQtyRefunded();
                break;
            }
        }

        return [
            'invoiced' => $invoicedQty > 0,
            'shipped'  => $shippedQty > 0,
            'refunded' => $refundedQty > 0,
        ];
    }

    /**
     * @param $quoteItem
     *
     * @return string
     * @throws InputException
     * @throws LocalizedException
     * @throws NoSuchEntityException
     * @throws SkuIsNotAssignedToStockException
     */
    public function checkStockBackOrder($quoteItem)
    {
        $product      = $quoteItem->getProduct();
        $requestedQty = $quoteItem->getQty();
        $stockItem    = $product->getExtensionAttributes()->getStockItem();
        if ($stockItem && $product->getTypeId() != 'bundle') {
            $stockProductId = $stockItem->getStockId();
            $stockItemData  = $this->getStockItemData->execute($product->getSku(), $stockProductId);
            if (null === $stockItemData) {
                return $requestedQty;
            }

            return $this->_helperData->isBackorderAllowed($requestedQty, $quoteItem);
        }

        return false;
    }

    /**
     * Related Stock
     *
     * @param Item $quoteItem
     * @param Order $order
     *
     * @return mixed
     * @throws InputException
     * @throws LocalizedException
     * @throws NoSuchEntityException
     * @throws SkuIsNotAssignedToStockException
     */
    public function getCustomQty($quoteItem, $order)
    {
        $requestedQty = $this->_helperData->getQtyItem($quoteItem);
        $isEnoughQty  = $this->checkStockBackOrder($quoteItem);
        if (!$isEnoughQty) {
            foreach ($order->getAllItems() as $item) {
                if (isset($item['sku']) && $item->getSku() == $quoteItem->getProduct()->getSku()) {
                    if ($requestedQty > $item['qty'] && $item->getProduct()->getTypeId() != 'bundle') {
                        return $item->getQtyOrdered();
                    } else {
                        return $requestedQty;
                    }
                }
            }
        }

        return $requestedQty;
    }
}
