phpwordpresswoocommercecheckoutdiscount

Quantity discount of one free product in WooCommerce


I have three products that I want to give as a free item. If anyone adds more quantity from an item I want to give only one quantity as free. That means deducting price of one quantity from the subtotal. For example: the price of a product is 4 and the total quantity added is 5. So the total subtotal will be 20. Now, I want to deduct the price of one quantity from the subtotal. So, the final outcome will be subtotal 15, after deducting the price.

I have tried this code.

$free_items_id = [344,345,346];
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
if ( in_array( $cart_item['product_id'], $free_items_id ) ) {
   if ( $cart_item['quantity'] > 1 ) {
    $price_to_be_deducted = $cart_item['data']->get_price();
    $updated_price = ( $cart_item['quantity'] - 1 ) * $price_to_be_deducted;
        $cart_item['data']->set_price( $updated_price );
    break;
    }
   else {
    $cart_item['data']->set_price( 0 );
   }
}
}

But this code multiplies the $updated_price with the total quantity number of the product. Can anyone give any solution.


Solution

  • To discount the price of one product (for specific defined products), when the quantity is up to 2, try the following (you can change the minimum required quantity):

    add_action( 'woocommerce_before_calculate_totals', 'action_before_calculate_totals');
    function action_before_calculate_totals( $cart ) {
        if ((is_admin() && !defined('DOING_AJAX')))
            return;
    
        if (did_action('woocommerce_before_calculate_totals') >= 2)
            return;
    
        $targeted_ids  = [344,345,346]; // Here define the valid products Ids
        $qty_threshold = 2; // Here define the minimum quantity required
    
        foreach ( $cart->get_cart() as $cart_item ) {
            if ( in_array( $cart_item['product_id'], $targeted_ids ) ) {
                $quantity = $cart_item['quantity'];
                if ( $quantity >= $qty_threshold ) {
                    $discounted_price = $cart_item['data']->get_price() / $quantity * ($quantity - 1);
                    $cart_item['data']->set_price( $discounted_price );
                }
            }
        }
    }
    

    Or (in the same way), you can add a global calculated discount subtotal like:

    add_action( 'woocommerce_cart_calculate_fees', 'action_cart_calculate_fees', 30, 1 );
    function action_cart_calculate_fees( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        $targeted_ids  = [344,345,346]; // Here define the valid products Ids
        $qty_threshold = 2; // Here define the minimum quantity required
        $discount      = 0; // Initializing
    
        foreach ( $cart->get_cart() as $cart_item ) {
            if ( in_array( $cart_item['product_id'], $targeted_ids ) ) {
                if ( $cart_item['quantity'] >= $qty_threshold ) {
                    $discount += $cart_item['data']->get_price();
                }
            }
        } 
        
        if( $discount > 0 ) {
            $cart->add_fee( __( "Quantity discount", "woocommerce" ), -$discount);
        }
    }
    

    Both ways should work.