Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

My WP site sells customized t-shirts. The customization plugin makes each customized shirt a line item in the woocommerce cart. If there are 2 shirts ordered of one design (quantity of 2 on that line item) I want to discount. But if there is just 1 item per line I dont want to discount.

I found this solution

Adding a discount by cart items conditionally based on the item quantity

But this seems to change the product price in the db, so after the discount kicks in for say 2 blue shirts because there were 2 ordered on 1 line, if I add a 3rd shirt on a separate line it also gets the discount, which I dont want.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
499 views
Welcome To Ask or Share your Answers For Others

1 Answer

Since woocommerce version 3+ the linked answer code doesn't work. It needs something different and can even be done in a better way.

The code will apply a cart item discount based on the cart item quantity. In this code example, it will apply a discount of 5% on the cart item, when the quatity is equal or more than 2 (two).

The cart item unit price displayed is always the real product price. The discount will be effective and displayed on the cart item subtotal.

Additionally the product name will be appended with a discount mention.

The code:

add_filter('woocommerce_add_cart_item_data', 'add_items_default_price_as_custom_data', 20, 3 );
function add_items_default_price_as_custom_data( $cart_item_data, $product_id, $variation_id ){
    $product_id = $variation_id > 0 ? $variation_id : $product_id;

    ## ----- YOUR SETTING ----- ##
    $discount_percentage = 5; // Discount (5%)

    // The WC_Product Object
    $product = wc_get_product($product_id);

    // Only for non on sale products
    if( ! $product->is_on_sale() ){
        $price = (float) $product->get_price();

        // Set the Product default base price as custom cart item data
        $cart_item_data['base_price'] = $price;

        // Set the Product discounted price as custom cart item data
        $cart_item_data['new_price'] = $price * (100 - $discount_percentage) / 100;

        // Set the percentage as custom cart item data
        $cart_item_data['percentage'] = $discount_percentage;
    }

    return $cart_item_data;
}

// Display the product original price
add_filter('woocommerce_cart_item_price', 'display_cart_items_default_price', 20, 3 );
function display_cart_items_default_price( $product_price, $cart_item, $cart_item_key ){
    if( isset($cart_item['base_price']) ) {
        $product        = $cart_item['data'];
        $product_price  = wc_price( wc_get_price_to_display( $product, array( 'price' => $cart_item['base_price'] ) ) );
    }
    return $product_price;
}

// Display the product name with the discount percentage
add_filter( 'woocommerce_cart_item_name', 'append_percetage_to_item_name', 20, 3 );
function append_percetage_to_item_name( $product_name, $cart_item, $cart_item_key ){
    if( isset($cart_item['percentage']) && isset($cart_item['base_price']) ) {
        if( $cart_item['data']->get_price() != $cart_item['base_price'] )
            $product_name .= ' <em>(' . $cart_item['percentage'] . '% discounted)</em>';
    }
    return $product_name;
}

add_action( 'woocommerce_before_calculate_totals', 'custom_discounted_cart_item_price', 20, 1 );
function custom_discounted_cart_item_price( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

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

    ## ----- YOUR SETTING ----- ##
    $targeted_qty = 2; // Targeted quantity

    // Loop through cart items
    foreach ( $cart->get_cart() as $cart_item ) {

        // For item quantity of 2 or more
        if( $cart_item['quantity'] >= $targeted_qty && isset($cart_item['new_price']) ){

            // Set cart item discounted price
            $cart_item['data']->set_price($cart_item['new_price']);
        }
    }
}

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

enter image description here


To display the discounted product price instead of the original product price, just remove woocommerce_cart_item_price() function (and hook)

Newest similar: Cart item quantity progressive percentage discount in Woocommerce 3


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...