• Set product as non-backorderable
• Set inventory to 0
• Add product to cart on frontend
You should not be allowed to add a 0 stock non-backorderable product to your cart
You are allowed to add the non-backorderable part to your cart. Trying to check out generates an error message for the user and redirects them back to the cart - which is confusing to some of our customers.
Create a JS file that disables the "Add to Cart" button and adds explanation text above/below the button when a variant is selected that is out of stock and non-backorderable.
Expanding that a bit further, you could also run into situations where you only have 2 of a product left and a customer tries to order 3. To prevent the customer from ordering more than what is on hand for non-backorderable products, you could track the current stock of the selected variant in the JS file, and when the "quantity" field > current stock, disable the button and add explanation text.
Thanks for reporting.
I can confirm this issue, even if I'm still not sure this is not the expected behavior.
Your JS proposal would not work if another user completes a purchase of the same product just before another user adds the product to the cart, right? I think that if we need to stop allowing users to add products with insufficient stocks to cart we need to implement some backend validation logic first. Also, IMO critical frontend functionalities should work without JS active on the page.
Something like this on Spree::LineItem should work:
validate :check_insufficient_stocks
def check_insufficient_stocks
unless Stock::Quantifier.new(variant).can_supply? quantity
errors.add(:quantity, "is not available")
end
end
but at the moment I'm not sure about drawbacks this can have on the rest of the code.
Let's wait for someone else feedback on if it is a bug or not.
Based on prior experience with other ecommerce platforms, I would expect the site to prevent me from adding an unbuyable product to my cart when I click the "add to cart" button. The proposed validation looks like the optimal solution to me, since it stays in the existing error flow and also works without JS (e.g. on API calls).
That validation has been removed from the line item and moved towards the before_complete callback in the order state machine for performance reason. If you want to re-add it, simply add the line
validates_with Spree::Stock::AvailabilityValidator, if: { !order.completed? }
to your Spree::LineItemDecorator.
However: I don't think this is an ideal solution as the record is not actually properly invalid. The thing might come back in stock before the order is completed. It's rather something that should be implemented in your custom frontend as a before_action, with a better error message than ActiveRecord::RecordInvalid.
Is this still an active bug? Seems like a major issue if you can sell something that is out of stock..
The system is allowing to add the item to the cart, not selling it. There's a validation before the order completion that prevents finalizing the order unless all items are in stock (or backorderable).
There are a couple of solutions above that you can easily implement in your own store. Anyway, I agree we should start thinking to provide an OOTB solution here, probably by just adding the check in the order populate action. What do you think @solidusio/core-team ?
Most helpful comment
The system is allowing to add the item to the cart, not selling it. There's a validation before the order completion that prevents finalizing the order unless all items are in stock (or backorderable).
There are a couple of solutions above that you can easily implement in your own store. Anyway, I agree we should start thinking to provide an OOTB solution here, probably by just adding the check in the order populate action. What do you think @solidusio/core-team ?