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
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:
Manage Stock = Yes:
It seems that the "magic" preventing the product to be added to cart reside in this class:
Magento\CatalogInventoryModel\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.
It seems that these two small changes would correct this bug!
Magento\CatalogInventoryModel\Quote\Item\QuantityValidator::validate()
Line 103 | - if (!$stockItem->getIsInStock() || $parentStockItem && !$parentStockItem->getIsInStock()) {
Line 103 | + if ((!$stockItem->getIsInStock() || $parentStockItem && !$parentStockItem->getIsInStock()) && !$stockItem->getBackorders()) {
Magento\CatalogInventoryModel\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.
@nikoelgatito Unfortunally, despite what is written in docs.magento, products with status āOut of stockā couldnāt be available for purchase. If you turned on āBackorderā function, it makes your product āIn stockā even with negative qty in stock, so it remains purchasable
Thank you @smoskaluk for your comments,
I do understand how it is currently unlogically working. I also do understand that basically the Stock Status
attribute was to control the availability of an item for which stocks are not managed. However when managing stocks this logic does not apply. An item for which a store accept backorders should always be recognized as not in stock as it is not, stocks might be on their way already or will be once an order has been placed (special order) but in any cases it should be recognized as out of stock. Most store managing stocks and backorders will want the threshold to switch Stock Status
to Out of Stock
for all products that has a qty below what they consider unavailable. Still they would like to be able to use the backorder function. The issue here is most merchant think that way because it is simply logically the way to do it but as Magento did it wrong unfortunately everyone had to adapt. What the doc says is the right way to do it and the very simple solution that is perfectly working for us is the fixed I shared above.
After all the Stock Status
attribute could almost be nonexistent and the isSalable()
function could simply rely on real stocks for every products that has its stocks managed. Some might say that the Stock Status
attribute acts more as a "Force Availability" attribute than anything but this does not add up to the current Magento logic. The backorders
attribute should be switched if one is willing to allow or disallow negative qty. In my point of view, Stock Status
is there more as informative to the visitor than anything, it is simply an indicator, whatever the current qty is, that the merchant decides from this point on this product should be indicated as out of stock. Still if backorders are enabled it should be saleable.
Say for example that a store has an unreliable inventory, an inventory that is updating every hour with lots of stock movements. They do accept backorders but the processing delay raise up to three days instead of 1 day for in stock products. Then to better be safe than sorry, they decide that the out of stock threshold is 5 qty. This way they ensure that a customer has much less chance to perceive unforeseen extra delays. Now what happens, the qty goes to 5 qty and the product is marked as out of stock, this makes sure that all visitors are aware that this is currently out of stock (backordered) and that an additional delay is to be expected. Unfortunately, this very popular situation does not work with the current Magento implemented logic, the product won't be saleable! The only way to make it saleable would be to put it In Stock, "lying" to ourselves and to the visitors showing it is in stock and "hopefully" we can add a notice in the cart.
Now of course added to the fix I proposed above, a great idea would be a way to "override" the Out of Stock status showing on the product page for Backordered if backorders are enabled for this product, this would be even more transparent to the customer. This is a part of what we do with a custom extension.
At this time, my understanding is that there probably was two different developers working on this aspect of the stock management for Magento and both did go with a different approach reaching in the middle.
This unfortunately does not work as there is a large difference between:
These surely should be related and are meant to influence each other but they should still be independant and a product should definitely still be saleable while showing out of stock or backorder on the frontend. A merchant should also be able to control from which qty level a product will be displayed as out of stock.
The solution # 2 below should allow for all case scenario.
The solution I initially proposed when creating this bug report is the simplest way requiring only a few edits for achieving what most users expect from a stock management logic. There is of course a much better approach to this that would require more code change but would also allow for better understanding, flexibility and much more satisfied merchants and customers.
The much better way to make it work keeping the actual Stock Status "almost" how it is (directly control the product saleability) would be in the case where ALL the following would apply:
1. The current Stock Status
attribute would be called "Availability" [Allow Sale/Disallow Sale] which would not relate to actual physical stocks BUT to the fact that we allow of disallow this product to be ordered. In this case it would be a "simple" way to keep a product enabled but still prevent sales.
2. The stock status displayed for a product would be controlled by an isInStock() that would rely both on availability and qty versus threshold. This would NOT affect the saleability of the product itself, only the stock status to be displayed on the frontend. The function logic would be the following:
true - `manage stock` is set to No.
true - `manage stock` is set to Yes or qty is above threshold
false - isAvailable() returns false
false - `manage stock` is set to Yes and qty is under threshold
3. In the case where isInStock() returns false but isAvalaible() returns true, isSalable() should verify if backorders are enabled and return the result. This also means that backorders logic should NOT solely be relying on qty < 0 to be taken into account.
This would mean that a product could appear out of stock if its qty is below the threshold even though availability is set to "available" and it would still be possible to order if backorders are enabled.
For those whose requirements include a way to disallow sales when a certain threshold has been reach (as with current wrong logic), my Solution # 2 still allows it:
Simply setting up an out of stock threshold as usual and making sure that backorders are disabled should be enough to ensure that both isInStock() and isSalable() return false therefore making the product both showing out of stock while preventing it sales once the threshold has been reached.
@nikoelgatito thank you for research. Would you like to submit pull request with your proposal?
Any update on this? Still an issue in 2.2.
@nikoelgatito, thank you for your report.
This seems to be correct Magento behavior. Please refer to the Community Forums or the Magento Stack Exchange site for advice or general discussion about this.
Otherwise you may submit Pull Request with the suggested changes.
Backorders are not working for me
Same here !
Set positive QTY(1) of product, staus should be enabled and stock should be in stock.
So for this product, ADD TO CART button will be appeared now. Place an order of this product by 1 QTY so the product will be out of stock. Now check the detail page and this time Add To Cart button will be there instead of Out Of Stock Button.
I don't why but this works for me. Try with yours
@nikoelgatito Did you implement your second solution?
We're dealing with the same issue at the moment, I can't believe magento sees this as intended behaviour and this is still an issue in 2.3
Would you be so kind to share your code with us? Or create a PR? :)
Big thanks for all the research you already did!
@magento-engcom-team I think this more an issue than an improvement. Many shop-owners will struggle with the same problem as they assume that backorders allow the sale of out-of-stock products with a negative qty.
Thx in advance!
We have the same issue, I can't believe Magento considers this as the normal behaviour... By allowing the backorders, of course, I would like to allow customers to purchase out of stock products, it's the definition of backorders...
Does anyone has found a solution ?
Thanks !
Magento 2.2.5 with the same problem. We are waiting years for this correction. The correct logic would be to be able to backorder product out of stock and with quantity below 1.
Still waiting...
i agree and have the same issue!
I agree with @samuelmafra as well. Our site is running 2.1.8 and we cannot get backorders to work either. Very annoying
@magento-engcom-team This is not an improvement. By what standards do you consider this an improvement? Hmm? Tell me? I would very much like to hear your opinion on this. I want facts from programming stand of point. This was already investigated in depth and model can be refactored in a custom module however i still cant understand where are you basing your statement that this is an improvement.
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.1.6
- Edit/Create a product,
- Set Manage Stock to "Yes",
- Set Qty to "0",
- 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\CatalogInventoryModel\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\CatalogInventoryModel\Quote\Item\QuantityValidator::validate()
Line 103 | - if (!$stockItem->getIsInStock() || $parentStockItem && !$parentStockItem->getIsInStock()) { Line 103 | + if ((!$stockItem->getIsInStock() || $parentStockItem && !$parentStockItem->getIsInStock()) && !$stockItem->getBackorders()) {
Magento\CatalogInventoryModel\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.
I could not find this line in that file,
Line 103 | - if (!$stockItem->getIsInStock() || $parentStockItem && !$parentStockItem->getIsInStock()) {
Backorders not working for me in magento2.3.2
Issue still occurs in M 2.3.2 Enterprise Edition.Is there any patch available to fix this issue.
Hi @engcom-Charlie. Thank you for working on this issue.
In order to make sure that issue has enough information and ready for development, please read and check the following instruction: :point_down:
Issue: Format is valid
will be added to the issue automatically. Please, edit issue description if needed, until label Issue: Format is valid
appears.[ ] 2. Verify that issue has a meaningful description and provides enough information to reproduce the issue. If the report is valid, add Issue: Clear Description
label to the issue by yourself.
[ ] 3. Add Component: XXXXX
label(s) to the ticket, indicating the components it may be related to.
[ ] 4. Verify that the issue is reproducible on 2.3-develop
branchDetails
- Add the comment @magento give me 2.3-develop instance
to deploy test instance on Magento infrastructure.
- If the issue is reproducible on 2.3-develop
branch, please, add the label Reproduced on 2.3.x
.
- If the issue is not reproducible, add your comment that issue is not reproducible and close the issue and _stop verification process here_!
[ ] 5. Add label Issue: Confirmed
once verification is complete.
[ ] 6. Make sure that automatic system confirms that report has been added to the backlog.
:white_check_mark: Confirmed by @engcom-Charlie
Thank you for verifying the issue. Based on the provided information internal tickets MC-21832
were created
Issue Available: @engcom-Charlie, _You will be automatically unassigned. Contributors/Maintainers can claim this issue to continue. To reclaim and continue work, reassign the ticket to yourself._
Backorders not in magento2.3.2 it does't show add to cart button it was working in magento 2.3.1
Hi @sdzhepa. Thank you for working on this issue.
Looks like this issue is already verified and confirmed. But if you want to validate it one more time, please, go though the following instruction:
Component: XXXXX
label(s) to the ticket, indicating the components it may be related to.[ ] 2. Verify that the issue is reproducible on 2.3-develop
branchDetails
- Add the comment @magento give me 2.3-develop instance
to deploy test instance on Magento infrastructure.
- If the issue is reproducible on 2.3-develop
branch, please, add the label Reproduced on 2.3.x
.
- If the issue is not reproducible, add your comment that issue is not reproducible and close the issue and _stop verification process here_!
[ ] 3. If the issue is not relevant or is not reproducible any more, feel free to close it.
Hello @nikoelgatito and all from this thread:
@torlokken @saumil171188 @sebfie @zuber11 @duckchip @magento2dev @samuelmafra @simonmaass @theschwag @goranhorvathr @veneu @soundararajanm1990 @sriharsha184 @shubhajay
Internal Magento team worked on this issue in the scope of MC-21832
.
The described flow in the Issue description was reconsidered again after reopen(issue was closed on Nov 1, 2017 here)
After multiple discussions and confirmation from the Product Owner of this functionality, the internal Jira ticket was closed as Not a Bug.
It is expected behavior for Magento 2 now.
POs resolution quote:
The Out of Stock status is a way for the merchant to take a product out of stock on the website without having to adjust the quantity. There may be several reasons they want to do this. By using the out of stock status, they can:
- Show the product on the storefront, which is not possible if they disable the product instead of using stock status
- Keep the existing quantity for the product unchanged, which may reflect the actual physical quantity in a warehouse
This is also shown in our documentation here: https://docs.magento.com/m2/ee/user_guide/catalog/inventory-backorders.html#stock-status
Stock Status
Products must be set to In Stock status when enabling backorders....
This issue should be closed as well
Hi, @sdzhepa, sorry if this is a silly question but I'm a bit confused. What do you mean by "Product Owner of this functionality?" What is that? The person who opened this ticket? An internal engineer? An EE customer?
Also can you clarify. Is the sole purpose of the Stock Status field to enable and disable the ability to purchase an item (while allowing it stay visible)?
Thanks!
Let me clarify some things :
This should really be 2 separate things. Backorders should allow the order of out of stock products. Another setting could be made to disable the add to cart like an 'Is Saleable' boolean field on product level.
We have enabled 'Allow Qty Below 0 and Notify Customer' and it is still automatically setting 'stock_status
' to 0 in cataloginventory_stock_status
. When i turn off 'Manage stock' it does not change it to 0. So something is definitely off here.
Please consider this and re open this issue.
Hi
Does anybody know where the stock count should be decreased? It's also not happening if I just overwrite the two methods as mentioned by @nikoelgatito :
Magento\CatalogInventory\Model\Quote\Item\QuantityValidator::validate()
Magento\CatalogInventory\Model\StockStateProvider::checkQuoteItemQty()
Been experiencing this same issue forever and now still not fixed in 2.3.4. You should be able to order Out of Stock products when you allow Backorders. It is very confusing to our customers when the product shows In Stock but yet it will be backordered.
Along with this is issue the product alert function does not work/show combined with allowing backorders and after using a workaround to get the alert link it seems the trigger of sending the email is also the is_in_stock setting (which needs to be true if u want to allow backorders) in stead of the real quantity causing sending email alerts while the quantity is still 0.
I'm facing same issue on Magento ver. 2.3.0, screen shot is settings of a simple product of configurable product which gives these two error messages when try to add to cart, any idea how to fix this
"The requested quantity is not available
This product is out of stock."
After multiple discussions and confirmation from the Product Owner of this functionality, the internal Jira ticket was closed as Not a Bug.
It is expected behavior for Magento 2 now.
@sdzhepa - the PO/Magento has misunderstood what BackOrder means then. Back Orders allow customers to order a product even if it is out of stock. Falsely marking a product as In Stock when it has zero or negative quantity is nonsensical, and doing so breaks other functionality/logic (Eg. In Stock filters).
The whole point of Back Order is to allow products to be marked Out of Stock. In researching this problem I've come across countless others confused by the same thing, this behaviour is obviously not what admins/users/customers expect.
We have the same complaint. This is so annoying. We should be able to set out of stock AND still allow backorders because right now, if we enable backorders, our products must be shown in stock and then also syndicated to Google and other places as in stock when they're not.
Please allow ordering out of stock products but show Out of stock and notify the customer that the product is out of stock but that they can still order it, an attribute to set the estimated restock date should be possible as well.
This seems like a bug to store owners.
Expect that an Out of Stock product (qty 0) can still be ordered, that it says Out of Stock.
It should also be able to show the product is expected to be in stock again, (from a product attribute)
Note: Customer is not notified.
Most helpful comment
@nikoelgatito Did you implement your second solution?
We're dealing with the same issue at the moment, I can't believe magento sees this as intended behaviour and this is still an issue in 2.3
Would you be so kind to share your code with us? Or create a PR? :)
Big thanks for all the research you already did!
@magento-engcom-team I think this more an issue than an improvement. Many shop-owners will struggle with the same problem as they assume that backorders allow the sale of out-of-stock products with a negative qty.
Thx in advance!