Question

Hi @all actually i wanted to display Out of stock products only in one category(Parent Category and it's all child categories) with "Display Out Of Stock" option "Yes" in the admin?

It means here i need to hide Out of stock products for all rest of the categories.

Here i tried to follow this link

If Anyone having any idea please help here. Thanks in Advance.

Was it helpful?

Solution 2

Vendor\Module\etc\di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\CatalogSearch\Model\Search\IndexBuilder">
       <plugin name="Custom_Layernavigation::CustomLayernavigation"
       type="Vendor\Module\Plugin\CatalogSearch\Model\Search\IndexBuilder" />
    </type>
</config>

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

<?php

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

use Magento\Framework\DB\Select;
use Magento\Framework\Search\Request\FilterInterface;
use Magento\Framework\Search\Request\Filter\BoolExpression;
use Magento\Framework\Search\Request\Query\Filter;
use Magento\Framework\Search\RequestInterface;
use Magento\Framework\Search\Request\QueryInterface as RequestQueryInterface;
use Magento\Framework\App\ResourceConnection;
use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Model\CategoryFactory;

class IndexBuilder
{
    /**
    * @var \Magento\Framework\App\Config\ScopeConfigInterface
    */
    protected $scopeConfig;

    /**
    * @var \Magento\Store\Model\StoreManagerInterface
    */
    protected $storeManager;
    protected $_stockFilter;
    private $layerResolver;
    protected $categoryRepository;
    protected $_categoryCollectionFactory;
    /**
     * @var Magento\Catalog\Model\CategoryFactory
     */
    protected $_categoryFactory;
    protected $registry;
    protected $_request;

    public function __construct(
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
        \Magento\Catalog\Model\Product\Visibility $productVisibility,
        \Magento\Catalog\Helper\Category $categoryHelper,
        \Magento\Framework\Registry $registry,
        \Magento\CatalogInventory\Helper\Stock $stockFilter,
        \Magento\Catalog\Model\Layer\Resolver $layerResolver,
        CategoryRepositoryInterface $categoryRepository,
        \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
        CategoryFactory $categoryFactory,
        \Magento\Framework\App\Request\Http $request
    ) {
        $this->storeManager = $storeManager;
        $this->_productCollectionFactory = $productCollectionFactory; 
        $this->_productVisibility = $productVisibility;
        $this->categoryHelper = $categoryHelper;
        $this->registry = $registry;
        $this->_stockFilter = $stockFilter;
        $this->layerResolver = $layerResolver;
        $this->categoryRepository = $categoryRepository;
        $this->_categoryCollectionFactory = $categoryCollectionFactory;
        $this->_categoryFactory = $categoryFactory;
        $this->_request = $request;
    }

    /**
    * Build index query
    *
    * @param $subject
    * @param callable $proceed
    * @param RequestInterface $request
    * @return Select
    * @SuppressWarnings(PHPMD.UnusedFormatParameter)
    */
    public function aroundBuild($subject, callable $proceed, RequestInterface $request) {
        $select = $proceed($request);
        $storeId = $this->storeManager->getStore()->getStoreId();
        $rootCatId = $this->storeManager->getStore($storeId)->getRootCategoryId();
        $productUniqueIds = $this->getCustomCollectionQuery();
        $select->where('search_index.entity_id IN (' . join(',', $productUniqueIds) . ')');

        return $select;
    }

    /**
    *
    * @return ProductIds[]
    */
    public function getCustomCollectionQuery() {
        $websiteId = $this->storeManager->getStore()->getWebsiteId();
        $collection = $this->_productCollectionFactory->create();
        $collection->addAttributeToSelect('*');
        $collection->addAttributeToSelect(array('entity_id','sku'));
        $collection->addWebsiteFilter($websiteId);
        $collection->setVisibility($this->_productVisibility->getVisibleInSiteIds());
        $collection->addAttributeToFilter('status',\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
       /*You can write your custom logic here...*/

        $getProductAllIds = $collection->getAllIds();
        $getProductUniqueIds = array_unique($getProductAllIds);
        return $getProductUniqueIds;
    }



}

This code will work in all scenario as like: category filters, layered navigations products count.Happy Coding :)

OTHER TIPS

You can create your own block that override

\Magento\Catalog\Block\Product\ListProduct

And inside of that include the collection for Out of Stock Products

 protected function _getProductCollection() { 
 ... some code here ...
 }

Create a template in frontend dir :

view/frontend/templates/module/mytemplate.phtml

Call your block there with the customizations you want to make .

After those are done , you can create a Cms Page called for ex: Out Of Stock and add this on the content :

{{block class="My\Module\Block\Product\ListProduct" template="My_Module::module/mytemplate.phtml"}}

Run magento commands for clearing contents and setup upgrade .

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top