Hello folks,
I think I found a major bug in the handling of Virtual Products in Prestashop 1.7.
First off some background:
A while ago, I asked for help with an issue I have about the total being incorrectly calculated when using discount vouchers:
https://www.prestashop.com/forums/topic/866094-total-doesnt-consider-voucher/
As you can see, no one bothered to give me an answer as of now. Because this issue keep costing me money I kept investigating. I set up a test server using the latest Prestashop build 1.7.4.2 and installed my theme to it, but other than that didn't bother to add any modules or even products. I found that with the default products the discount voucher was displayed correctly:
https://i.imgur.com/xHBmxKR.jpg
After a lot of testing I found the culprit! When I changed the product type to "Virtual Product" the discount voucher stopped being calculated correctly:
https://i.imgur.com/n7wdC7d.jpg
https://i.imgur.com/HuRWDFw.jpg
I considered that this might be an issue related to my custom theme, but even using "Classic" that comes with 1.7.4.2 the problem still remained.
I really hope you could look into this matter and fix it for the next update and it would be great if someone could provide me some clues how I can remedy the problem in the meantime. As I mentioned, I am actually missing out on sales right now, because people can't use their discount codes.
Cheers
Hi @GMVitus,
I manage to reproduce the issue with the last version 1.7.4.2.
Discount is not applied when the product type is a virtual product.
We will see how to fix it.
In the version 1.7.3.4 => OK.
Best regards, Khouloud
Thank you for taking on the task. Maybe it helps you to know that previous version of 1.7 didn't have this problem. I can't say for sure which version started it, but I'd say it was around the 1.7.3 update.
Any updates on this issue, preliminary fixes maybe?
Hi @GMVitus,
Sorry, not fixed yet.
But it is with major priority.
Best regards, Khouloud
Please help to solve this bug.
Prestashop version 1.7.4.2
Yes we need it to :(
I've checked it, this is an important issue!!
Temporal solution, at least for me. We have a full virtual product Prestashop ecommerce (1.7.4.2), and we made these changes on Cart class (/classes/Cart.php). The problem was that, if the full cart was virtual, the Cart Rules weren't added to cart final calculation.
With this modifications, at a full-virtual-product-ecommerce, the results are OK.
@khouloudbelguith can you validate these changes?
Regards,
Thank you! It helped me
Thanks for diving into this @Xaconi
Would you be willing to make a pull request on GitHub with your code suggestion?
https://github.com/PrestaShop/PrestaShop/tree/develop
Thank you!
Thanks @Xaconi it worked!!
Would someone be willing to make a pull request on GitHub with your code suggestion?
https://github.com/PrestaShop/PrestaShop/tree/develop
Thank you!
Same issue here, tried update to 1.7.4.4
no changes :-(
@pantle, sorry not fixed yet.
But you can try the fix described by @Xaconi https://github.com/PrestaShop/PrestaShop/issues/10264#issuecomment-427342155
Thanks!
@all thank you ev'rybody. xaconi's suggestion worked. Didn't check other carts for checkout yet. but the error is gone. THANK YOU!
- Cart.php:1884 => Added Cart::BOTH_WITHOUT_SHIPPING to the array to check at the IF statement
- Cart.php:1905 => Move the "case Cart::BOTH_WITHOUT_SHIPPING:" to the "case Cart::BOTH:" case
⚠️❌ TRIED and worked for virtual products ONLY in the cart. If custumer tries to puts a normal product into the cart nothing happens. the "ADD TO CART" button is without action. If there is a normal and virtual product in the cart the custumer gets a WHITE SCREEN.
I can concur this is an issue still even in 1.7.5, and a big one. The fix about causes an infinite loop and then swallows all PHP memory if you have a virtual and physical product in the cart. This really needs fixing
Hi!
I've have the same problem with the cart rules with virtual products in Prestashop 1.7.5.0.
The Cart.php at the line 1884 has this:
// check type $type = (int) $type; $allowedTypes = array( Cart::ONLY_PRODUCTS, Cart::ONLY_DISCOUNTS, Cart::BOTH, Cart::BOTH_WITHOUT_SHIPPING, Cart::ONLY_SHIPPING, Cart::ONLY_WRAPPING, Cart::ONLY_PHYSICAL_PRODUCTS_WITHOUT_SHIPPING, );
This seems ok because it has the line Cart::BOTH_WITHOUT_SHIPPING,.
At the line 1932:
// CART CALCULATION $cartRules = array(); if (in_array($type, [Cart::BOTH, Cart::ONLY_DISCOUNTS])) { $cartRules = $this->getCartRules(); } $calculator = $this->newCalculator($products, $cartRules, $id_carrier); $computePrecision = $this->configuration->get('_PS_PRICE_COMPUTE_PRECISION_'); switch ($type) { case Cart::ONLY_SHIPPING: $calculator->calculateRows(); $calculator->calculateFees($computePrecision); $amount = $calculator->getFees()->getInitialShippingFees(); break; case Cart::ONLY_WRAPPING: $calculator->calculateRows(); $calculator->calculateFees($computePrecision); $amount = $calculator->getFees()->getInitialWrappingFees(); break; case Cart::BOTH: $calculator->processCalculation($computePrecision); $amount = $calculator->getTotal(); break; case Cart::BOTH_WITHOUT_SHIPPING: case Cart::ONLY_PRODUCTS: $calculator->calculateRows(); $amount = $calculator->getRowTotal(); break; case Cart::ONLY_DISCOUNTS: $calculator->processCalculation($computePrecision); $amount = $calculator->getDiscountTotal(); break; default: throw new \Exception('unknown cart calculation type : ' . $type); }
I've tried 2 different things:
In both cases, the discount doesn't applied. Does anybody knows how can I resolve it?
Thanks in advance!
Got no clue, but I wonder why the Case
Cart::ONLY__VIRTUAL_PRODUCTS,
is missing.
On prestashop 1.7.5 same problem
Resolved with this method
in cart.php:
search for( at the line 1910)
if ($virtual && $type == Cart::BOTH) {
$type = Cart::BOTH_WITHOUT_SHIPPING;
}
change to
if ($virtual && $type == Cart::BOTH) {
$type = Cart::BOTH;
}
tried with virtual and physical product in the same cart and no issue.
try and tell me.
Hi @nziria,
Would you be willing to make a pull request on GitHub with your code suggestion?
https://github.com/PrestaShop/PrestaShop/tree/develop
Thank you!
Sorry but I haven't time. You can make the pull and mention me if the code work and I see the pull request have you created. Thanks
On prestashop 1.7.5 same problem
Resolved with this methodin cart.php:
search for( at the line 1910)
if ($virtual && $type == Cart::BOTH) { $type = Cart::BOTH_WITHOUT_SHIPPING; }
change to
if ($virtual && $type == Cart::BOTH) { $type = Cart::BOTH; }
tried with virtual and physical product in the same cart and no issue.
try and tell me.
this bug fix worked for me (had the same issue under 1.7.5
Yes! It works!
Thank you @nziria!
I have 1.7.4.4 and in /classes/Cart.php
I found if ($virtual && $type == Cart::BOTH) {
in line 1860
I changed line 1861 into $type = Cart::BOTH;
As long as I can see it works. Even checked both: Voucher for virtual and voucher for normal product together in the same cart and it worked for me.
Thanks for now @nziria !
Glad to see that works. hope for fix in the next minor update
@nziria Hi ! I created a PR with your fix: https://github.com/PrestaShop/PrestaShop/pull/12384
I credited you in the commit message. I tried to also make you the author of the commit (following this method) but I need your email then. If you want to be credited as the commit's author, please provide me your email ;)
On my customized 1.6.1.4 I have two options more^^
Fixed by https://github.com/PrestaShop/PrestaShop/pull/12965 however since this topic can be larger than what we thing, feel free to open other issues if you find other bugs related to virtual products. This bug, reported and diagnosed, is fixed so the issue can be closed.
https://github.com/PrestaShop/PrestaShop/issues/10264#issuecomment-458485085
Thx Work in 1.7.5
I NOW have auto-updated to 1.7.5.2 and error occurs again. 😖
So in /classes/Cart.php
I found
if ($virtual && $type == Cart::BOTH) {
at line 1910
I changed line 1911 from $type = Cart::BOTH_WITHOUT_SHIPPING;
into $type = Cart::BOTH;
TESTING FOR THE TIME BEEING!!!
seems to be working . . .
Hi @pantle,
This issue is fixed in PS1.7.6.0.
Here's the PR: https://github.com/PrestaShop/PrestaShop/pull/12965 to fix the issue.
Thanks!
Most helpful comment
On prestashop 1.7.5 same problem
Resolved with this method
in cart.php:
search for( at the line 1910)
if ($virtual && $type == Cart::BOTH) { $type = Cart::BOTH_WITHOUT_SHIPPING; }
change to
if ($virtual && $type == Cart::BOTH) { $type = Cart::BOTH; }
tried with virtual and physical product in the same cart and no issue.
try and tell me.