4

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.

1
  • Can anyone help?
    – Octopus
    Commented Feb 11, 2019 at 4:47

2 Answers 2

3

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

2
  • Thanks much for your reply. My question is "I am filtering a product using search criteria builder. And I know that the product is in the database but in out_of_stock status. will that searchcriteriabuilder bring my product or it will result in empty collection?"
    – Octopus
    Commented Feb 12, 2019 at 9:43
  • these are all marked deprecated by the MSI in 2.3.3 but I am just not finding the "new" way (InventoryCatalog and not CatalogInventory) to do it.
    – iphigenie
    Commented Feb 11, 2020 at 17:11
0

From your question, my understanding is that, you need to filter the searchCriteria using the AND condition with custom_item_number = $itemNumber AND quantity_and_stock_status=1. Here quantity_and_stock_status stands for the stock status. It's value is 1 for in stock products and 0 for out of stock. You can make theAND query by using the class FilterGroupBuilder So inject the class and make the FilterGroupBuilder object in your constructor.

\Magento\Framework\Api\Search\FilterGroupBuilder $filterGroupBuilder 
$this->_filterGroupBuilder = $filterGroupBuilder;

Then modify your code as follows.

$filter1 = $this->_filterBuilder
->setField('custom_item_number')
->setValue($itemNumber)
->setConditionType('eq')
->create();

$filterGroup1 = $this->_filterGroupBuilder->setFilters([$filter1])->create();

$filter2 = $this->_filterBuilder
    ->setField('quantity_and_stock_status')
    ->setValue(1)  
    ->setConditionType('eq')
    ->create();

$filterGroup2 = $this->_filterGroupBuilder->setFilters([$filter2])->create();

$searchCriteria = $this->_searchCriteriaBuilder->create();
$searchCriteria->setFilterGroups([$filterGroup1, $filterGroup2]);
$productCollection = $this->_productRepository->getList($searchCriteria)->getItems();

Now clear your cache and let me know your result.

2
  • Thanks for your reply. My question is "I am filtering a product using search criteria builder. And I know that the product is in the database but in out_of_stock status. will that searchcriteriabuilder bring my product or it will result empty array?"
    – Octopus
    Commented Feb 12, 2019 at 9:42
  • As per the above filtering condition, it will only output the products which are in stock and with the custom_item_number equal to the provided value.
    – MGento
    Commented Feb 12, 2019 at 10:25

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.