Skip to content

Magento 2 Saleable Qty breaks paging in tile.phtml

I have created a new extension to get a product’s Saleable Quantity and Out of Stock Threshold to display in the category visual merchandiser.

I am able to get this data to display; however, when I try to go to page 2, the next set of products do not display. It continues to stay on page 1.

screen capture of quantity counts

Here is my code:

app/code/Vendor/VisualMerchandiser/Helper/Data.php

<?php

namespace VendorVisualMerchandiserHelper;

use MagentoFrameworkAppHelperAbstractHelper;
use MagentoFrameworkAppHelperContext;
use MagentoInventorySalesAdminUiModelGetSalableQuantityDataBySku;
use MagentoCatalogInventoryApiStockRegistryInterface;
use MagentoCatalogModelProductRepository;

class Data extends AbstractHelper
{
private $getSalableQuantityDataBySku;

private $getStockItemRepository;

protected $productRepository;

public function __construct(
    Context $context,
    GetSalableQuantityDataBySku $getSalableQuantityDataBySku,
    StockRegistryInterface $getStockItemRepository,
    ProductRepository $productRepository
){
    $this->getSalableQuantityDataBySku = $getSalableQuantityDataBySku;
    $this->getStockItemRepository = $getStockItemRepository;
    $this->productRepository = $productRepository;
    parent::__construct($context);
}

public function getProductSalableQty($sku)
{
    try {
        $salable = $this->getSalableQuantityDataBySku->execute($sku);
        return $salable[0]['qty'];
    } catch (MagentoFrameworkExceptionNoSuchEntityException $e) {
        return '0';
    }
}

public function getProductStockQtyThreshold($productId) {
    $stockQty = $this->getStockItemRepository->getStockItem($productId);
    return $stockQty->getMinQty();
}

public function getProductStatus($productId)
{
    try {
        $product = $this->productRepository->getById($productId);
        return $product->getStatus();
    } catch (MagentoFrameworkExceptionNoSuchEntityException $e) {
        return null;
    }
}
}

app/design/adminhtml/Vendor/AdminTheme/Magento_VisualMerchandiser/templates/category/merchandiser/tile.phtml

<ul id="catalog_category_merchandiser_list" class="catalog-category-merchandiser-list">
  <?php foreach ($block->getCollection() as $_index => $_product): ?>
  <?php /** @var MagentoCatalogModelProduct $_item */ ?>
  <?php
    $productStatus = $_outputhelper->getProductStatus($_product->getID());
    $saleQuantity = $_outputhelper->getProductSalableQty($_product->getSku());
    $oosThreshold = $_outputhelper->getProductStockQtyThreshold($_product->getId());
    // if item status is disabled add class to gray out tile
    if ($productStatus == 2) {
      $oosClass = 'item-disabled';
    } elseif ($oosThreshold <= '0.0000') {
       $oosClass = 'item-oos';
    } else {
       $oosClass = '';
    }?>
    <li class="product_tile <?= /* @noEscape */ $oosClass ?>">
       <?php echo $saleQuantity . '*' . $oosThreshold; ?>
       <div class="controlbar-top">
         <a href="#" class="icon-gripper"><span><?= $block->escapeHtml(__('Draggable')) ?></span></a>
         <a href="#" class="remove-product icon-close-mage"><span><?= $block->escapeHtml(__('Close')) ?></span></a>
       </div>
       <div class="image-holder">
          <img src="<?= $block->escapeUrl($block->getImageUrl($_product)) ?>" alt="<?= $block->escapeHtmlAttr(__('Product image')) ?>" />
       </div>

       <div class="info-block">
         <?php foreach ($block->getAttributesToDisplay($_product) as $attribute): ?>
           <?= /* @noEscape */ $attribute->render() ?>
         <?php endforeach; ?>
        </div>
     <div class="controlbar-bottom">
        <div class="position">
          <label for="id_position_<?= $block->escapeHtmlAttr($_index) ?>"><?= $block->escapeHtml(__('Position')) ?></label>
          <div>
             <a href="#" class="move-top icon-backward"><span><?= $block->escapeHtml(__('Top')) ?></span></a>
            <input type="text" name="position" id="id_position_<?= $block->escapeHtmlAttr($_index) ?>" value="<?= $block->escapeHtmlAttr($_product->getPosition()) ?>" />
           <a href="#" class="move-bottom icon-forward"><span><?= $block->escapeHtml(__('Bottom')) ?></span></a>
        </div>
      </div>
        <input type="hidden" name="entity_id" value="<?= $block->escapeHtmlAttr($_product->getId()) ?>" />
     </div>
  </li>
  <?php endforeach; ?>
</ul>

Am I missing something to get this to page properly?

When I comment out the line that gets the $saleQuantity, I am able to go to page 2 and so on.

Ultimately, I want my new if/else in the tile.phtml file to look something like this:

if ($productStatus == 2) {
   $oosClass = 'item-disabled';
} elseif ($saleQuantity <= $oosThreshold) {
   $oosClass = 'item-oos';
} else {
   $oosClass = '';
}