After doing R&D found a solution to get all the out of stock products
<?php
namespace [VENDOR_NAME]\[MODULE_NAME]\Block;
use Magento\Catalog\Model\Product\Attribute\Source\Status;
use Magento\Catalog\Model\Product\Visibility;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
class OoSProducts extends Template
{
/**
* @var CollectionFactory
*/
protected $_productCollection;
/**
* @var Visibility
*/
protected $_productVisibility;
/**
* @var Status
*/
protected $_productStatus;
/**
* OoSProducts constructor.
* @param Context $context
* @param CollectionFactory $productCollection
* @param Visibility $productVisibility
* @param Status $productStatus
*/
public function __construct(
Context $context,
CollectionFactory $productCollection,
Visibility $productVisibility,
Status $productStatus
) {
parent::__construct($context);
$this->_productCollection = $productCollection;
$this->_productVisibility = $productVisibility;
$this->_productStatus = $productStatus;
}
/**
* Out of Stock Product Collection
* @return $this|\Magento\Catalog\Model\ResourceModel\Product\Collection
*/
public function getOutofstockProductCollection()
{
$collection = $this->_productCollection->create();
$collection->setFlag('has_stock_status_filter', true);
$collection = $collection->addAttributeToSelect(array('name', 'sku', 'product_url'))
->addAttributeToSort('name', 'ASC')
->joinField('qty',
'cataloginventory_stock_item',
'qty',
'product_id=entity_id',
'{{table}}.stock_id=1',
'left'
)
->joinTable('cataloginventory_stock_item', 'product_id=entity_id', array('stock_status' => 'is_in_stock'))
->addAttributeToSelect('stock_status')
->addFieldToFilter('stock_status', ['eq' => 0])
->addAttributeToFilter('status', ['in' => $this->_productStatus->getVisibleStatusIds()])
->setVisibility($this->_productVisibility->getVisibleInSiteIds());
return $collection;
}
}
pt 1. To exclude product visibility Not Visible Individually
, use this method.
$this->_productVisibility->getVisibleInSiteIds() returns the
self::VISIBILITY_IN_SEARCH
self::VISIBILITY_IN_CATALOG
self::VISIBILITY_BOTH
pt 2. Get all enabled product, Use below method
$this->_productStatus->getVisibleStatusIds() returns
self::STATUS_ENABLED
pt 3. $collection->setFlag('has_stock_status_filter', true);
It is important to set the has_stock_status_filter flag to true to get proper results for Out of stock products.
Note: [VENDOR_NAME]\[MODULE_NAME] should be replaced by your project directory names i.e vendor name and its module name.