Search code examples
wordpresswoocommerceproducthook-woocommercediscount

Add discount per certain number of products on the cheapest products in WooCommerce


I'm adding the discount rule for every 3 products: 3,6,9,12,15.. on the cart and it should apply to discount 50% only the cheapest products.

So if you have 9, only the 3 cheapest gets 50% off.

This code applies a discount to all products, so it should only be every 3 products

add_action('woocommerce_cart_calculate_fees', 'ts_add_custom_discount', 10, 1 );
function ts_add_custom_discount( $wc_cart ){
    $discount = 0;
    $product_ids = array();
    $item_prices = array();
    $in_cart = false;

    foreach ( $wc_cart->get_cart() as $cart_item_key => $cart_item ) {
        $cart_product = $cart_item['data'];
        if ( has_term( 'get2', 'product_cat', $cart_product->get_id() ) ) { // get2 selected category
            $in_cart = true;
        }else {
            $in_cart = true;
            $product_ids[] = $cart_product->get_id();
            $item_prices[$cart_product->get_id()] = $cart_product->get_price();
        }
    }

    if( $in_cart ) {

        $count_ids = count($product_ids);

        asort( $item_prices ); //Sort the prices from lowest to highest

        $cartQuantity = WC()->cart->cart_contents_count;

        $count = 0;

        if( $count_ids > 3 || $cartQuantity >= 3 ) { 
           foreach( $item_prices as $id => $price ) {
                if( $count >= 1 ) {
                    break;
                }
                //$product = wc_get_product( $id );
                //$price = $product->get_price();
                $discount -= ($price * 50) /100;
                $count++;
           }
       }

    } 

    if( $discount != 0 ){
        $wc_cart->add_fee( 'Discount', $discount, true  );
    }
}

I have attached a screenshot, you can see there is a red outline for every 3rd cheapest product.


Solution

  • This answer will apply a 50% discount per 3 products on the cheapest products. (explanation via comment tags added to the code)

    So you get:

    function action_woocommerce_cart_calculate_fees( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
    
        // Products in cart
        $products_in_cart = count( $cart->get_cart() );
    
        // Every so many products
        $every = 3;
    
        // When products in cart greater than or equal to every so many products
        if ( $products_in_cart >= $every ) {
            // Set array
            $product_prices = array();
    
            // Loop though cart items
            foreach ( $cart->get_cart() as $cart_item ) {
                // Product
                $product = $cart_item['data'];
    
                // Get price
                $product_price = $product->get_price();
    
                // Push
                $product_prices[] = $product_price;
            }
    
            // Sort: low to high
            asort( $product_prices );
    
            // Number of products receive a discount
            $products_receive_discount = floor( $products_in_cart / $every );
    
            // Set variable
            $total = 0;
    
            // Loop trough
            foreach ( array_slice( $product_prices, 0, $products_receive_discount ) as $product_price ) {
                // Calculate
                $total += $product_price;
            }
    
            // Calculate discount
            $discount = ( $total * 50 ) / 100;
    
            // Discount
            $cart->add_fee( __( 'Discount', 'woocommerce' ), -$discount, true );
        }
    }
    add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );