Magento2 – How to Update Cart After checkout_cart_update_items_after Event

cartevent-observermagento-2.1quote

I am trying tho again update cart after update cart action(when cart qty is updated from cart page Or from miniCart) and change the qty if some cases

$mappedProductSkus= $this->_helperData->getSku();
        $cartData=[];
        foreach($quote->getAllVisibleItems() as $item)
        {
            $productSku=$item->getSku();
            $productAdded = $this->_productRepository->get($productSku);

            if(in_array($productSku, $mappedProductSkus ))
            {
                $itemQty= $item->getQty();
                $allocatedQty = $this->_helperData->finalQty($productSku,$itemQty);
                $itemId= $item->getId();
                $cartData[$itemId]['qty'] = $allocatedQty;
                if($allocatedQty<$itemQty){
                    $this->_messageManager->addNoticeMessage('Max Qty of '.$allocatedQty.' can be added to cart for'.$productAdded->getName());
                }
            }
            else
            {
                $itemId= $item->getId();
                $cartData[$itemId]['qty'] = 1;
                if($item->getQty()>1){
                $this->_messageManager->addNoticeMessage('Only one item can be bought at a time );
                }
            }
        }
        $cartData = $this->_cart->suggestItemsQty($cartData);
        $this->_cart->updateItems($cartData)->save();

But as we call updateItems it again triggers checkout_cart_update_items_after and the code goes in infinite loop

event.xml

<event name="checkout_cart_update_items_after">
        <observer name="checkbeforeupdate" instance="Fleetguard\Inventoryrationing\Observer\Checkbeforeupdate" />
    </event>

Best Answer

I ended up using plugin 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="interceptUpdateProductToCart" type="Mycompany\Inventory\Plugin\Rationingcheck"/>
    </type>
</config>

Rationingcheck.php

<?php
namespace Mycompany\Inventoryrationing\Plugin;
use \Magento\Framework\Message\ManagerInterface ;
use Myvendor\Inventoryrationing\Helper\Rationinglogic;


class Rationingcheck
{
    /**
     * @var Rationinglogic|Data
     */
    protected $_helperData;

    /**
     * @var ManagerInterface
     */
    protected $_messageManager;

    /**
     * @var \Magento\Quote\Model\Quote
     */
    protected $quote;

    /**
     * Plugin constructor.
     *
     * @param \Magento\Checkout\Model\Session $checkoutSession
     */
    public function __construct(
        \Magento\Checkout\Model\Session $checkoutSession,
        Rationinglogic $helperData,
        ManagerInterface $messageManager
    ) {
        $this->quote = $checkoutSession->getQuote();
        $this->_helperData = $helperData;
        $this->_messageManager = $messageManager;
    }

    /**
     * @param \Magento\Checkout\Model\Cart $subject
     * @param $data
     * @return array
     */
    public function beforeupdateItems(\Magento\Checkout\Model\Cart $subject,$data)
    {
        $quote = $subject->getQuote();
        $mappedProductSkus= $this->_helperData->getSku();
        foreach($data as $key=>$value){
            $item = $quote->getItemById($key);
             $productSku= $item->getSku();
              $itemQty= $value['qty'];
                if(Condition ))
                {
                    $data[$itemId]['qty'] = 1;
                    if($item->getQty()>1){
                        $this->_messageManager->addNoticeMessage('Only one item can be bought at a time');
                    }
                }

        }
        return [$data];

    }
}