Magento 2.4.2. Mini cart count not updating after free product remove on update cart button click
-
11-05-2021 - |
문제
When total price is above $200 cart price rule is applied and free products are added to the cart.
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.
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
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
*/
}
}
}
다른 팁
$quote->getQuote()
->setTotalsCollectedFlag(false)
->collectTotals()
->save()
Try clear cache
제휴하지 않습니다 magento.stackexchange