Ограничить добавление в корзину только одним товаром в корзину в magento 2


Как ограничить корзину в magento только одним товаром на одного клиента?

Author: Bhargav Mehta, 2017-07-27

3 answers

Хотя решение, предоставленное @Jigs-Parmar, также должно работать, вы также можете сделать это с помощью плагина.

Ниже приведены основные шаги:

App/code/SR/Stackexchange/etc/frontend/di.xml


<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Model\Cart">
        <plugin name="SR_Stackexchange::add_to_cart" type="SR\Stackexchange\Plugin\Checkout\Model\Cart" sortOrder="1"/>
    </type>
</config>

App/code/SR/Stackexchange/Plugin/Checkout/Model/Cart.php


namespace SR\Stackexchange\Plugin\Checkout\Model;

use Magento\Catalog\Model\Product;

class Cart
{
    /**
     * @var \Magento\Checkout\Model\Session
     */
    protected $checkoutSession;

    /**
     * Cart constructor.
     *
     * @param \Magento\Checkout\Model\Session $checkoutSession
     */
    public function __construct(
        \Magento\Checkout\Model\Session $checkoutSession
    ) {
        $this->checkoutSession = $checkoutSession;
    }

    /**
     * @param \Magento\Checkout\Model\Cart $subject
     * @param \Closure $proceed
     * @param $productInfo
     * @param null $requestInfo
     * @return mixed
     */
    public function aroundAddProduct(
        \Magento\Checkout\Model\Cart $subject,
        \Closure $proceed,
        $productInfo,
        $requestInfo = null
    ) {

        if ($productInfo instanceof Product) {
            $productId = $productInfo->getId();
        } elseif (is_int($productInfo) || is_string($productInfo)) {
            $productId = $productInfo;
        } else {
            return $proceed($productInfo, $requestInfo);
        }

        $isSameProduct = 0;
        $quote = $this->checkoutSession->getQuote();
        $items = $quote->getAllItems();
        foreach ($items as $item) {
            if($productId == $item->getProductId()) {
                $isSameProduct = 1;
                break;
            }
        }

        if($isSameProduct) {
            return $proceed($productInfo, $requestInfo);
        }

        $quote->removeAllItems()->save();
        return $proceed($productInfo, $requestInfo);
    }
}

Теперь вам нужно изменить при объединении цитату после входа в систему:

App/code/SR/Stackexchange/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="SR_Stackexchange_sales_quote_merge_before" instance="SR\Stackexchange\Observer\SalesQuoteMergeBefore"/>
    </event>
</config>

App/code/SR/Stackexchange/Observer/SalesQuoteMergeBefore.php


namespace SR\Stackexchange\Observer;

use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Event\ObserverInterface;

class SalesQuoteMergeBefore implements ObserverInterface
{
    /**
     * Avoid shopping carts merging on customer login
     *
     * @param EventObserver $observer
     */
    public function execute(EventObserver $observer)
    {
        if ($observer->getSource()->hasItems()) {
            $currentQuote = $observer->getSource();
            $productId = 0;
            foreach ($currentQuote->getAllVisibleItems() as $item) {
                $productId = $item->getProductId();
            }

            if (is_object($observer->getQuote()) && $observer->getQuote()->getId()) {
                $oldQuote = $observer->getQuote();
                $hasSameProduct = 0;
                foreach ($oldQuote->getAllVisibleItems() as $item) {
                    if($productId == $item->getProductId()) {
                        $hasSameProduct = 1;
                    }
                }
                if($hasSameProduct == 0) {
                    $observer->getQuote()->removeAllItems();
                }
            }
        }
    }
}

Очистить кэш.

Примечание: Вы можете изменить 'SR/Stackexchange' свое собственное имя модуля

Примечание: Я предполагаю, что вы хотите удалять последний добавленный товар каждый раз, когда в корзину добавляется новый товар. Пожалуйста, внесите необходимые изменения в класс плагина, если вы хотите сохранить старый элемент и показать клиенту только сообщение о том, что новый элемент не может быть добавлен.

Дайте мне знать, если это не так работайте или если у вас есть запрос.

 3
Author: Mohit Kumar Arora, 2018-05-29 10:00:22

Поскольку ответ не принимается, около плагинов (используемых в ответе Мохита) не рекомендуется Magento, и ответ Джигса кажется чрезмерным и может не сработать, если другие расширения подключаются к тому же наблюдателю, я решил поделиться своим собственным ответом.

Я предполагаю, что вы знаете, как построить основы модуля (registration.php, module.xml, и т.д.)

Этот модуль перенаправляет пользователя в корзину и показывает ошибку, предлагая пользователю сначала завершить этот заказ и разместить другой.

Daan/LimitCartItems/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="controller_action_predispatch_checkout_cart_add">
        <observer name="daan_limit_items_in_cart_checkout_before" instance="Daan\LimitCartItems\Observer\Checkout\Cart\Add" />
    </event>
