0

I have this code for showing if my product is in stock or not.

 <?php /* @var $block \Magento\Catalog\Block\Product\View\AbstractView */?>
 <?php $_product = $block->getProduct() ?>
 <?php
 $stockstate = \Magento\Framework\App\ObjectManager::getInstance()- 
 >get('\Magento\InventorySalesApi\Api\GetProductSalableQtyInterface');
 $sale_qty = $stockstate->execute($_product->getSku(), 1);
 ?>

 <?php if ($block->displayProductStockStatus()): ?>
 <?php if ($_product->isAvailable() && $sale_qty > 0): ?>
 <div class="stock available" title="<?php /* @escapeNotVerified */ echo 
  __('Availability') ?>">
 <span><?php /* @escapeNotVerified */ echo __('In stock') ?></span>
 </div>
<?php else: ?>
    <div class="stock unavailable" title="<?php /* @escapeNotVerified */ echo __('Availability') ?>">
        <span><?php /* @escapeNotVerified */ echo __('Out of stock') ?></span>
    </div>
<?php endif; ?>

What I want to add is the number of products in stock like 1,5,7 pcs etc. So it must be that avilability in stock that needs to be changed.

Could anyone help me with that so I get the number of products in stock if more than 1 pcs in stock and if salable quantity is 0 or below it displays out of stock.

2 Answers 2

0

the reason you see 0 stock instead of "Out of stock" is because of inventory reservations. Stock is not actually deducted from saleable quantity until the order is shipped and complete. Hence, even when someone purchases all the quantity of product, the product will keep showing "In Stock" because its saleable check is still true.

You can disable the inventory reservation using Disable Stock Reservation

This should fix your issue. An alternate solution would be to add multiple checks on the front end to ensure that the product is displayed correctly. Something as follows:

app/code/Stackoverflow/ShowProductQuantity/etc/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="Stackoverflow_ShowProductQuantity">
        <sequence>
            <module name="Magento_Catalog"/>
        </sequence>
    </module>
</config>

app/code/Stackoverflow/ShowProductQuantity/registration.php

<?php
/**
 * Copyright © Magento All rights reserved.
 * See COPYING.txt for license details.
 */
use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Stackoverflow_ShowProductQuantity', __DIR__);

app/code/Stackoverflow/ShowProductQuantity/view/frontend/layout/catalog_product_view_type_simple.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="product.info.simple" template="Stackoverflow_ShowProductQuantity::product/view/type/default.phtml">
            <arguments>
                <argument name="view_model" xsi:type="object">Stackoverflow\ShowProductQuantity\ViewModel\ProductStockInfo</argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

app/code/Stackoverflow/ShowProductQuantity/view/frontend/templates/product/view/type/default.phtml

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

use Magento\Catalog\Block\Product\View\AbstractView;
use Magento\Catalog\Model\Product;
use Stackoverflow\ShowProductQuantity\ViewModel\ProductStockInfo;

?>
<?php /* @var $block AbstractView */?>
<?php
/** @var Product $_product */
$_product = $block->getProduct();

/** @var ProductStockInfo|null $viewModel */
$viewModel = $block->getViewModel();
$productQty = $viewModel->getProductSaleableQty($_product);
?>

<?php if ($block->displayProductStockStatus()) :?>
    <?php if ($_product->isAvailable() && !empty((int) $productQty)) :?>
        <div class="stock available" title="<?= $block->escapeHtmlAttr(__('Availability')) ?>">
            <span><?= $block->escapeHtml(__('In stock: %1', $productQty)) ?></span>
        </div>
    <?php else :?>
        <div class="stock unavailable" title="<?= $block->escapeHtmlAttr(__('Availability')) ?>">
            <span><?= $block->escapeHtml(__('Out of stock')) ?></span>
        </div>
    <?php endif; ?>
<?php endif; ?>

app/code/Stackoverflow/ShowProductQuantity/ViewModel/ProductStockInfo.php

<?php
declare(strict_types=1);

namespace Stackoverflow\ShowProductQuantity\ViewModel;

use Magento\Catalog\Model\Product;
use Magento\InventorySalesApi\Api\GetProductSalableQtyInterface;
use Magento\InventorySalesApi\Api\StockResolverInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Bundle\Model\Product\Type as BundleProduct;
use Magento\GroupedProduct\Model\Product\Type\Grouped as GroupedProduct;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable as ConfigurableProduct;
use Magento\Framework\View\Element\Block\ArgumentInterface;
use Magento\InventorySalesApi\Api\Data\SalesChannelInterface;

class ProductStockInfo implements ArgumentInterface
{
    /**
     * @var array
     */
    private array $complexProductTypes = [
        BundleProduct::TYPE_CODE,
        GroupedProduct::TYPE_CODE,
        ConfigurableProduct::TYPE_CODE
    ];

    /**
     * @var StoreManagerInterface
     */
    private StoreManagerInterface $storeManager;

    /**
     * @var StockResolverInterface
     */
    private StockResolverInterface $stockResolver;

    /**
     * @var GetProductSalableQtyInterface
     */
    private GetProductSalableQtyInterface $productSaleableQty;

    /**
     * @param StoreManagerInterface $storeManager
     * @param StockResolverInterface $stockResolver
     * @param GetProductSalableQtyInterface $productSaleableQty
     */
    public function __construct(
        StoreManagerInterface $storeManager,
        StockResolverInterface $stockResolver,
        GetProductSalableQtyInterface $productSaleableQty
    ) {
        $this->storeManager = $storeManager;
        $this->stockResolver = $stockResolver;
        $this->productSaleableQty = $productSaleableQty;
    }

    /**
     * @param Product $product
     * @return float|null
     */
    public function getProductSaleableQty(Product $product): ?float
    {
        try {
            $websiteCode = $this->storeManager->getWebsite()->getCode();
            $stockDetails = $this->stockResolver->execute(SalesChannelInterface::TYPE_WEBSITE, $websiteCode);
            $stockId = $stockDetails->getStockId();
            if (!in_array($product->getTypeId(), $this->complexProductTypes)) {
                return $this->productSaleableQty->execute($product->getSku(), $stockId);
            }
        } catch (\Exception $ex) {
            return null;
        }
    }
}

I would recommend disabling the stock reservation. You can also use the code that I shared as using the object manager directly is not recommended that's why I have used the view model here.

NOTE: Above code is only for showing the quantity for simple products on the PDP page as there are different layout handles for each type. The same view_model can be used to achieve the same for other types of products we just need to use the right type of layout handle and block.

Please let me know in case of any queries.

0

Have used this to show the salable quantity but the problem is that it show 0 in stock instead off out of stock.

   <?php
   /* @var $block \Magento\Catalog\Block\Product\View\AbstractView */
   $_product = $block->getProduct();
   $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
   $stockState = $objectManager- 
  >get('\Magento\InventorySalesAdminUi\Model\GetSalableQuantityDataBySku');
  $qty = $stockState->execute($_product->getSku());
  $qty = $qty[0]['qty'] < 0 ? 0 : ($qty[0]['qty'] > 25 ? '10+' : $qty[0] 
  ['qty']);
   echo "Quantity :{$qty} in stock";
  ?>
3
  • Hi Kasper, just to clarify. You need to show available quantities of the product if the product is in stock otherwise display "Out of stock". Is that correct? Nov 1, 2023 at 15:42
  • Yes. Thats correct. Nov 1, 2023 at 15:44
  • You can update this code : $qty = $qty[0]['qty'] <= 0 ? 'Out of stock' : ($qty[0]['qty'] > 25 ? '10+' : $qty[0] ['qty']); Nov 6, 2023 at 7:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.