Question

When total price is above $200 cart price rule is applied and free products are added to the cart. enter image description here

when total price is below $200, cart price rule is applied and free products are removed from the cart after we decrease quantity and click update cart button. But the minicart count doesnt decrease.

enter image description here

The items are being removed through the 'sales_quote_save_after' event and observer:

class SamplesRemoveExtra implements ObserverInterface
{
    protected $checkoutSession;
    protected $itemModel;
    protected $ruleModel;
    protected $logger;
    protected $collectionFactory;
    protected $stockHelper;
    protected $storeManager;
    protected $cartItemFactory;
    protected $productRepository;
    protected $cart;
    protected $appState;
    protected $scopeConfig;

    public function __construct(
        \Magento\Checkout\Model\Session $checkoutSession,
        \Magento\Quote\Model\Quote\Item $itemModel,
        \Magento\SalesRule\Model\Rule $ruleModel,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $collectionFactory,
        \Magento\CatalogInventory\Helper\Stock $stockHelper,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Quote\Api\Data\CartItemInterfaceFactory $cartItemFactory,
        \Magento\Catalog\Model\ProductRepository $productRepository,
        \Magento\Checkout\Model\Cart $cart,
        \Magento\Framework\App\State $appState,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
    ) {
        $this->checkoutSession = $checkoutSession;
        $this->itemModel = $itemModel;
        $this->ruleModel = $ruleModel;
        $this->logger = $logger;
        $this->collectionFactory = $collectionFactory;
        $this->stockHelper = $stockHelper;
        $this->storeManager = $storeManager;
        $this->cartItemFactory = $cartItemFactory;
        $this->productRepository = $productRepository;
        $this->cart = $cart;
        $this->appState = $appState;
        $this->scopeConfig = $scopeConfig;
    }

