0

I want to restrict per order qty of any product to 50, In other words, I don't want to allow users to purchase more than 50 items of any product in one order from my store.

So, I know qty can be changed by repeatedly clicking Add to Cart button or by changing qty directly from the cart (mini-cart or cart page). To detect these events I have two observers, one that observes checkout_cart_product_add_after (if a product is added to cart) and the second observer observes checkout_cart_update_items_after (the cart update event).

Now, if the qty exceeds allowed limit I want to show an error message to the user like below.

The maximum allowed qty for LG G5 Handset is 50

Here is my /app/code/TahirYasin/CartCheck/etc/frontend/events.xml

<?xml version="1.0"?>
<config 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="checkout_cart_update_items_after">
        <observer
            name="TahirYasin_CartCheck_observer_cart_update_items_after"
            instance="TahirYasin\CartCheck\Observer\CartUpdateItemsAfter" />
    </event>
    <event name="checkout_cart_product_add_after">
        <observer
            name="TahirYasin_CartCheck_observer_cart_product_add_after"
            instance="TahirYasin\CartCheck\Observer\CartProductAddAfter" />
    </event>
</config>

Here is my /app/code/TahirYasin/CartCheck/Observer/CartUpdateItemsAfter.php

<?php

namespace TahirYasin\CartCheck\Observer;

use TahirYasin\CartCheck\Helper\Data as HelperData;
use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\App\Response\RedirectInterface;
use Magento\Framework\Message\ManagerInterface as MessageManager;

class CartUpdateItemsAfter implements ObserverInterface
{

    protected $checkoutSession;

    public function __construct(
        HelperData $helper,
        ResponseInterface $response,
        RedirectInterface $redirect,
        MessageManager $messageManager
    )
    {
        $this->helper = $helper;
        $this->_response = $response;
        $this->_redirect = $redirect;
        $this->messageManager = $messageManager;
    }

    /**
     * @param EventObserver $observer
     * @return void
     */
    public function execute(EventObserver $observer)
    {

        if ($this->helper->isActive()) {
            foreach ($observer->getCart()->getQuote()->getAllVisibleItems() as $item) {
                if ($item->getParentItem()) {
                    $item = $item->getParentItem();
                }
            }
        // check if product qty doesn't exceed 50, if it does show error
            $allowedQty = 50;
            if ($item->getQty() > $allowedQty) {
                $this->messageManager->addError(
                        sprintf(__('The maximum allowed qty for %s is %d.'), $item->getName(), $allowedQty)
                );
                $this->_response->setRedirect($this->_redirect->getRefererUrl())->sendResponse();
                exit;
            }
        }
    }

}

Here is my /app/code/TahirYasin/CartCheck/Observer/CartProductAddAfter.php

<?php

namespace TahirYasin\CartCheck\Observer;

use TahirYasin\CartCheck\Helper\Data as Helper;
use Magento\Framework\Event\Observer as EventObserver;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\App\Response\RedirectInterface;
use Magento\Framework\Message\ManagerInterface as MessageManager;

class CartProductAddAfter implements ObserverInterface
{

    public function __construct(
        Helper $helper,
        ResponseInterface $response,
        RedirectInterface $redirect,
        MessageManager $messageManager
    )
    {
        error_reporting(E_ALL);
        ini_set('display_errors', 'On');
        $this->_helper = $helper;
        $this->_response = $response;
        $this->_redirect = $redirect;
        $this->messageManager = $messageManager;
    }

    /**
     * @param EventObserver $observer
     * @return $this
     */
    public function execute(EventObserver $observer)
    {
        if ($this->_helper->isActive()) {
            $item = $observer->getQuoteItem();
            if ($item->getParentItem()) {
                $item = $item->getParentItem();
            }

        // check if product qty doesn't exceed 50 if it does show error
            $allowedQty = 50;
            if ($item->getQty() > $allowedQty) {
                $this->messageManager->addError(
                        sprintf(__('The maximum allowed qty for %s is %d.'), $item->getName(), $allowedQty)
                );
                $this->_response->setRedirect($this->_redirect->getRefererUrl())->sendResponse();
                exit;
            }
        }
    }

}

Test Case 1 (Failed): - 50 items of the product already added in the cart. Now, when I click Add to cart button, the button text changes to 'Adding...', no error shows and the button keeps displaying 'Adding...' and remains disabled forever.

add to cart

Expectation: Add to Cart button should get back to its normal state and error should display if the product qty exceeds 50.

Test Case 2 (Failed): When I put 60 in Qty box from the mini cart and hit the Update button, they qty revert to previous value 50 (this is fine) but no error displays on the page.

mini cart

Expectation: The error should be displayed if item qty is greater than 50.

Test Case 3 (Passed): When I put 60 in Qty box from shopping cart page and hit 'Update Shopping Cart' button, the page reloads and shows error The maximum allowed qty for LG G5 Handset is 50.. So only this part is working correctly.

Expectation: It works according to my expectation.

Add to Cart button and Update button in mini cart use AJAX and I guess that is why the redirection part doesn't work and no error displays whereas Update Shopping Cart button does a simple form post (without ajax) so it works fine.

Any solution, please?

  • remove exit;from code – Amit Bera Oct 11 '17 at 12:41
  • @AmitBera Thanks for your response. If I remove exit, it doesn't restrict qty to be <=50, I clicked Add to Cart and it added 51st product in cart that is wrong. Also the Add to Cart button not coming back to normal form, also no error or success message appears, mini cart also allows qty beyond limit. Shopping cart page also allows beyond limit and now it shows both success and error messages. – Tahir Yasin Oct 11 '17 at 13:05
  • 1
    @TahirYasin I think every product Advanced Inventory have Maximum Qty Allowed in Shopping Cart option, So you can save that option to 50. – Bojjaiah Oct 12 '17 at 5:47

Your Answer

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

Browse other questions tagged or ask your own question.