Intro
MSI stock works differently from the previous CatalogInventory stock.
To explain how to get the stock properly i first need to explain how MSI works.
However i will state this beforehand, it is impossible to get a different stock based on storeviews.
It is only possible to get it per website, as i will explain below:
In Magento 2.3 when using MSI you can have multiple "Stocks" which each have their own "Sources".
Stock explained
A "Stock" is pretty much your total inventory for one or more websites.
Each "Stock" can be assigned to multiple websites, however a website can only have a single "Stock" as this encompasses all of your stock for that website, regardless of the "Source".
Within a "Stock" you can have multiple "Sources".
Sources explained
A "Source" is pretty much a warehouse, with a location and it's own stock.
Each "Source" can be configured per product.
It is possible to leave sources empty, however it is not possible to change the stock on a storeview level, it is always global for the websites your source's stock is linked to.
Possible Solution
The comment of Prabhu M. was pretty close but did not explain why you should use this.
Magento\InventoryApi\Api\GetSourceItemsBySkuInterface
This code gets the "Source Items" for a product based on the SKU.
It does so for all sources, so if lets say you have 2 sources (warehouses) for a specific website, it will retrieve both of them.
It will also do the same for other websites.
Example:
Lets say you have 2 websites.
- website1.nl
- website2.com
For website 1 you have it linked to the "Stock": Stock NL
For "Stock NL" you have 3 sources linked to it:
- Warehouse Rotterdam (33 stock) [code: rotterdam]
- Warehouse Amsterdam (0 stock) [code: amsterdam]
- Warehouse Leiden (5 stock) [code: leiden]
For website 2 you have it linked to the "Stock": Stock EN
For "Stock EN" you have 1 sources linked to it:
- Warehouse New York (0 stock) [code: new_york]
To get the data above you can use the following code:
use Magento\Inventory\Model\SourceItem\Command\GetSourceItemsBySku;
...
public function __construct(
GetSourceItemsBySku $getSourceItemsBySku
) {
$this->getSourceItemsBySku = $getSourceItemsBySku;
}
...
function doSomething($product) {
$sourceItems = $this->getSourceItemsBySku->execute($product->getSku());
foreach ($sourceItems as $sourceItemId => $sourceItem) {
print $sourceItem->getSku() . ',';
print $sourceItem->getSourceCode() . ','; // The actual source code, e.g: warehouse_rotterdam
print $sourceItem->getStatus() . ','; // wether it is sellable
print $sourceItem->getQuantity() . '<br/>'; // the quantity for the current source
}
}
...
This will return the follow data:
testproduct, rotterdam, 1 (true), 33
testproduct, amsterdam, 0 (false), 0
testproduct, leiden, 1 (true), 5
testproduct, new_york, 1 (false), 0
In case of Stock NL your total quantity would be 38 and it would be sellable.
In case of Stock EN your total quantity would be 0 and it would not be sellable. (as it has no sources with stock)
Do note that this does not provide you with any indication of the website it is linked to.
If you know which sources you want to get it for you could use the following to get the stock:
use Magento\InventorySourceDeductionApi\Model\GetSourceItemBySourceCodeAndSku;
...
public function __construct(
GetSourceItemBySourceCodeAndSku $getSourceItemBySourceCodeAndSku
) {
$this->getSourceItemBySourceCodeAndSku = $getSourceItemBySourceCodeAndSku;
}
...
public function doSomething($product, $source) {
$sourceItem = $this->getSourceItemBySourceCodeAndSku->execute($sourceCode, $itemSku);
print $sourceItem->getSku() . ',';
print $sourceItem->getSourceCode() . ','; // The actual source code, e.g: warehouse_rotterdam
print $sourceItem->getStatus() . ','; // wether it is salable
print $sourceItem->getQuantity() . '<br/>'; // the quantity for the
}
...