[4.x]: Out of stock product in cart causes problems, unable to update cart after this
What happened?
Description
When having a product in your cart that went out of stock, while you had it in your cart, it causes problems. When you try to add another product to your cart, it always returns the "“{description}” is currently out of stock." and not adding the product o your cart.
Same goes for editing other line items in your cart, let's say you want to change the qty or delete another product, it is not possible because of this one product that is out of stock.
Steps to reproduce
- Add multiple products to your active cart.
- reduce the stock of 1 product to 0 through the control panel.
- Try adding another product to your cart through a product detail page for example
Expected behavior
- The product still gets added to you cart.
Actual behavior
You get an error that it is not possible to update your cart because that product is currently out of stock, but this is far from user friendly.
Craft CMS version
4.13.9
Craft Commerce version
4.7.2
PHP version
8.1
Operating system and version
Mac OS
Database type and version
Mysql 8
Image driver and version
No response
Installed plugins and versions
@jornwildenbeest can you confirm this is also an issue on Craft Commerce 4.8?
The item that became out of stock should be removed from the cart and a notice placed on the order that it was removed due to being out of stock.
If 4.8 doesn't fix it could you email your database backup, composer.json, composer.lock to [email protected] and reference this issue to us in support so we have context.
Let us know the order number the issue is occurring on and we will try to reproduce.
Thanks.
@jornwildenbeest I was able to reproduce now!
I have a potential fix here: https://github.com/craftcms/commerce/pull/3878
But will need to do some more testing as it is a change in the way we recalculate the cart.
I will update you here once we finalize on a solution.
We have merged that PR to fix this, to be included in the next release.
To get the fix early, change your craftcms/commerce requirement in composer.json to:
"require": {
"craftcms/commerce": "4.x-dev as 4.8.0.1",
"...": "..."
}
Then run composer update, and then let us know how you go.
We will update this ticket once the release is out.
Hi
This fix has been released in Commerce 4.8.1 which is out now.
Thanks!
The fix has also been included in Commerce 5.3.2 which has been released.
Thanks!
We have had to revert this fix in 5.3.2.1 and 4.8.1.1 due to it causing other issues.
We will look into it more.
Hi @lukeholder @nfourtythree @jornwildenbeest any new information on this? This could have quite an impact for us as stock is regularly changing. We are currently seeing the following issues (Craft 4.16.11, Commerce 4.9.1):
- Unable to add other items to a cart if an existing lineitem has subsequently become out of stock
- Unable to clear out of stock line items + any related notices when calling update-cart with just the
clearNotices=1(this previously worked nicely)
I'm assuming its related to how / when / where cart recalculation is happening, but I can't see any obvious changes in the docs or changelog.
@samhibberd I don't think so. We run a shop where products get out of stock frequently, so we run a custom console command, every ... hours or every day, not sure, but we run it quite often to prevent this.
The console command we use:
public function actionRemoveOutOfStockProductsFromCart(): void
{
$ids = Variant::find()->hasStock(false)->select('id')->collect()->pluck('id')->toArray();
$orderIds = LineItem::find()
->where('purchasableId IN (' . implode(',', $ids) . ')')
->select('orderId')
->distinct()
->collect()
->pluck('orderId')
->toArray();
$carts = Order::find()->isCompleted(false)->id($orderIds)->withLineItems()->all();
foreach ($carts as $cart) {
$lineItems = $cart->getLineItems();
foreach ($lineItems as $lineItem) {
$purchasableId = $lineItem->purchasableId;
if (in_array($purchasableId, $ids)) {
$cart->removeLineItem($lineItem);
}
}
if(!Craft::$app->getElements()->saveElement($cart, false)){
Craft::warning('Could not save cart with out of stock product, cart id: ' . $cart->id, __METHOD__);
}
}
$this->success("Removed out of stock products from carts");
}
But I agree, I think this is a serious bug that can happen quite easily. Maybe it helps!
Hey @jornwildenbeest thanks for this, interesting. Similar for us, although we present a notice to customers when they access a cart with unavailable items (using the notice logic) with the option to manually clear / remove them. This is pretty typical and we like it as the customer is kept in the loop.
This bug means the cart is in essence broken/ unusable, until it's manually cleared (which this bug also prevents) or a command like yours is run.
This feels like quite an significant issue.
We really need to know if this is a bug, what steps will be taken/ will it be fixed. And if not an update to docs on how we should be handling this scenario.
It's been months since the initial fix was reverted and this bug was reopened @lukeholder @nfourtythree @brandonkelly
We can't be the only ones impacted?! Unless we are missing something really obvious?!
@samhibberd Thanks for the ping. We are looking into this issue today as a team and will get back to you. Thanks.
Hi @lukeholder thanks very much. We are running on 4.x, but I have just checked over the Spoke & Chain Demo (running 5.x) to see how the demo handles this scenario, and can confirm that there something up on 5.x too, the Spoke & Chain Demo, just reports an "Unable to update cart" flash anywhere you try to interact (save in the background) the cart, and the basket just shows the out of stock item.
I'm wary to start implementing any custom code / work arounds until Craft has taken a call on what's going to be actioned moving forward, so even just an update on the plan as soon as you have one would be very much appreciated!!
Hi @samhibberd & @jornwildenbeest
We have just pushed a fix to the 4.x branch that we believe solves the issue you are seeing. It would be great if you could test this out with your projects.
To get this fix, change your craftcms/commerce requirement in your project's composer.json to:
"require": {
"craftcms/commerce": "4.x-dev as 4.9.2",
"...": "..."
}
Then run composer update.
Please let us know how you get on, we can then look to get the fix released ASAP as well including it in a 5.x version.
Thanks!
Thanks @nfourtythree am testing now and will come back to you as soon as I can.
@nfourtythree gets a 👍 from us, we have tested the various scenarios that this would impact and it looks good. Thanks.
Hi All
Thank you for all of the info and feedback on this issue.
The fix we produced has now been released in Commerce versions 4.9.3 and 5.4.6.
Thanks!