0

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?

2
  • $itemId = $item->getData('item_id'); $helper->getCart()->removeItem($itemId)->save(); If this does not work $quote->getQuote()->setTotalsCollectedFlag(false) ->collectTotals() ->save(); Add this ofter cart save. Commented Apr 26, 2021 at 11:42
  • I tried both but it did not work.
    – mechanic
    Commented Apr 27, 2021 at 10:08

2 Answers 2

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
            */
        }
    }
}
0
$quote->getQuote()
      ->setTotalsCollectedFlag(false)
      ->collectTotals()
      ->save()

Try clear cache

3
  • I tried your code but it is not working.
    – mechanic
    Commented Apr 27, 2021 at 10:07
  • Do you use Luma or other custom theme? try switch to Luma. Are you using module for ajax add to cart / mini cart delete? If yes, then disable it and check it Commented Apr 28, 2021 at 7:05
  • No I am not using any custom theme or module for ajax add to cart / minicart delete.
    – mechanic
    Commented Apr 28, 2021 at 8:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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