I am encountering some issues with my condition to check for cart total, amongst cart quantity and shipping classes.
What I am trying to achieve
I am trying to hide a specific shipping method free_shipping:7
based on quantity of other specific shipping classes and cart total.
The problem I am encountering is that my conditional logic won’t work after using ||
(or) operator, it will not check for cart total, if I also check for quantity.
The code
/* Hide free shipping unless minimum of 6 bottle or 1 box is selected, or if 2 gins and under 600 cart total */
add_filter( 'woocommerce_package_rates', 'hide_free_shipping_method', 10, 2 );
function hide_free_shipping_method( $rates, $package )
{
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Shipping class to check for
$class1 = 132; // shipping class for bottles
$class2 = 131; // shipping class for boxes
$class3 = 142; // shipping class for gin bottles
// Shipping method to hide
$ShipMethod_key_ids = array('free_shipping:7'); // free shipping
// Get cart total of items in the cart, but after discounts.
$cart_totals = WC()->cart->cart_contents_total;
// Keep track of the quantity of items with the specified shipping class
$quantity_bottle = 0;
$quantity_gin = 0;
$quantity_box = 0;
// Loop through cart content and add to specified shipping classes
if( $item['data']->get_shipping_class_id() == $class1 || $item['data']->get_shipping_class_id() == $class3){
$quantity_bottle += $item['quantity'];
$quantity_gin += $item['quantity'];
}
elseif ( $item['data']->get_shipping_class_id() == $class2 ) {
$quantity_box += $item['quantity'];
}
}
// If there are less than 6 bottles, 6 gins, and less than 1 box
// or
// if equal to 2 gins and less than 600 in Cart Total, hide the shipping method
if( $quantity_bottle < 6 && $quantity_gin < 6 && $quantity_box < 1 || $quantity_gin == 2 && $cart_totals < 600 ) {
foreach( $ShipMethod_key_ids as $method_key_id ){
unset($rates[$method_key_id]);
}
}
return $rates;
}
Problem
The problem I have is that the condition which checks for cart total, does not work when combined with ||
(or) operators.
if( $quantity_bottle < 6 && $quantity_gin < 6 && $quantity_box < 1 || $quantity_gin == 2 && $cart_totals < 600 ) {
If I use the combined example, as above, the code will neglect the last condition (2).
The condition will only work with one of the two:
-
$quantity_bottle < 6 && $quantity_gin < 6 && $quantity_box < 1
-
$quantity_gin == 2 && $cart_totals < 600
What I have tried
I have tried isolating the two conditions to check if they work. They do work on their own, but not in combination.
I have also tried to write them in separate if
statements, but without any results.
Question
Can someone explain to me what am I doing wrong in this example? and what can I do to make it check for both statements?
Is it possible for me to achieve above without having to implement two different codes for each logic?
List of references
how to check the quantity of products in the woocommerce cart
Change flat rate shipping rate based on item cart totals belonging to specific shipping class
Conditionally Hide WooCommerce Shipping methods based on shipping class
2
Answers
So the major issue was with my logical expression. When we use
||
(OR), it will return true if either$a or $b
is true. Whereas if we use&&
(AND) it will return true if both$a and $b
are true.I also made sure to loop through cart items checking for shipping classes and add to the variables separately. This made my first expression invalid
$quantity_bottle < 6 && $quantity_gin < 6 && $quantity_box < 1
, but was needed for my second expression$quantity_gin == 2 && $cart_totals < 600
. In order to make my first expression work, I add a new variable which counts bottle quantity and gin bottle quantity total.So the condition ended up being:
if (($quantity_bottle < 6 && $quantity_gin < 6 && $quantity_box < 1 && $total_bottle_quantity_cart < 6 ) && !($quantity_gin >= 2 && $subtotaltax > 600 ) )
The full code below:
Could someone help me. I would like a code that gives me free shipping if I make a minimum purchase. The minimum value of 5 products is 1000