2

how to stop decreasing stock qty while placing an order in Magento 2 via REST API

Which plugin or which observer we have to use to stop decreasing stock qty?

I am using event "checkout_submit_all_after"

events.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
     <event name="checkout_submit_all_after">
        <observer name="stop_decrease_qty" instance="CompanyName\ModuleName\Observer\StopDecreaseQty"/>
    </event>
</config>

StopDecreaseQty.php <?php namespace CompanyName\ModuleName\Observer;

class StopDecreaseQty implements \Magento\Framework\Event\ObserverInterface
{
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
       /** @var \Magento\Quote\Model\Quote $quote */
       $quote = $observer->getEvent()->getQuote();
       $quote->setInventoryProcessed(true); //not effect inventory
       return $this;
    }
}

But it is not working

1

I have an idea for you: leave Magento to do what it does best first with all its complexity and coupled features... Then once the order is successfully placed, increment the stock for each item in the order.

Below I put an event when the order is successful, and an observer with a code that shows you how the increment stock code could work... There are still some lines of codes to add to have it fully working but hopefully, it may help you going on the right track

<?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="sales_model_service_quote_submit_success">
        <observer name="mbs_stock_order_save_after" instance="Mbs\StockTrick\Observer\OrderSaveAfter" />
    </event>


public function execute(Observer $observer)
{
    if ($this->quoteHasItems($observer)) {
        foreach ($this->getVisibleQuoteItems() as $item) {
            try {
                $this->productStockHandler->incrementStock($item);
            } catch (InvalidQuoteItem $e) {
                // possible log
            } 
        }
    }
}

I have written a full module for you. It works on my local, hopefully, it resolves your issue. Keep me posted, thanks

https://bitbucket.org/magstaging/incrementstock/src

Updated Date:- 23rd August 2021 once the order is successfully placed, increment the stock for each item in the order. you can do this easier...

Refer below Example Code:-

Vendor\ModuleName\etc\events.xml file

<?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="sales_order_save_after">
        <observer name="vendor_modulename_update_qty_with_saleable_qty" instance="Vendor\ModuleName\Observer\AfterPlaceOrderUpdateQty" />
    </event>
</config>

**

Note:- "sales_order_save_after" Event will call on every order state change, so you can use it for frontend & admin both side

**

then, Vendor\ModuleName\Observer\AfterPlaceOrderUpdateQty file

<?php 
namespace vendor\ModuleName\Observer; 
use Magento\Framework\Event\ObserverInterface;

class AfterPlaceOrderUpdateQty implements ObserverInterface 
{ 
    protected $order;
    protected $_productFactory;
    /**
     * @var Magento\CatalogInventory\Api\StockStateInterface 
     */
    protected $_stockStateInterface;

    /**
     * @var Magento\CatalogInventory\Api\StockRegistryInterface 
     */
    protected $_stockRegistry;

    private $getSalableQuantityDataBySku;

    public function __construct(
        \Magento\Sales\Model\Order $order,
        \Magento\Catalog\Model\ProductFactory $productFactory,
        \Magento\CatalogInventory\Api\StockStateInterface $stockStateInterface,
        \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
        \Magento\InventorySalesAdminUi\Model\GetSalableQuantityDataBySku $getSalableQuantityDataBySku
    ) {
        $this->order = $order;
        $this->_productFactory = $productFactory;
        $this->_stockStateInterface = $stockStateInterface;
        $this->_stockRegistry = $stockRegistry;
        $this->getSalableQuantityDataBySku = $getSalableQuantityDataBySku;
    }


    public function execute(\Magento\Framework\Event\Observer $observer) { 
        $order = $observer->getEvent()->getOrder();
        $orderId = $order->getId();
        
        $writer = new \Zend\Log\Writer\Stream(BP . '/var/log/templog.log'); //alert() || critical() || debug() || emergency() || error() || info() || log() || notice() || warning()
        $logger = new \Zend\Log\Logger();
        $logger->addWriter($writer);
        if($order->getState() == "new")
        { 
            $logger->notice("OrderId ".$orderId." state: ".$order->getState()." Order Status ".$order->getStatus());

            //$product = $this->_productFactory->create();
            foreach($order->getAllVisibleItems() as $item ) {
                $productId = $item->getProductId();
                $productSku = $item->getSku();
                $QtyOrdered = $item->getQtyOrdered();
                
                $stockItem = $this->_stockRegistry->getStockItemBySku($productSku);
                // $stockItem->setQtyCorrection($QtyOrdered); 
                //if you use setQtyCorrection($var) instead of manually set Exact Qty, then it will increase Stock Qty with Ordered Qty. 
                $stockQty = $stockItem->getQty() + $QtyOrdered;
                $stockItem->setQty($stockQty);
                $stockItem->setIsInStock((bool)$stockQty);
                $this->_stockRegistry->updateStockItemBySku($productSku, $stockItem);

                $salableArr = $this->getSalableQuantityDataBySku->execute($productSku);
                
                $logger->log("Order Items ".$productId." Product SKU: ".$productSku." Total Qty: ".$QtyOrdered."  Salaable Qty. from Database: " .$salableArr[0]['qty']."  Stock QTY. ".$stockQty);
            }

            date_default_timezone_set('Asia/Kolkata');
            $logger->info('Catched event succssfully Date: '.date('d-m-Y H:i')); 
        }
    }
    

**

Note:- You can't debug it using $echo, print_r($var), var_dump($var), echo 'console.log('.json_encode($var).')'; in sales_order_save_after event... You want to use Logger method for debug...

**

7
  • this variable $this->productStockHandler i need to declare in construct ? Jul 21 '20 at 11:22
  • i am getting when use your code - Uncaught Magento\Framework\Exception\InputException: An ID is needed. Set the ID and try again. in /var/www/html/sessions.ca/vendor/magento/module-sales/Model/OrderRepository.php:133 Jul 21 '20 at 12:42
  • do put your code and we should be able to work out what is wrong Jul 21 '20 at 12:49
  • what i have to put code ? Jul 21 '20 at 13:31
  • just the observer and the events.xml file should be sufficient Jul 21 '20 at 13:37

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.