3
votes

I wish to set up a specific discount on a particular variable products but for certain selected variations not for all variation: eg : my varible id - 1571
variation id - 1572
variation id - 1573

So if customer buys one product they get the another (the same) on 50% discount (Buy one get another for 50% off).

I've tried many discount plugins and the closest that I have found are:

With some of them, I was able to setup discount on subtotal or discount on a each product but not exactly what I am looking for (Buy 1 get 1 off). There are other pro plugins I don't want to go for it.

The nearest code that I found is WooCommerce discount: buy one get one 50% off with a notice.

Is it possible to make a discount on the 2nd item for specific product variations of a variable product (only for each product variation)?

  1. mak
2
When you are asking a question where the code comes from an existing answer code without making real changes to it, don't use it in your question, and always add the related link to the original answer please…LoicTheAztec

2 Answers

2
votes

To get a 50% Off on the 2nd item for some specific product variations of a variable product, you will use the following instead:

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:
    $product_variations_ids = array(1572, 1573); // <== HERE your targeted product variations

    // Initializing variables
    $discount = 0;
    $product_names = array();

    // Loop through cart items
    foreach ( $cart->get_cart() as $key => $cart_item ) {
        if ( in_array( $cart_item['variation_id'], $product_variations_ids ) ) {
            $qty   = (int)    $cart_item['quantity'];
            $price = (float)  $cart_item['data']->get_price();
            $name  = (string) $cart_item['data']->get_name();

            if ( $qty > 1 ) {
                $discount -= number_format( $price / 2, 2 );
            }
            elseif( $qty = 1 ) {
                $product_names[] = $name;
            }
        }
    }

    // Applying the discount
    if( $discount != 0 ){
        $cart->add_fee('Buy one get one 50% off', $discount );
    }
    
    //  Display a custom reminder notice on cart page (otional)
    if( ! empty($product_names) ){
        wc_clear_notices(); // clear other notices on checkout page.
        if( ! is_checkout() ){
            wc_add_notice( sprintf(
                __( "Add one more to get 50%% off on the 2nd item for %s" ),
                '"<strong>' . implode(', ', $product_names) . '</strong>"'
            ), 'notice' );
        }
    }
}

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


To get 1 item at 50% OFF for each item purchased, instead of 50% OFF on the 2nd item, replace:

$discount -= number_format( $price / 2, 2 );

by:

$multiplier = ( $qty % 2 ) === 0 ? $qty / 2 : ( $qty - 1 ) / 2;
$discount  -= number_format( $price / 2 * $multiplier, 2 );

To get the 2nd one Free instead of 50% OFF on the 2nd item, replace the code line:

$discount -= number_format( $price / 2, 2 );

by:

$discount -= $price;

To get 1 item free for each item purchased, instead of 50% OFF on the 2nd item, replace:

$discount -= number_format( $price / 2, 2 );

by:

$multiplier = ( $qty % 2 ) === 0 ? $qty / 2 : ( $qty - 1 ) / 2;
$discount  -= $price * $multiplier;
0
votes

You were really close!
The discount amount calculation were wrong

add_action('woocommerce_cart_calculate_fees', 'add_custom_discount_2nd_at_50', 10, 1 );
function add_custom_discount_2nd_at_50( $wc_cart ){

if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
$discount = 0;
$items_prices = array();
$qty_notice = 0;  //  <==  Added HERE

// Set HERE your targeted variable product ID
$targeted_product_id = 1571 ;

foreach ( $wc_cart->get_cart() as $key => $cart_item ) {
    if( $cart_item['product_id'] == $targeted_product_id ){
        $qty = intval( $cart_item['quantity'] );
        $qty_notice += intval( $cart_item['quantity'] ); //  <==  Added HERE
        for( $i = 0; $i < $qty; $i++ )
            $items_prices[] = floatval( $cart_item['data']->get_price());
    }
}
$count_items_prices = count($items_prices);
//to get the discount of lowest price sorting in descending order 
rsort($items_prices);
if( $count_items_prices > 1 ) foreach( $items_prices as $key => $price )
    if( $key % 2 == 1 ) $discount -= number_format($price / 2, 2 );
if( $discount != 0 ){
  // The discount
  # Note: Last argument in add_fee() method is related to applying the tax or not to the discount (true or false)
$wc_cart->add_fee('50% off de segunda almohada' , (($price/2)*($discount))^⁻1, true  ); //EDITED
  // Displaying a custom notice (optional)
  wc_clear_notices();
  if(!is_checkout()){
  wc_add_notice( __("Hurrah!! You got 50% off 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();
  if(!is_checkout()){
    wc_add_notice( __( "Add one more to get 50% off on 2nd item" ), 'notice');
}}
}