3

I do not want to merge cart items if the user has items in cart and logs into the site.

Let's go through the scenario:

  1. User logs in and adds one item to cart and logs out from a site.
  2. Now as a guest user he adds 2 items to cart.
  3. He logs in into the site again and sees 3 items.

What I am trying to achieve ?: What I want to do is, when he logs in to the site, item which was there in his cart before logging-in should not be merged and after logging in, he should see only 1 item in the cart.

I have observed sales_quote_merge_before event as given below and deleted the guest-user-quote, still, these items are visible in cart after loggin-in.

etc/frontend/events.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="sales_quote_merge_before">
        <observer name="validate_quote_befor_merge" instance="Vendor\Module\Observer\QuoteBeforeMerge" />
    </event>
</config>

QuoteBeforeMerge.php

<?php

namespace Vendor\Module\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Quote\Model\QuoteRepository;

class QuoteBeforeMerge implements ObserverInterface
{

    /**
     * @var QuoteRepository
     */
    private $quoteRepository;

    public function __construct(
        QuoteRepository $quoteRepository
    )
    {
        $this->quoteRepository = $quoteRepository;
    }

    /**
     * @param Observer $observer
     * @return void
     */
    public function execute(Observer $observer)
    {
        if ($observer->getSource()->hasItems()) {
            $currentQuote = $observer->getSource();
            $quoteId = $currentQuote->getId();
            $quote = $this->quoteRepository->get($quoteId);
            $this->quoteRepository->delete($quote);
        }
    }
}
0

1 Answer 1

3

You should remove the items from the quote object passed to the observer because that's what is used in the merge method. The quote isn't loaded from repository again after your code has been executed. Add the following code into your execute method:

// If you want to remove guest cart item from merged cart
//event: sales_quote_merge_after
$currentQuote = $observer->getSource();


// If you want to remove customer (old) cart item from merged cart
//event: sales_quote_merge_before
$currentQuote = $observer->getQuote();

foreach ($currentQuote->getAllVisibleItems() as $item) {
    $currentQuote->removeItem($item->getId());
}
//alternatively this should also work:
$currentQuote->removeAllItems();

I guess the delete operation in the repository doesn't update the quote items collection of the actual quote object.

1
  • The suggested edit from Arshad M may make sense if the logic should also be used in the event sales_quote_merge_after and not only as asked in the question in sales_quote_merge_before therefore I will let the edit pass.
    – HelgeB
    Commented Oct 9, 2020 at 7:42

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.