Search

May 14, 2024

Magento 2.4 product stock status not change after salable quantity become zero

 From Niraj Patel issue: 

I tried the below scenario in Magento 2.4.0 version

Anyone please try the below scenario in your Magento 2.4 version ?

I created one configurable product and it's two simple children with 100 qty.

Before Order place: I went to Admin Product Grid there are two columns Quantity and Salable Quantity. One child product has 100 Quantity and Salable Quantity are 100

After Placed order: In Admin product grid, same child product has salable quantity is 0 and quantity column shows 100 quantity and when I went product edit page it still shows in stock status even no backorders and Manages stock set to yes and I did reindex.

Expected Result: when the product becomes zero salable quantity it should automatically change stock status out of stock

Actual Result: when the product becomes zero salable quantity it does not change stock status from in stock to `out of stock

Anyone faces above issue in your Magento 2.4 version ?

____________________

My SOLUTION: 
Create Lexim_InventoryConfigurableProduct extension


etc/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\Inventory\Model\SourceItem\Command\DecrementSourceItemQty">
        <plugin name="update_parent_configurable_product_stock_status_in_legacy_stock" disabled="true"/>
        <plugin name="update_parent_configurable_product_stock_status_in_legacy_stock_fix" type="Lexim\InventoryConfigurableProduct\Plugin\InventoryApi\UpdateParentStockStatusInLegacyStockPlugin"/>
    </type>
</config>



Plugin\InventoryApi\UpdateParentStockStatusInLegacyStockPlugin.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Lexim\InventoryConfigurableProduct\Plugin\InventoryApi;

use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Inventory\Model\SourceItem\Command\DecrementSourceItemQty;
use Magento\InventoryApi\Api\Data\SourceItemInterface;
use Magento\InventoryCatalogApi\Api\DefaultSourceProviderInterface;
use Magento\InventoryCatalogApi\Model\GetProductIdsBySkusInterface;
use Magento\ConfigurableProduct\Model\Inventory\ChangeParentStockStatus;

/**
 * Apply a fix for update configurable product stock status in legacy stock
 * after decrement quantity of child stock item
 */
class UpdateParentStockStatusInLegacyStockPlugin
{
    /**
     * @var DefaultSourceProviderInterface
     */
    private $defaultSourceProvider;

    /**
     * @var ChangeParentStockStatus
     */
    private $changeParentStockStatus;

    /**
     * @var GetProductIdsBySkusInterface
     */
    private $getProductIdsBySkus;

    /**
     * @param DefaultSourceProviderInterface $defaultSourceProvider
     * @param GetProductIdsBySkusInterface $getProductIdsBySkus
     * @param ChangeParentStockStatus $changeParentStockStatus
     */
    public function __construct(
        DefaultSourceProviderInterface $defaultSourceProvider,
        GetProductIdsBySkusInterface $getProductIdsBySkus,
        ChangeParentStockStatus $changeParentStockStatus
    ) {
        $this->defaultSourceProvider = $defaultSourceProvider;
        $this->getProductIdsBySkus = $getProductIdsBySkus;
        $this->changeParentStockStatus = $changeParentStockStatus;
    }

    /**
     * Make configurable product out of stock if all its children out of stock
     *
     * @param DecrementSourceItemQty $subject
     * @param void $result
     * @param SourceItemInterface[] $sourceItemDecrementData
     * @return void
     * @throws NoSuchEntityException
     */
    public function afterExecute(DecrementSourceItemQty $subject, $result, array $sourceItemDecrementData): void
    {
        $productIds = [];
        $sourceItems = array_column($sourceItemDecrementData, 'source_item');

        /** @var SourceItemInterface $sourceItem */
        foreach ($sourceItems as $sourceItem) {
            $sku = $sourceItem->getSku();
            if ($sourceItem->getSourceCode() === $this->defaultSourceProvider->getCode()
                && $productId = ($this->getProductIdsBySkus->execute([$sku])[$sku] ?? null)
            ) {
                $productIds[] = (int) $productId;
            }
        }

        if ($productIds) {
            $this->changeParentStockStatus->execute($productIds);
        }
    }
}



registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Lexim_InventoryConfigurableProduct',
    __DIR__
);



module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Lexim_InventoryConfigurableProduct" setup_version="1.0.0" />
</config>





No comments:

Post a Comment