Hello,
I discovered a major bug with using coupon codes in the cart and removing products from that cart and having coupon codes with only allowed products and a minimum order amount. When I add 2 products to the cart, and remove one of the products and the price will come below that of the minimum order amouont of the coupon it will get an error 500:
E_ERROR:1 0: array_intersect(): Argument #1 ($array) must be of type array, null given in file: /administrator/components/com_virtuemart/helpers/calculationh.php line: 1143
Product 1 = 100 euro
Product 2 = 20 euro
Coupon code = 30 euro discount with a minimum of 90 euro.
Now when I add the 2 products to the cart I will have a total amount of 120 euro. I can add the coupon code. It will become 90 euro. Now when I remove Product 1 the total will be 20 euro, i now get a error 500:
E_ERROR:1 0: array_intersect(): Argument #1 ($array) must be of type array, null given in file: /administrator/components/com_virtuemart/helpers/calculationh.php line: 1143
It's this block of code:
if(!empty($_data->virtuemart_product_ids) || !empty($_data->virtuemart_category_ids)){
$sizeof_cartitems_by_product = count($this->_cart->productsQuantity);
if(empty($allowed_product_ids)) $allowed_product_ids = array();
if(empty($allowed_productcat_ids)) $allowed_productcat_ids = array();
$coupon_discount = 0;
for($i = 0; $i < $sizeof_cartitems_by_product; $i++){
if( (!empty($allowed_product_ids) and in_array($this->_cart->cartPrices[$i]['virtuemart_product_id'],$allowed_product_ids)) || (!empty($allowed_productcat_ids) and array_intersect($this->_cart->products[$i]->categories, $allowed_productcat_ids))){
$coupon_discount += ($this->_cart->cartPrices[$i]['salesPriceTt'] * ($_data->coupon_value / 100));
}
}
$this->_cart->cartPrices['salesPriceCoupon'] = ($_value_is_total ? $_data->coupon_value * -1 : $coupon_discount * -1);
}
I added a fix by adding this peice of code:
if(is_array($this->_cart->products[$i]->categories)){
} else {
return;
}
So the end result would be:
if(!empty($_data->virtuemart_product_ids) || !empty($_data->virtuemart_category_ids)){
$sizeof_cartitems_by_product = count($this->_cart->productsQuantity);
if(empty($allowed_product_ids)) $allowed_product_ids = array();
if(empty($allowed_productcat_ids)) $allowed_productcat_ids = array();
$coupon_discount = 0;
for($i = 0; $i < $sizeof_cartitems_by_product; $i++){
if(is_array($this->_cart->products[$i]->categories)){
if( (!empty($allowed_product_ids) and in_array($this->_cart->cartPrices[$i]['virtuemart_product_id'],$allowed_product_ids)) || (!empty($allowed_productcat_ids) and array_intersect($this->_cart->products[$i]->categories, $allowed_productcat_ids))){
$coupon_discount += ($this->_cart->cartPrices[$i]['salesPriceTt'] * ($_data->coupon_value / 100));
}
} else {
return;
}
}
$this->_cart->cartPrices['salesPriceCoupon'] = ($_value_is_total ? $_data->coupon_value * -1 : $coupon_discount * -1);
}
Maybe Max could take a look at this and see if this is correct. For now it works, and I don't get a error 500.
EDIT: It also shows a minus total value but that is corrected in the next step. Maybe it's an idea to remove the coupon code so it won't show the minus total value (20 - 30 = -10)
Hello Kuubs, great work, thank you.
I think the code should be just
if( (!empty($allowed_product_ids) and in_array($this->_cart->cartPrices[$i]['virtuemart_product_id'],$allowed_product_ids))
|| (!empty($allowed_productcat_ids and !empty($this->_cart->products[$i]->categories)) and array_intersect($this->_cart->products[$i]->categories, $allowed_productcat_ids))){
Yes the coupon should be removed. Removing the coupon is simple. We just need to set here
$this->_cart->cartData['couponCode'] = '';
Would be cool you play around with it, where to set the line.
Quote from: Milbo on October 16, 2023, 20:09:45 PM
Hello Kuubs, great work, thank you.
I think the code should be just
if( (!empty($allowed_product_ids) and in_array($this->_cart->cartPrices[$i]['virtuemart_product_id'],$allowed_product_ids))
|| (!empty($allowed_productcat_ids and !empty($this->_cart->products[$i]->categories)) and array_intersect($this->_cart->products[$i]->categories, $allowed_productcat_ids))){
Yes the coupon should be removed. Removing the coupon is simple. We just need to set here
$this->_cart->cartData['couponCode'] = '';
Would be cool you play around with it, where to set the line.
Awesome thank you! Hopefully this will be integrated in the new update. Thanks!
I'm having some issues where I can set the coupon value to 0 again when the products in the cart are not getting to the treshhold of the minimum order amount. When you remove a product to come below the minimum amount it should calculate again and remove the coupon code. But i'm not sure where i can do that/
I tried checking the files myself but I'm not sure where to find it. Possibly cart.php or coupon.php helper files?
It's fixed in the new release. Thank you Max!