PayPal checkout fails if twice the required stock is not available #10511
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
When checking out using PayPal payment method in checkout, you will be thrown back to the "Review" screen with "We can't place the order" message if one or more items in the cart are ordering half of the available stock. For example, "RED BOOT" is in the cart with quantity 1, and there is only 2 left in stock.
#10512 is a continuation of this as there is another section of code that triggers same error with slightly different conditions - when ordering the last item in stock. #10511 and #10512 together have resolved and stabilised all of our PayPal transactions to date.
Fixed Issues (if relevant)
Part of #9116
Possibly #10142
Manual testing scenarios
Expected
Actual
Rationale
The quote object is saved via repository TWICE during PayPal checkout.
Saving a quote via repository triggers CartItemPersister of all items.
In the first save, the product options of the items are not present since no changes were made to the items. Thus the CartItemOptionsProcessor returns just the quantity and no buyRequestData. (This could be an issue itself but it seems to work OK.) During this first save the CartItemPersister at the end, however, then adds the product options to the item. As with any quote save, the stock is also validated.
Then, during the second save via repository, because product options now exist, updateItems is called for every configurable product in the cart.
Because the buyRequestData passed to updateItem does not contain the ID of the item like it would if it was triggered from a cart edit, it results in the reset quantity flag being ignored, thus, the quantity of the item within the cart is increased to 2 and a stock check for 2 is performed.
PayPal checkout has a quote save early on and then it has one in Quote->submit AFTER order placement. So at this point, the RED stock is now 1, but then a stock check is performed for 2 items, and throws an exception post order placement, causing the redirect to the review screen with error message. In fact, this then triggers a return to stock of the items in the quote for some reason, resulting in 3 RED items now in stock...
Contribution checklist
[x] Pull request has a meaningful description of its purpose
[x] All commits are accompanied by meaningful commit messages
[ ] All new or changed code is covered with unit/integration tests (if applicable)
[ ] All automated tests passed successfully (all builds on Travis CI are green)