Magento – Search criteria builder does not filter an “out_of_stock” products

collection;magento2.3magento2.3.0search-criteria

I am using Magento 2.3,
Am filtering the product collection using the search criteria builder with a custom attribute as the filter.

$filter1 = $this->_filterBuilder->setField('custom_item_number')
                ->setValue($itemNumber)
                ->setConditionType('eq')
                ->create();
            $this->_searchCriteriaBuilder->addFilters([$filter1]);
            $searchCriteria = $this->_searchCriteriaBuilder->create();
            $productCollection = $this->_productRepository->getList($searchCriteria)->getItems();

This does not filter the product if it is in out of stock status. If I make the product stock status as "in_stock", it works. Why? And How can I filter the product collection?

Thanks in advance.

Best Answer

It's because stock status was added when product collection is loading. You can see how it works as the following

  1. \Magento\Catalog\Model\ProductRepository::getList()
...
$collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');

        $this->collectionProcessor->process($searchCriteria, $collection);

        $collection->load();// The stock fillter will be added after this

        $collection->addCategoryIds();
...
  1. \Magento\CatalogInventory\Model\AddStockStatusToCollection::beforeLoad()
public function beforeLoad(Collection $productCollection, $printQuery = false, $logQuery = false)
    {
        $this->stockHelper->addIsInStockFilterToCollection($productCollection);
        return [$printQuery, $logQuery];
    }
  1. \Magento\CatalogInventory\Helper\Stock::addIsInStockFilterToCollection()
public function addIsInStockFilterToCollection($collection)
    {
        $stockFlag = 'has_stock_status_filter';
        if (!$collection->hasFlag($stockFlag)) {
            $isShowOutOfStock = $this->scopeConfig->getValue(
                \Magento\CatalogInventory\Model\Configuration::XML_PATH_SHOW_OUT_OF_STOCK,
                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
            );
            $resource = $this->getStockStatusResource();
            $resource->addStockDataToCollection(
                $collection,
                !$isShowOutOfStock
            );
            $collection->setFlag($stockFlag, true);
        }
    }

As you can see here, Magento has a configuration that allows showing products are out of stock: enter image description here

If you change Display Out of Stock Products to Yes as my screenshot, you will have all products that include products are out of stock

Related Topic