0

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);
        }
    }
}
1

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:

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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