you can set-up priorities of Sources in the scope of the given Stock on that Stock editing page in Admin panel or via Web API.
Here you can read more about that:
https://github.com/magento-engcom/msi/wiki/Create-Stock (Assigned Sources and Priorities - section).
After adding sources to the stock, arrange those sources from top-to-bottom in priority for fulfilling orders using Drag-n-Drop. The Source Selection Algorithm (SSA) provides an algorithm Priority using this order when determining shipment and inventory deductions.
The definition of salable quantity includes the quantity minQty.
Nowadays MSI is the approach. So no other methods, shortcuts, objectmanagers or M1 flashback code. It all has to be an MSI approach that will be compatible with future versions of M2.
So, let's get into it:
$websiteCode = $this->storeManager->getWebsite()->getCode();
$stock = $this->stockResolver->execute(SalesChannelInterface::TYPE_WEBSITE, $websiteCode);
$stockId = $stock->getStockId();
This gets your stock id for your website. It might always be the same but you have to look it up.
If on the frontend you want to show a different message for an item on backorder then you can do this:
$stockItem = $this->getStockItemConfiguration->execute($product->getSku(), $stockId);
$minQty = $stockItem->getMinQty();
$salableQty = $this->productSalableQty->execute($product->getSku(), $stockId);
To determine if the product is in stock and on sale:
$product->isSalable()
If you want to show what is low stock then you can get this from:
$lowStock = $this->scopeConfig->getValue(self::XML_PATH_STOCK_THRESHOLD_QTY, ScopeInterface::SCOPE_STORE);
Combining these values to show stock availability:
if (($salableQty + $minQty) > $lowStock) {
This shows what is readily available with no wait on backorders and no low stock.
If you want to know what is in stock including low stock, change the above to:
if (($salableQty + $minQty) > 0) {
To setup your class use the interfaces:
use Magento\InventoryConfigurationApi\Api\GetStockItemConfigurationInterface;
use Magento\InventorySalesApi\Api\GetProductSalableQtyInterface;
use Magento\InventorySalesApi\Api\StockResolverInterface;
use Magento\Store\Model\StoreManagerInterface;
Then, for your constructor:
const XML_PATH_STOCK_THRESHOLD_QTY = 'cataloginventory/options/stock_threshold_qty';
private $getStockItemConfiguration;
private $productSalableQty;
private $stockResolver;
private $storeManager;
public function __construct(
. . .
GetProductSalableQtyInterface $productSalableQty,
GetStockItemConfigurationInterface $getStockItemConfiguration,
StockResolverInterface $stockResolver,
StoreManagerInterface $storeManager,
. . .
) {
$this->getStockItemConfiguration = $getStockItemConfiguration;
$this->productSalableQty = $productSalableQty;
$this->stockResolver = $stockResolver;
$this->storeManager = $storeManager;
. . .
}
Best Answer
This is by design behavior as on the Category and Search Result pages Magento does not apply Inventory Reservations which are created when Order is placed. This is done to get the maximum performance on the category page. The product will disappear from the Category page as soon as you complete the order and create a shipment, that would lead to Source deduction and re-calculation of Stock Quantity