</config>

Daan/LimitCartItems/Observer/Checkout/Cart/Add.php

<?php

namespace Daan\LimitCartItems\Observer\Checkout\Cart;

use Magento\Checkout\Model\Session;
use Magento\Framework\App\ActionFlag;
use Magento\Framework\App\Response\RedirectInterface as ResponseRedirect;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Message\ManagerInterface as MessageManager;

class Add implements ObserverInterface
{
    /** @var Session $session */
    private $session;

    /** @var ActionFlag $flag */
    private $flag;

    /** @var ResponseRedirect $redirect */
    private $redirect;

    /** @var MessageManager $messageManager */
    private $messageManager;

    /**
     * Add constructor.
     *
     * @param Session          $session
     * @param ActionFlag       $flag
     * @param ResponseRedirect $redirect
     * @param MessageManager   $messageManager
     */
    public function __construct(
        Session $session,
        ActionFlag $flag,
        ResponseRedirect $redirect,
        MessageManager $messageManager
    ) {
        $this->session         = $session;
        $this->flag            = $flag;
        $this->redirect        = $redirect;
        $this->messageManager  = $messageManager;
    }

    /**
     * @param Observer $observer
     *
     * @return $this|void
     * @throws \Magento\Framework\Exception\LocalizedException
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function execute(Observer $observer)
    {
        $quote      = $this->session->getQuote();
        $itemsCount = $quote->getItemsCount();

        if ($itemsCount >= 1) {
            $request = $observer->getRequest();
            $request->setParams([
                'product'    => false,
                'return_url' => $this->redirect->getRefererUrl(),
                'backUrl'    => $this->redirect->getRefererUrl()
            ]);

            $this->messageManager->addErrorMessage(
                __('Only one product per purchase allowed. Please complete this order first and place another order afterwards.')
            );

            $action = $observer->getEvent()->getControllerAction();
            $this->flag->set('', \Magento\Framework\App\ActionInterface::FLAG_NO_DISPATCH, true);
            $action->getResponse()->setRedirect('/checkout/cart');

            return $this;
        }
    }
}
 1
Author: Daan van den Bergh, 2020-03-16 14:36:01

Создать event.xml файл в папке etc

И напишите ниже код

<event name="controller_action_predispatch_checkout_cart_add">
      <observer name="restrict_sales_model_cart_add_before" instance="Vendor\Module\Observer\Cartadd" />
  </event>

Теперь создайте Cartadd.php в папке Obsever

<?php
namespace Vendor\Module\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;

class Cartadd implements ObserverInterface {

    protected $_urlManager;
    protected $_checkoutSession;
    protected $_cart;
    protected $_messageManager;
    protected $_redirect;
    protected $_request;
    protected $_response;
    protected $_responseFactory;
    protected $_resultFactory;
    protected $_scopeConfig;
    protected $_product;

    public function __construct(\Magento\Framework\UrlInterface $urlManager, \Magento\Checkout\Model\Session $checkoutSession, \Magento\Framework\App\Response\RedirectInterface $redirect, \Magento\Checkout\Model\Cart $cart, \Magento\Framework\Message\ManagerInterface $messageManager, \Magento\Framework\App\RequestInterface $request, \Magento\Framework\App\ResponseInterface $response, \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Catalog\Model\Product $product, \Magento\Framework\App\ResponseFactory $responseFactory, \Magento\Framework\Controller\ResultFactory $resultFactory
    ) {
        $this->_urlManager = $urlManager;
        $this->_checkoutSession = $checkoutSession;
        $this->_redirect = $redirect;
        $this->_cart = $cart;
        $this->_messageManager = $messageManager;
        $this->_request = $request;
        $this->_response = $response;
        $this->_responseFactory = $responseFactory;
        $this->_resultFactory = $resultFactory;
        $this->_scopeConfig = $scopeConfig;
        $this->_product = $product;
    }

    public function execute(\Magento\Framework\Event\Observer $observer) {

        $controller = $observer->getControllerAction();
        $postValues = $this->_request->getPostValue();
        $cartQuote = $this->_cart->getQuote()->getData();
        $cartItemsCount = $this->_cart->getQuote()->getItemsCount();
        $cartItemsAll = $this->_cart->getQuote()->getAllItems();

        if($cartItemsCount > 0)
        {
            $observer->getRequest()->setParam('product', false);
            $observer->getRequest()->setParam('return_url', $this->_redirect->getRefererUrl());
            $observer->getRequest()->setParam('backUrl', $this->_redirect->getRefererUrl());
            $this->_messageManager->addError(__('Only 1 product Allowed to Purchase at a time.'));
        }
    }
}
 0
Author: Jigs Parmar, 2018-05-29 09:24:45