    /**
     * @param Observer $observer
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $quote = $observer->getEvent()->getQuote();
        if ($quote instanceof \Magento\Framework\Model\AbstractModel) {

            $appliedRules = [];

            $quoteItems = $quote->getAllItems();

            if (count($quoteItems) == 0) {
                return;
            }

            if ($quote->getAppliedRuleIds()) {
                $appliedRules = explode(',', $quote->getAppliedRuleIds());
            }

            /**
            CASE-2,
            if rule ids exists,
            check count of each rule id,
            if found count greater than allowed samples,
            forcily remove extra free samples
            */
            if (count($appliedRules) > 0) {
                $allowedSamplesLimit = 0;
                $cartAddedsamples = 0;
                $associatedSamples = [];
                $removeExtraSamples = [];
                $mergedAssociatedSamples = [];
                $sampleSkuArray = [];
                $i=0;

                foreach ($appliedRules as $eachRule) {
                    $ruleModel = '';
                    $ruleModel = $this->ruleModel->load($eachRule);
                    if ($ruleModel->getIsActive()) {
                        if ($ruleModel->getAutoAddtocart() != 3) { //means free, normal, deluxe
                            $sampleSkuArray[] = explode(',', $ruleModel->getAssociated());
                            $allowedSamplesLimit += (int)$ruleModel->getNumberItem();
                        } else { //means gift-regimen
                            if ($ruleModel->getPrepare()) {
                                $sampleSkuArray[] = explode(',', $ruleModel->getPrepare());
                                $allowedSamplesLimit += (int)$ruleModel->getNumberItem();
                            }
                            if ($ruleModel->getCleanse()) {
                                $sampleSkuArray[] = explode(',', $ruleModel->getCleanse());
                                $allowedSamplesLimit += (int)$ruleModel->getNumberItem();
                            }
                            if ($ruleModel->getTreat()) {
                                $sampleSkuArray[] = explode(',', $ruleModel->getTreat());
                                $allowedSamplesLimit += (int)$ruleModel->getNumberItem();
                            }

                            if ($ruleModel->getFourth()) {
                                $sampleSkuArray[] = explode(',', $ruleModel->getFourth());
                                $allowedSamplesLimit += (int)$ruleModel->getNumberItem();
                            }

                            if ($ruleModel->getFifth()) {
                                $sampleSkuArray[] = explode(',', $ruleModel->getFifth());
                                $allowedSamplesLimit += (int)$ruleModel->getNumberItem();
                            }
                        }

                        if (is_array($sampleSkuArray)) {
                            foreach ($sampleSkuArray as $eachSample) {
                                if (is_array($eachSample)) {
                                    foreach ($eachSample as $eachSku) {
                                        if ($eachSku) {
                                            $associatedSamples[] = trim($eachSku);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
        
                $mergedAssociatedSamples = array_map('strtoupper', $associatedSamples);
                $addedSampleSkus = [];

                try {
                    foreach ($quoteItems as $eachItem) {
                        if (ceil($eachItem->getPrice()) == (int)0 && $eachItem->getFreeSample()) {
                            if (in_array(strtoupper($eachItem->getSKU()), $mergedAssociatedSamples)) {
                                /**
                                important,
                                no risk for samples more than 1 qty,
                                forcily set qty 1 for free-samples
                                */
                                $eachItem->setQty(1);
                                /**
                                ends
                                */
                                $cartAddedsamples++;
                                
                                if (!$eachItem->getFreeSample() && ceil($eachItem->getPrice()) == (int)0) {
                                    $eachItem->setFreeSample(true);
                                }

                                if ($cartAddedsamples > $allowedSamplesLimit) {
                                    $removeExtraSamples[] = $eachItem->getItemId();
                                }
                            } else { //means free-sample not found in any rule and must be deleted
                                $removeExtraSamples[] = $eachItem->getItemId();
                            }
                            if (!in_array($eachItem->getSKU(), $addedSampleSkus)) {
                                $addedSampleSkus[] = $eachItem->getSKU();
                            } else {
                                //make sure, no sample can be appeared twice in cart
                                $removeExtraSamples[] = $eachItem->getItemId();
                            }
                        }
                    }
                                        
                    if ($this->appState->getAreaCode() != \Magento\Framework\App\Area::AREA_ADMINHTML) {
                        $flagDelete = false;
                        foreach ($quoteItems as $eachItem) {
                            if (in_array($eachItem->getItemId(), $removeExtraSamples) &&
                                $eachItem->getParentItemId()==null) {
                                    $itemId = $eachItem->getItemId();
                                    $quoteItem = $this->itemModel->load($itemId);
                                    $quoteItem->delete();
                                    $flagDelete = true;
                            }
                        }
                        if ($flagDelete == true) {
                            $this->cart->save();
                        }
                    }

                } catch (\Magento\Framework\Exception\LocalizedException $e) {
                    $this->logger->critical($e);
                } catch (\Exception $e) {
                    $this->logger->critical($e);
                }
            } else {
                $flagDel = false;
                foreach ($quoteItems as $eachItem) {
                    if (ceil($eachItem->getPrice()) == (int)0 && $eachItem->getFreeSample()) {
                        $itemId = $eachItem->getItemId();
                        $quoteItem = $this->itemModel->load($itemId);
                        $quoteItem->delete();
                        $flagDel = true;
                    }
                }
                if ($flagDel == true) {
                    $this->cart->save();
                }
            }
            /**
            ends
            */
        }
    }
}

How do I update the minicart count when the free items are removed from the cart?

Was it helpful?

Solution 2

I have found the solution.

I simply refreshed the quote after save cart using:

$quoteId = $quote->getId();
$getQuotebyId = $this->quoteRepository->get($quoteId);
$this->quoteRepository->save($getQuotebyId);

The updated code is:

class SamplesRemoveExtra implements ObserverInterface
{
    protected $checkoutSession;
    protected $itemModel;
    protected $ruleModel;
    protected $logger;
    protected $collectionFactory;
    protected $stockHelper;
    protected $storeManager;
    protected $cartItemFactory;
    protected $productRepository;
    protected $cart;
    protected $appState;
    protected $scopeConfig;
    protected $quoteRepository;

    public function __construct(
        \Magento\Checkout\Model\Session $checkoutSession,
        \Magento\Quote\Model\Quote\Item $itemModel,
        \Magento\SalesRule\Model\Rule $ruleModel,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $collectionFactory,
        \Magento\CatalogInventory\Helper\Stock $stockHelper,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Quote\Api\Data\CartItemInterfaceFactory $cartItemFactory,
        \Magento\Catalog\Model\ProductRepository $productRepository,
        \Magento\Checkout\Model\Cart $cart,
        \Magento\Framework\App\State $appState,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Quote\Api\CartRepositoryInterface $quoteRepository
    ) {
        $this->checkoutSession = $checkoutSession;
        $this->itemModel = $itemModel;
        $this->ruleModel = $ruleModel;
        $this->logger = $logger;
        $this->collectionFactory = $collectionFactory;
        $this->stockHelper = $stockHelper;
        $this->storeManager = $storeManager;
        $this->cartItemFactory = $cartItemFactory;
        $this->productRepository = $productRepository;
        $this->cart = $cart;
        $this->appState = $appState;
        $this->scopeConfig = $scopeConfig;
        $this->quoteRepository = $quoteRepository;
    }

    /**
     * @param Observer $observer
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $quote = $observer->getEvent()->getQuote();
        
        $quoteId = $quote->getId();
        $getQuotebyId = $this->quoteRepository->get($quoteId);

        if ($quote instanceof \Magento\Framework\Model\AbstractModel) {

            $appliedRules = [];

            $quoteItems = $quote->getAllItems();

            if (count($quoteItems) == 0) {
                return;
            }

            if ($quote->getAppliedRuleIds()) {
                $appliedRules = explode(',', $quote->getAppliedRuleIds());
            }

            /**
            CASE-2,
            if rule ids exists,
            check count of each rule id,
            if found count greater than allowed samples,
            forcily remove extra free samples
            */
            if (count($appliedRules) > 0) {
                $allowedSamplesLimit = 0;
                $cartAddedsamples = 0;
                $associatedSamples = [];
                $removeExtraSamples = [];
                $mergedAssociatedSamples = [];
                $sampleSkuArray = [];
                $i=0;

                foreach ($appliedRules as $eachRule) {
                    $ruleModel = '';
                    $ruleModel = $this->ruleModel->load($eachRule);
                    if ($ruleModel->getIsActive()) {
                        if ($ruleModel->getAutoAddtocart() != 3) { //means free, normal, deluxe
                            $sampleSkuArray[] = explode(',', $ruleModel->getAssociated());
                            $allowedSamplesLimit += (int)$ruleModel->getNumberItem();
                        } else { //means gift-regimen
                            if ($ruleModel->getPrepare()) {
                                $sampleSkuArray[] = explode(',', $ruleModel->getPrepare());
                                $allowedSamplesLimit += (int)$ruleModel->getNumberItem();
                            }
                            if ($ruleModel->getCleanse()) {
                                $sampleSkuArray[] = explode(',', $ruleModel->getCleanse());
                                $allowedSamplesLimit += (int)$ruleModel->getNumberItem();
                            }
                            if ($ruleModel->getTreat()) {
                                $sampleSkuArray[] = explode(',', $ruleModel->getTreat());
                                $allowedSamplesLimit += (int)$ruleModel->getNumberItem();
                            }

                            if ($ruleModel->getFourth()) {
                                $sampleSkuArray[] = explode(',', $ruleModel->getFourth());
                                $allowedSamplesLimit += (int)$ruleModel->getNumberItem();
                            }

                            if ($ruleModel->getFifth()) {
                                $sampleSkuArray[] = explode(',', $ruleModel->getFifth());
                                $allowedSamplesLimit += (int)$ruleModel->getNumberItem();
                            }
                        }

                        if (is_array($sampleSkuArray)) {
                            foreach ($sampleSkuArray as $eachSample) {
                                if (is_array($eachSample)) {
                                    foreach ($eachSample as $eachSku) {
                                        if ($eachSku) {
                                            $associatedSamples[] = trim($eachSku);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
        
                $mergedAssociatedSamples = array_map('strtoupper', $associatedSamples);
                $addedSampleSkus = [];

                try {
                    foreach ($quoteItems as $eachItem) {
                        if (ceil($eachItem->getPrice()) == (int)0 && $eachItem->getFreeSample()) {
                            if (in_array(strtoupper($eachItem->getSKU()), $mergedAssociatedSamples)) {
                                /**
                                important,
                                no risk for samples more than 1 qty,
                                forcily set qty 1 for free-samples
                                */
                                $eachItem->setQty(1);
                                /**
                                ends
                                */
                                $cartAddedsamples++;
                                
                                if (!$eachItem->getFreeSample() && ceil($eachItem->getPrice()) == (int)0) {
                                    $eachItem->setFreeSample(true);
                                }

                                if ($cartAddedsamples > $allowedSamplesLimit) {
                                    $removeExtraSamples[] = $eachItem->getItemId();
                                }
                            } else { //means free-sample not found in any rule and must be deleted
                                $removeExtraSamples[] = $eachItem->getItemId();
                            }
                            if (!in_array($eachItem->getSKU(), $addedSampleSkus)) {
                                $addedSampleSkus[] = $eachItem->getSKU();
                            } else {
                                //make sure, no sample can be appeared twice in cart
                                $removeExtraSamples[] = $eachItem->getItemId();
                            }
                        }
                    }
                                        
                    if ($this->appState->getAreaCode() != \Magento\Framework\App\Area::AREA_ADMINHTML) {
                        $flagDelete = false;
                        foreach ($quoteItems as $eachItem) {
                            if (in_array($eachItem->getItemId(), $removeExtraSamples) &&
                                $eachItem->getParentItemId()==null) {
                                    $itemId = $eachItem->getItemId();
                                    $quoteItem = $this->itemModel->load($itemId);
                                    $quoteItem->delete();
                                    $flagDelete = true;
                            }
                        }
                        if ($flagDelete == true) {
                            $this->cart->save();
                            $this->quoteRepository->save($getQuotebyId);
                        }
                    }

                } catch (\Magento\Framework\Exception\LocalizedException $e) {
                    $this->logger->critical($e);
                } catch (\Exception $e) {
                    $this->logger->critical($e);
                }
            } else {
                $flagDel = false;
                foreach ($quoteItems as $eachItem) {
                    if (ceil($eachItem->getPrice()) == (int)0 && $eachItem->getFreeSample()) {
                        $itemId = $eachItem->getItemId();
                        $quoteItem = $this->itemModel->load($itemId);
                        $quoteItem->delete();
                        $flagDel = true;
                    }
                }
                if ($flagDel == true) {
                    $this->cart->save();
                    $this->quoteRepository->save($getQuotebyId);
                }
            }
            /**
            ends
            */
        }
    }
}

OTHER TIPS

$quote->getQuote()
      ->setTotalsCollectedFlag(false)
      ->collectTotals()
      ->save()

Try clear cache

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top