2

I have enabled Show out of stock products in the admin Inventory section.

I have to show all in stock and out of stock products of one category(id=10 and its subcategory) in list and search result page. by hiding all out of stock products in remaining categories(But should show all in-stock products).

So when we are in category page(id is 10) need to show all in_stock and out of stock,

category page(id is not 10), Need to show only in_stock products.

If in the search result page, have to show both in_stock and out_of_stock(only from category id 10).

I used the below plugin.

Vendor\Module\etc\di.xml

<type name="Magento\CatalogSearch\Model\Search\IndexBuilder">
  <plugin name="Custom_Layernavigation::CustomLayernavigation"
  type="Vendor\Module\Plugin\CatalogSearch\Model\Search\IndexBuilder" />
</type>

Then Vendor\Module\Plugin\CatalogSearch\Model\Search\IndexBuilder.php

<?php
use Magento\Framework\Search\RequestInterface;

class IndexBuilder {    
protected $_request;
protected $_categoryHelper;
 protected $_logger;

public function __construct(
    \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
    \Magento\Catalog\Helper\Category $categoryHelper,
    \Magento\Framework\App\Request\Http $request,
    \Psr\Log\LoggerInterface $logger
) {
    $this->_productCollectionFactory   = $productCollectionFactory;
    $this->_categoryHelper = $categoryHelper;
    $this->_request = $request;
    $this->_logger = $logger;
}

public function aroundBuild($subject, callable $proceed, RequestInterface $request) {
    $select = $proceed($request);

    $collection = $this->_productCollectionFactory->create();
    $collection->addAttributeToSelect('*');     
    $collection->joinField(
        'qty', 'cataloginventory_stock_item', 'qty', 'product_id=entity_id', '{{table}}.stock_id=1', 'left'
    );
    $collection->addAttributeToFilter('qty',['gt'=>0])->load();
    $collection->getSelect()
        ->join(array('cat_index'=> 'catalog_category_product_index_store1'), "cat_index.product_id = e.entity_id")
        ->where('cat_index.category_id <> 10');

    return $select;
  }
}

Can someone update me on how to implement this functionality? I am unable to write a join query to match the above requirement. Please check and update me about this. Thanks for the help.

1

If you're using magento 2.4 then you have to create a plugin for

Magento\Catalog\Model\Layer

We have to set the Go to Stores > Configuration > Catalog > Inventory > Stock Options->Display Out of Stock Products. This is necessary because Magento doesn't load the is_in_stock filters when we set this option to 'NO'. So we can't put our custom work/conditions when it sets to NO I've debugged it completely and well , So first we have to set it to YES , then I've created a plugin for Magento\Catalog\Model\Layer`and I've handled in such a way that it is now working properly. 1- The Out Of Stock and In Stock products will be shown for specified category 2- Other all the categories of the store will only show InStock products according to our requirement.

The code is below:

 public function aroundPrepareProductCollection(CatalogLayer $subject, \Closure $proceed, $collection)
{
    // Getting current category Id
    $categoryId = $subject->getCurrentCategory()->getId();
    // Getting specified category whom we wann show OOS products
    $showAllCategoryId = $this->displayBoth->getShowAllCategoryId();

    if($categoryId == $showAllCategoryId) {
        //Get Out Of Stock Products and also In Stock Products of the specified category
        $collection->addFieldToSelect('*')
            ->setFlag('has_stock_status_filter', true)
            ->joinField('stock_item', 'cataloginventory_stock_item', 'is_in_stock', 'product_id=entity_id',
                'is_in_stock=0 || is_in_stock=1');
        // Apply to the collection
        $collection->addCategoriesFilter(['eq' => $categoryId]); // Current category filter, it's not require, because PrepareProductCollection() automatically apply filter for current category.
    }else{
        //Get only In Stock products to the all the categories instead of above specified one
        $collection->addFieldToSelect('*')
            ->setFlag('has_stock_status_filter', true)
            ->joinField('stock_item', 'cataloginventory_stock_item', 'is_in_stock', 'product_id=entity_id',
                'is_in_stock=1');
        //Apply to the collection
        $collection->addCategoriesFilter(['eq' => $categoryId]);
    }
    return $proceed($collection);
}

This has been tested well and working fine for Magento 2.4 EE and CE

0

Try to do using afterPlugin method by this below way :

<?php

namespace Vendor\Module\Plugin\CatalogSearch\Model\Search;

class IndexBuilder
{
    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $storeManager;

    public function __construct(
        \Magento\Store\Model\StoreManagerInterface $storeManager
    ) {
        $this->storeManager = $storeManager;
    }

    public function afterBuild($subject, $result)
    {
        if(your_category_id){
            $connection = $result->getConnection();
            $result->joinLeft(
                ['stock_status_filter' => $connection->getTableName('cataloginventory_stock_status')],
                'search_index.entity_id = stock_status_filter.product_id'
                . $connection->quoteInto(
                    ' AND stock_status_filter.website_id IN (?, 0)',
                    $this->storeManager->getWebsite()->getId()
                ),
                []
            );
            return $result;
        } else {
            return $result;
        }
    }
}

Make sure display out of stock products configuration enabled.

Hope, Maybe it's helpful for you.

5
  • hi @Rohan, Thanks for the answer, but the above code may work only for category page, I can use registry and get the current category and use it, but in search result page this will fail, this will not come inside if condition Feb 26 '20 at 4:59
  • Okay. wait please. Feb 26 '20 at 5:16
  • Did you created any plugin for Magento\Catalog\Model\Layer ? Feb 26 '20 at 5:20
  • No i have not created any plugin for that? But i am using Bss layered navigation extension, they have re-written it Feb 26 '20 at 5:22
  • Also I checked ur code now only for categories, problem is out of stock products showing for all other categories also we have to show only in_stock for other categories except one category(there both in_stock and out_of_stock) should show Feb 26 '20 at 5:52

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.