My intention is to add multiple bulk dynamic pricing for WooCommerce products with specific product-tag. I use the slug “petit-format” on my code.
Based on Bulk dynamic pricing for WooCommerce products with specific product-tag answer code, this is my attempt:
function bbloomer_quantity_based_pricing( $cart ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return; // count tag found $tag_found = 0; // Loop through cart items, count how many times tag occurs foreach ( $cart->get_cart() as $cart_item ) { // Get an instance of the WC_Product object $product = $cart_item['data']; // Get product id $product_id = $cart_item['product_id']; // if product has tag if( has_term( 'petit-format', 'product_tag', $product_id ) ) { // Get quantity from product in cart $quantity = $cart_item['quantity']; // if product quantity > 1 if ( $quantity > 1) { $tag_found = $tag_found + $quantity; } else { $tag_found += 1; } } } // Define discount rules and thresholds $threshold1 = 2; // Change price if items > 2 $discount1 = 0.142857; // Reduce unit price by 5% $threshold2 = 3; // Change price if items > 3 $discount2 = 0.285714; // Reduce unit price by 10% $threshold3 = 6; $discount3 = 0.428571; $threshold4 = 10; $discount4 = 0.5; $threshold5 = 20; $discount5 = 0.571429; $threshold6 = 50; $discount6 = 0.607143; $threshold7 = 100; // if tag found >= $threshold if ( $tag_found >= $threshold1 ) { // Loop through cart items, add discount foreach ( $cart->get_cart() as $cart_item ) { // Get an instance of the WC_Product object $product = $cart_item['data']; // Get product id $product_id = $cart_item['product_id']; // if product has tag if( has_term( 'petit-format', 'product_tag', $product_id ) ) { // calculate new price $price = round( $cart_item['data']->get_price() * ( 1 - $discount1 ), 2 ); // set new price $cart_item['data']->set_price( $price ); } } } elseif ( $tag_found >= $threshold2 ) { // Loop through cart items, add discount foreach ( $cart->get_cart() as $cart_item ) { // Get an instance of the WC_Product object $product = $cart_item['data']; // Get product id $product_id = $cart_item['product_id']; // if product has tag if( has_term( 'petit-format', 'product_tag', $product_id ) ) { // calculate new price $price = round( $cart_item['data']->get_price() * ( 1 - $discount2 ), 2 ); // set new price $cart_item['data']->set_price( $price ); } } } } add_action( 'woocommerce_before_calculate_totals', 'bbloomer_quantity_based_pricing', 10, 1 );
But I only have the first discount that works, but the other one doesn’t.
So the $discount1
works, but the function doesn’t work with the second discount. Any advice?
My example is with only two discounts, but I need to create more than 10 discounts.
Advertisement
Answer
It is not necessary to go through the entire cart again per condition, apply it in reverse
- Multiple discounts can be granted through the
if/elseif/else
conditions - I have used WC_Cart::get_cart_item_quantities() versus looping through the cart in the first
foreach
loop. Since this is faster
So you get
function action_woocommerce_before_calculate_totals( $cart ) { if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return; if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return; // Settings $term = 'petit-format'; $taxonomy = 'product_tag'; // Initialize $counter = 0; // Loop through cart items, count how many times tag occurs foreach( WC()->cart->get_cart_item_quantities() as $product_id => $cart_item_quantity ) { // Contains the definite term if ( has_term( $term, $taxonomy, $product_id ) ) { // Add the cart item quantity from this certain product to the counter $counter += $cart_item_quantity; } } // Define discount rules and thresholds if ( $counter >= 1 ) { // Less than or equal to 2 if ( $counter <= 2 ) { $discount = 0.05; // Reduce unit price by 5% // Between 2 and 10 } elseif ( $counter > 2 && $counter <= 10 ) { $discount = 0.10; // Reduce unit price by 10% // Between 10 and 20 } elseif ( $counter > 10 && $counter <= 20 ) { $discount = 0.20; // Reduce unit price by 20% // Between 20 and 50 } elseif ( $counter > 20 && $counter <= 50 ) { $discount = 0.50; // Reduce unit price by 50% // Default } else { $discount = 0.05; // Reduce unit price by 5% } // Loop through cart items, add discount foreach ( $cart->get_cart() as $cart_item ) { // Get product ID in $product_id = $cart_item['product_id']; // Contains the definite term if ( has_term( $term, $taxonomy, $product_id ) ) { // calculate new price $price = round( $cart_item['data']->get_price() * ( 1 - $discount ), 2 ); // Set new price $cart_item['data']->set_price( $price ); } } } } add_action( 'woocommerce_before_calculate_totals', 'action_woocommerce_before_calculate_totals', 10, 1 );