-
-
Notifications
You must be signed in to change notification settings - Fork 730
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Track (negative) stock for on-demand products and overrides #12726
Conversation
During checkout, stock is adjusted when a shipment is finalised. The chain is: * Order state change to complete. * Trigger Order#finalize! which updates shipments. * Trigger Shipment#finalize! which adjusts stock on the variant. * A variant holds stock in stock items or in a variant override.
VariantOverrides are bolted onto variants to change their logic.
We weren't allowing negative stock to stop any bug from accidentally drawing too much stock. But now we want to implement a backordering logic that depends on negative stock levels to know how much is needed to replenish stock levels.
We weren't bothering with stock when items were on demand anyway. But we want to track stock now so that we can backorder more when local stock levels become negative.
We allowed this for producer stock and need to do the same for inventory stock. This will allow us to create backorders for missing, but promised stock.
Otherwise we would try to take stock from the producer stock level without respecting their on-demand settings. So from now on: If stock level or on_demand are set on the override then it's not using producer stock levels.
e864f60
to
2201d2e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work ! the commit history make it easy to follow.
override.reload | ||
} | ||
.to change { override.count_on_hand }.from(7).to(4) | ||
.and change { hub_variant.on_hand }.from(7).to(4) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The spec description implies that only the override
stock should be updated, is this meant to change as well ?
Took me a minute to understand, but if I am not mistaken because of OpenFoodNetwork::ScopeVariantToHub
the variant override is "linked" to the variant, so hub_variant.on_hand
actually returns the override.count_on_hand
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation seems very strange and error-prone to me.. I'm glad that we at least have a spec that demonstrates it now!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job, as Gaetan said it's very well structured and easy to follow.
Sorry if it's already covered, but what will happen in the case of existing on-demand products that don't need stock tracking? As this PR shows, there shouldn't be any change in behaviour, but I guess the underlying stock level in the DB will change.
- If
count_on_hand
was an integer, it will now get reduced. - If
count_on_hand
wasnil
, is it considered0
, and therefore reduced below zero?
Either way, if admins switch their products back off on-demand, they will then probably be confronted with a negative number. This may be confusing at first, but I don't think a problem.
override.reload | ||
} | ||
.to change { override.count_on_hand }.from(7).to(4) | ||
.and change { hub_variant.on_hand }.from(7).to(4) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation seems very strange and error-prone to me.. I'm glad that we at least have a spec that demonstrates it now!
Yes, that's right. And when you switch to stock tracking then you will see a negative number. That's the reason we didn't do it before. We avoided that negative number. But I don't think it's a big problem. |
It's funny I thought we already did that. Maybe we did at some point? I've searched around and found this: #4217 Anyway I agree it's not a problem 👍 |
That's an interesting issue you found, @RachL. I added checking shipments to the test list so that we don't introduce that issue again. |
Hey @mkllnk , Thank you for outlining the test scenarios. i) Test the checkout of stock controlled items and on-demand items.
ii) Also include inventory items with overridden stock or overridden on-demand.
iii) Test the order creation as admin of those items. Without variant overrides:
With variant overrides:
iv) Test with producer products and with inventory products (using variant overrides). v) When a stock controlled product goes out of stock during checkout, we still need to raise an error -> verified in i) and ii) vi) When an on-demand product goes out of stock, we should still be able to check out and it should not be marked as out of stock -> indeed, it was noticed that stock goes to negative values, which does not prevent orders from being placed, either in the shopfront or backoffice vii) After on-demand products have been ordered, the stock level may go negative. Ensure that order with products with negative stock can still be shipped. All order management actions should be as before. 🟢 All looks good. I have a question regarding the stock levels for on demand items, with variant overrides. Lets take the following steps:
So, each time, a variant is overridden with the Is this the expected behavior? |
Hi @mkllnk, |
Thank you, @drummer83, for reminding me. It slipped through my notifications. The remaining problematic behaviour is the reset of stock when you change a variant to Currently, we don't allow negative stock. During checkout, we check that there's enough stock and then complete the order. The order completion triggers stock to be adjusted. And if there was a race condition and someone else checked out at the same time then Rails would raise an error if the stock became negative. So validating stock to be positive is part of the checkout logic at the moment. We would need to add some additional checks if we allowed negative stock. And we would not be able to check out. For example:
So while preserving the stock level would be nice, I don't think that there's much benefit. If we find a use case for it, we can do it. But any change of the checkout logic is risky because it's complex old code. |
David just noted as well that on the new products screen, we don't see the stock level unless we switch on-demand off. And then we can't save it until we set it to 0 or a positive value anyway. So there is no automatic, surprising reset. The current logic should be good then. Long term, I would like to allow negative stock though and make the checkout logic more robust to handle that, not relying on validation errors to fail the checkout. |
ℹ️ Funded Feature. Please track ALL ASSOCIATED WORK under the associated tracking code #11678 DFC Orders
What? Why?
We want to place backorders on a wholesaler's platform when we run out of stock in our local OFN store. This complicates the stock logic though. To allow customers to order more than we have in stock, we set the products to on demand. And we change the logic to still count stock, allowing it to go negative, so that we know how much stock we need to order from the wholesaler.
This PR just prepares the change in OFN stock logic without adding the backordering logic. While it seems to be a fairly easy change, there's potential for subtle bugs around products going out of stock. We may have assumptions in our code that I'm not aware of.
What should we test?
Release notes
Changelog Category (reviewers may add a label for the release notes):
The title of the pull request will be included in the release notes.
Dependencies
Documentation updates