3
votes

I have set up a Woocommerce shop and wish to set up a specific discount on all products based on multiples of 12 (a box). I've tried many discount plugins but haven't found what I am looking for.

For example, if I order 12 of product X, I get a 10% discount. If I order 15 of product X, I get a 10% discount on the first 12, and the last three are full price. If I order 24, then that 10% discount applies to all 24 of product X.

The closest I have found is this: Discount for Certain Category Based on Total Number of Products

But this is applied as a discount (actually a negative fee) at the end, and I'd like to display the discount in the cart next to the product, like normal discounts.

I also need this discount to be disabled if a product is already on sale.

Thanks.

1

1 Answers

3
votes

This code will not work in Woocommerce 3+

See: Cart item discount based on quantity in Woocommerce 3:

Yes this is also possible, making a custom calculation for each cart item and replacing individually their price (matching your conditions and calculations), using a custom function hooked in woocommerce_before_calculate_totals action hook.

This is the code:

add_action( 'woocommerce_before_calculate_totals', 'custom_discounted_cart_item_price', 10, 1 );
function custom_discounted_cart_item_price( $cart_object ) {

    $discount_applied = false;

    // Set Here your targeted quantity discount
    $t_qty = 12;

    // Iterating through each item in cart
    foreach ( $cart_object->get_cart() as $item_values ) {

        ##  Get cart item data
        $item_id = $item_values['data']->id; // Product ID
        $item_qty = $item_values['quantity']; // Item quantity
        $original_price = $item_values['data']->price; // Product original price

        // Getting the object
        $product = new WC_Product( $item_id );


        // CALCULATION FOR EACH ITEM 
        // when quantity is up to the targetted quantity and product is not on sale
        if( $item_qty >= $t_qty && !$product->is_on_sale() ){
            for($j = $t_qty, $loops = 0; $j <= $item_qty; $j += $t_qty, $loops++);

            $modulo_qty = $item_qty % $t_qty; // The remaining non discounted items

            $item_discounted_price = $original_price * 0.9; // Discount of 10 percent

            $total_discounted_items_price = $loops * $t_qty * $item_discounted_price;

            $total_normal_items_price = $modulo_qty * $original_price;

            // Calculating the new item price
            $new_item_price = ($total_discounted_items_price + $total_normal_items_price) / $item_qty;


            // Setting the new price item
            $item_values['data']->price = $new_item_price;

            $discount_applied = true;
        }
    }
    // Optionally display a message for that discount
    if ( $discount_applied )
        wc_add_notice( __( 'A quantity discount has been applied on some cart items.', 'my_theme_slug' ), 'success' );
}

This make exactly the discount that you are expecting separately for each item in cart (based on it's quantity) and not for items that are in sale. But you will not get any label (text) indicating a discount in the line items of cart.

Optionally I display a notice when a discount is applied to some cart items…

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

This code is tested and works.