Asked  7 Months ago    Answers:  5   Viewed   41 times

In WooCommerce, I have a category of products called Samples, each sample costs $2.99. But I'd like a way to automatically change the cost of the Samples from $2.99 to $1 when 5 Samples are added to cart.

So if 4 samples are added to cart, the total would be $11.96… but if 5 were added the total would be $5.

So for every 5 products, the product price would change from $2.99 to $1 but if 6 Samples were added to cart the total would be $7.99 and if 10 were added the total would be $10 etc...

How could I achieve this?

Thanks.

 Answers

59

UpdateAdded Woocommerce 3 compatibility.

Here is something that should be convenient to your requirements.
This function will add discount to cart:

add_action( 'woocommerce_cart_calculate_fees','custom_cart_discount', 20, 1 );
function custom_cart_discount( $cart ) {

    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    // Define HERE your targeted product category (id, slug or name are accepted)
    $category = 'posters';
    // Set the price for Five HERE
    $price_x5 = 5;

    // initializing variables
    $calculated_qty = 0;
    $calculated_total = 0;
    $discount = 0;

    // Iterating through each cart item
    foreach($cart->get_cart() as $cart_item):

        // Make this discount calculations only for products of your targeted category
        if(has_term($category, 'product_cat', $cart_item['product_id'])):
            $item_price = version_compare( WC_VERSION, '3.0', '<' ) ? $cart_item['data']->price : $cart_item['data']->get_price(); // The price for one (assuming that there is always 2.99)
            $item_qty = $cart_item["quantity"];// Quantity
            $item_line_total = $cart_item["line_total"]; // Item total price (price x quantity)
            $calculated_qty += $item_qty; // ctotal number of items in cart
            $calculated_total += $item_line_total; // calculated total items amount
        endif;
    endforeach;

    // ## CALCULATIONS (updated) ##
    if($calculated_qty >= 5):      
        for($j = 5, $k=0; $j <= $calculated_qty; $j+=5,$k++); // Update $k=0 (instead of $k=1)
        $qty_modulo = $calculated_qty % 5;
        $calculation = ( $k * $price_x5 ) + ($qty_modulo * $item_price);
        $discount -= $calculated_total - $calculation;
    endif;

    // Adding the discount 
    if ($discount != 0)
        $cart->add_fee( __( 'Quantity discount', 'woocommerce' ), $discount, false );
        // Note: Last argument in add_fee() method is related to applying the tax or not to the discount (true or false)
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.

Wednesday, March 31, 2021
 
SkyNet
answered 7 Months ago
61

Updated July 2020

If you are still using the code from my answer to your previous question, you can change it a bit to get this working too:

add_action('woocommerce_cart_calculate_fees', 'add_custom_discount_2nd_at_50', 10, 1 );
function add_custom_discount_2nd_at_50( $cart ){
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) 
        return;

    // YOUR SETTINGS:
    $targeted_product_id = 40; // Set HERE your targeted product ID

    // Initializing variables
    $discount = $qty_notice = 0;
    $items_prices = array();

    // Loop through cart items
    foreach ( $cart->get_cart() as $key => $cart_item ) {
        if( in_array( $targeted_product_id, [$cart_item['product_id'], $cart_item['variation_id']] ) ){
            $quantity = (int) $cart_item['quantity'];
            $qty_notice += $quantity;
            for( $i = 0; $i < $quantity; $i++ ) {
                $items_prices[] = floatval( $cart_item['data']->get_price());
            }
        }
    }

    $count_items = count($items_prices); // Count items

    rsort($items_prices); // Sorting prices descending order

    if( $count_items > 1 ) {
        foreach( $items_prices as $key => $price ) {
            if( $key % 2 == 1 )
                $discount -= number_format( $price / 2, 2 );
        }
    }

    // Applying the discount
    if( $discount != 0 ){
        $cart->add_fee('Buy one get one 50% off', $discount );

        // Displaying a custom notice (optional)
        wc_clear_notices(); // clear other notices on checkout page.
        if( ! is_checkout() ){
            wc_add_notice( __("You get 50% of discount on the 2nd item"), 'notice');
        }
    }
    //  Display a custom notice on cart page when quantity is equal to 1.
    elseif( $qty_notice == 1 ){
        wc_clear_notices(); // clear other notices on checkout page.
        if( ! is_checkout() ){
            wc_add_notice( __( "Add one more to get 50% off on 2nd item" ), 'notice');
        }
    }
}

Code goes in functions.php file of your active child theme (or active theme) Tested and works.

Note: The wc_add_notice() function absolutely don't need to be echoed

Wednesday, March 31, 2021
 
Stefan
answered 7 Months ago
62

There is something missing in your code to target specific product category. Try the following:

add_action( 'woocommerce_before_calculate_totals', 'quantity_based_pricing', 9999 );
function quantity_based_pricing( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) 
       return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) 
        return;

    // Define categories and discount rules (quantity threshold and discount amount)
    $categories = array('example');
    $threshold1 = 2;  // Change price if items > 1
    $discount1  = 10; // Reduce unit flat price by 10
    $threshold2 = 3;  // Change price if items > 2
    $discount2  = 20; // Reduce unit flat price by 20

    // Loop through cart items
    foreach ( $cart->get_cart() as $cart_item ) {
        // Target specific product category(ies)
        if ( has_term ($categories, 'product_cat', $cart_item['product_id']) ) {
            if ( $cart_item['quantity'] >= $threshold1 && $cart_item['quantity'] < $threshold2 ) {
                $price = round( $cart_item['data']->get_price() - $discount1, 2 );
                $cart_item['data']->set_price( $price );
            } elseif ( $cart_item['quantity'] >= $threshold2 ) {
                $price = round( $cart_item['data']->get_price() - $discount2, 2 );
                $cart_item['data']->set_price( $price );
            }
        }    
    }
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.

Wednesday, March 31, 2021
 
turik
answered 7 Months ago
88

You can use TEXT
=TEXT(B1-A1,"d:h:mm")

Note the same effect can be achieved using a simple number format on the cells directly

  • select your range (cells C1, C2 etc)
  • right click and Format Cells
  • Custom
  • Type d:hh:mm

If unlike your example data, your date differences exceed 31 days, then an approach such as =INT(B1-A1)&":"&TEXT(B1-A1,"h:mm")
will work

Friday, July 30, 2021
 
shwabob
answered 3 Months ago
12

Based on (this answer) WooCommerce Cart Quantity Base Discount, you can add a progressive fee based on total number of items:

add_action( 'woocommerce_cart_calculate_fees','woocommerce_cart_extra_cost', 10, 1 );
function woocommerce_cart_extra_cost( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )  return;

    $cart_item_count = $cart->get_cart_contents_count();

    // CONDITIONAL ITEMS QUANTITY FEE AMOUNT
    if( $cart_item_count < 6 )
        $fee = 0;
    elseif( $cart_item_count >= 6 && $cart_item_count < 12 )
        $fee = 5;
    elseif( $cart_item_count >= 12 )
        $fee = 10;

    if( $fee > 0 )
        $cart->add_fee( __( "Extra Cost", "woocommerce" ), $fee, true);
}

Code goes in functions.php file of your active child theme (or theme) or also in any plugin file.

Tested and works.

Friday, August 6, 2021
 
tika
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :