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
Add filter hook to allow currently hardcoded 10 minute checkout draft stock reservation to be filtered #45246
Conversation
Hi , Apart from reviewing the code changes, please make sure to review the testing instructions as well. You can follow this guide to find out what good testing instructions should look like: |
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.
Hi @ninetyninew thanks for contributing to WooCommerce. I have some quick feedback on this.
We should ensure the new filter is documented (similar to how it is done here) and maybe a better name would be woocommerce_draft_order_hold_stock_minutes
.
You could also move it to a separate variable to make it clearer what the documentation refers to.
Finally, the changelog entry on the PR body is incorrectly formatted, but I'll update it for you so it auto-generates one. I'd also change it to an Add
rather than a tweak since we're adding new functionality here.
I'd like to hear @mikejolley's input on why 10 minutes was chosen, and why it's not editable. It was added in this PR: woocommerce/woocommerce-blocks#5546
@ninetyninew could you also share your use-case on this PR as to why you want to filter this?
@opr I've hopefully made those changes and committed them as required. My use case for this is for when you have a layer of custom stock management on top of WooCommerce's standard stock functionality, it is useful to be able to stop the reservation by suppling zero minutes, previously you could turn off the stock reservation with woocommerce_hold_stock_minutes, but now with Cart/Checkout blocks this isn't possible due to the forced 10 minutes, I have read @mikejolley's ticket on why it is 10 minutes, but I think you should be allowed to supply your own value for this (including 0): "we put a hold on stock for all items in the cart to prevent things going out of stock while the customer enters their details" If you've set the proposed new filter to 0 and it does go out of stock in that scenario, what would happen? |
…+ filter comment amend (#45245)
@opr just seemed like a sensible number to allow customer to idle on checkout before invalidating everything. The time gets updated whenever there is an API push during field entry. If this was somehow set too low, the checkout would error when placing an order if something went out of stock. There would be race conditions. |
Thanks for the info Mike, makes sense.
If we communicate this in the hook docks I think it's OK then. |
@opr Let me know if anything further needs amending here, I saw yesterday the workflows flagged a lint error which I believe I have rectified in the latest commit. |
* | ||
* @param integer $minutes Minutes to hold stock for draft orders on checkout entry. | ||
*/ | ||
$draft_order_hold_stock_minutes = (int) apply_filters( 'woocommerce_draft_order_hold_stock_minutes', 10 ); |
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.
Maybe we should check that the result is: not empty, is an integer (or can be cast to one) and is not negative, if any of these are true it should default back to 10. Do you agree?
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.
@opr I think casting to a integer and a check for negative is fine, however the !empty would stop being able to filter to 0, which for our particular scenario (to stop stock reservation) is why we need this filter.
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.
Yep, you're right 👍🏼
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.
@opr The int casting is already there, i've just amended to include the negative check in the latest commit if you'd like to check over it.
@ninetyninew thanks for your patience so far, after more testing I have found that if the filter returns 0, then the value is defaulted to 60 in therefore, to disable stock reservation on draft orders, you need to use two filters: Looping in @woocommerce/proton to get your thoughts on this. I personally don't think this is the greatest DX, especially if you only want to set draft order stock reservation time to 0 leaving regular order's reservation time alone. Instead of this, do you think a better approach would be adding a filter to |
@opr Makes sense, and less complicated. Happy to do that, would I do that here or does it require creation of a new PR? Also what would the suggested filter name be? Maybe |
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.
Thanks for working on this @ninetyninew - it's working fine for me now and the stock is not reserved. Please can you close and reopen the PR to get CI running?
I have a suggestion for an improvement that would make the filter more flexible: what if instead of accepting an returning a boolean, it accepts the value of Thus the begninning of the function body, not including the filter docblock, would look like this (I haven't tested it): $minutes = $minutes ? $minutes : (int) get_option( 'woocommerce_hold_stock_minutes', 60 );
$minutes = apply_filters( 'woocommerce_order_hold_stock_minutes', $minutes, $order );
if ( ! $minutes || ! $this->is_enabled() ) {
return;
} |
@Konamiman @opr I find this a little harder to understand than our proposed filter, due to the already existing woocommerce_hold_stock_minutes setting, could that new filter lead to confusion with what woocommerce_hold_stock_minutes is doing maybe? Whereas the woocommerce_reserve_stock_for_order seems quite self explanatory: there is a hold stock minutes setting, but you can exclude an order from it. Not quite sure on this, but I think that it may also cause a potential issue, as the checkout draft |
@ninetyninew thanks for sharing your thoughts! I think @Konamiman's suggestion is great and makes a lot of sense, but I also agree that naming is tricky. I think we should go with the new suggestion but with a clearer/easier name.
If the stock-hold is set to 0, it's effectively the same as returning |
Thanks for the feedback, I have now made the changes as recommended, committed them and updated the testing instructions. Can you please re-review @opr @Konamiman Note: As a $minutes based hook, I can't think of better name than this, when writing the previous reply I was mistakenly forgetting hat woocommerce_hold_stock_minutes isn't a filter in itself and is a setting, so with this new proposed filter being the only filter hook related to what it's doing (and woocommerce_hold_stock_minutes being a setting), I think the name works. |
@ninetyninew It looks good now, thanks. Just one additional small nitpick: it would be good to explicitly state in the docblock of the filter that a value of zero minutes will disable the stock reservation for the order entirely (that was the original goal of the change after all). |
@Konamiman No problem, I have now made and committed the doc block change. |
@Konamiman Thanks! I noticed 1 thing failed here, do I need to do anything? I haven't raised a PR for a long time so unfamiliar with the latest processes. |
@ninetyninew Don't worry, it's Github trying to create a build from the PR branch but that sometimes fails and it's not related to the code changes introduced. |
Submission Review Guidelines:
Changes proposed in this Pull Request:
Closes #45245
Note: We originally committed a filter hook for the hardcoded 10 minute reserve stock on block checkout entry, however due to reviews since then we have opted for a filter in
Automattic\WooCommerce\Checkout\Helpers
in theReserveStock::reserve_stock_for_order()
.The proposed newer filter was then reviewed and recommended we amend to a minutes based filter, and hence this is now a
woocommerce_order_hold_stock_minutes
filter hook.Testing instructions below updated.
Snippet for testing:
Test based on WooCommerce hold stock minutes setting:
Test based on block checkout entry hold stock minutes (this uses a hardcoded 10 minutes not the hold stock setting):
Changelog entry
Significance
Type
Message
Add
woocommerce_order_hold_stock_minutes
filter hook to allow the number of minutes stock in an order should be reserved for to be filtered.Comment