Update stock in Magento 2.4, 2.3 multi source inventory
Magento 2.3 introduced a new feature: Multi-Source Inventory (MSI) that was designed to handle multiple inventory sources. This broke many inventory synchronisations with various ERP systems.
MSI can not be turned off and it introduced some more complexity for how Magento 2.3 is handling stock. When an order is placed, it’s adding a record to the inventory_reservation
table. This reserves an item from the existing stock without changing the quantity on the stock item. Many traditional ERP systems designed to update the inventory quantity without doing anything with the reservation. So if for example, there were 2 items in the stock of a product, and an order was placed for one, the stock item was still 2, with 1 reserved in the inventory_reservation
table. It’s now only possible to purchase one item.
What happened when this order went through the ERP system that was capable of updating the Magento stock is, it decreased the stock item’s quantity to 1, so with reservation still in place, the product is now marked as out of stock in Magento, despite there’s still one in stock.
Invoicing and shipping the order removes the reservation, but it’s also decreasing the stock, so our example product remains out of stock. It’s therefore very important for any stock synchronisation to make sure the reserved stock is also updated or considered when changing any stock item’s quantity. There’s also a new way to update stock in Magento 2, with the old classes being deprecated.
In order to use the new API to update stock, add this to the constructor:
public function __construct(
\Magento\InventoryApi\Api\SourceItemsSaveInterface $sourceItemsSaveInterface,
\Magento\InventoryApi\Api\Data\SourceItemInterfaceFactory $sourceItemFactory,
) {
$this->sourceItemsSaveInterface = $sourceItemsSaveInterface;
$this->sourceItemFactory = $sourceItemFactory;
}
Updating the quantity looks like this:
$sourceItem = $this->sourceItemFactory->create();
$sourceItem->setSourceCode('default');
$sourceItem->setSku($sku);
$sourceItem->setQuantity($qty);
$sourceItem->setStatus(1);
$this->sourceItemsSaveInterface->execute([$sourceItem]);
Where I used the “default” inventory source, which is added to Magento by the install script and it’s there unless it was removed from the admin. $sku
is the product SKU and $qty
stands for quantity.
SourceItemsSaveInterface
accepts an array of items and it’s quite fast to save multiple stock items at once, compared to saving them one by one in a loop.
Why does Magento need MSI? Because Adobe acquired Magento in late 2018. Their idea is to transform Magento into an enterprise eCommerce solution. Without MSI, Magento lacked the feature of handling inventory for larger enterprises so they were forced to use an ERP software that was capable of handling this. Stores with only a single inventory can still use the system, but the byproduct of inventory reservation needs a little more attention from developers.
Comments