-
Notifications
You must be signed in to change notification settings - Fork 9.4k
Description
From the official Magento documentation both for the first edition and Magento 2 we can read the following very logical definition for Out of Stock products:
Out of Stock: Unless Backorders are activated, prevents the product from being available for purchase and removes the listing from the catalog.
Source: http://docs.magento.com/m2/ce/user_guide/catalog/settings-advanced-advanced-inventory.html
Preconditions
- Magento 2.3.x
- Edit/Create a product,
- Set Manage Stock to "Yes",
- Set Qty to "0",
- Enable Backorders
- Set Stock Status to "Out of Stock".
Steps to reproduce
- Visit the product page,
- Add the product to cart.
Expected result
- The Add to Cart button shows and we can add the product to the shopping cart.
Actual result
- The Add to Cart button does not show,
- Even after forcing the isSalable() method to return true, then refreshing the page and clicking on the Add to Cart button that is now showing, the product is not added to cart and the red "This product is out of stock." notification message is showing.
Remarks regarding the Add to Cart button not showing:
It seems that the isSalable() method depends more on the In Stock status than the real item quantity. This function should rely on real quantity for every product that has the Manage Stock option enabled. Solely relying on the Stock Status for product with real quantity is not reliable.
The logic should be as follow:
Manage Stock = No:
- isSalable() should return true/false based on Stock Status.
Manage Stock = Yes:
- Backorders are not allowed: isSalable() should return true/false based on stock qty and threshold.
- Backorders are allowed: isSalable() should always return true.
Remarks regarding the product not adding to cart:
It seems that the "magic" preventing the product to be added to cart reside in this class:
Magento\CatalogInventory\Model\Quote\Item\QuantityValidator::validate()
As we can see on line 103, the verification here again solely rely on Stock Status and not on the actual quantity even though Manage Stock is enabled:
103 | if (!$stockItem->getIsInStock() || $parentStockItem && !$parentStockItem->getIsInStock()) {
...
}
This is unfortunate as we though backorders were well implemented in Magento and we are currently on a project for which we will have to modify the default (wrong) Magento behavior by the meantime this bug gets officially resolved and released.
[UPDATE]
Possible Solution:
It seems that these two small changes would correct this bug!
Magento\CatalogInventory\Model\Quote\Item\QuantityValidator::validate()
Line 103 | - if (!$stockItem->getIsInStock() || $parentStockItem && !$parentStockItem->getIsInStock()) {
Line 103 | + if ((!$stockItem->getIsInStock() || $parentStockItem && !$parentStockItem->getIsInStock()) && !$stockItem->getBackorders()) {
Magento\CatalogInventory\Model\StockStateProvider::checkQuoteItemQty()
Line 155 | - if (!$stockItem->getIsInStock()) {
Line 155 | + if (!$stockItem->getIsInStock() && !$stockItem->getBackorders()) {
These are making sure that the product Stock Status being out of stock has no impact if backorders are enabled. The process will then continue its nomal verification flow and the backorder notices will still be shown where applicable. It has been tested and completely working.