4
votes

In Woocommerce, I would like to set a percentage discount based on customer total purchases sum. For example if the total purchase sum greater or equal to 200$, customer get 5% discount.

So, I have first part of code for showing the total sum:

function get_customer_total_order() {
    $customer_orders = get_posts( array(
        'numberposts' => - 1,
        'meta_key'    => '_customer_user',
        'meta_value'  => get_current_user_id(),
        'post_type'   => array( 'shop_order' ),
        'post_status' => array( 'wc-completed' )
    ) );

    $total = 0;

    foreach ( $customer_orders as $customer_order ) {
        $order = wc_get_order( $customer_order );
        $total += $order->get_total();
    }

    return $total;
}

And I would like to use my code with the code of this answer:
Progressive discount based on cart total in WooCommerce

It there a way to use them both to set the discount based on total sum of all orders?

1

1 Answers

5
votes

There is multiple ways to get customer's total purchases sum:

1) You could replace your first function using wc_get_customer_total_spent() dedicated Woocommerce function, but this function take all orders paid status ( which are "processing" and "completed").

2) You could also use this lighter SQL query based on a similar source code for "completed" order status only:

// Utililty function to get customer's total purchases sum
function get_customer_total_purchases_sum() {
    $current_user_id = get_current_user_id(); // Current user ID

    if( $current_user_id == 0 ) return 0; // we return zero if customer is not logged in

    global $wpdb;

    // return the SQL query (paid orders sum)
    return $wpdb->get_var("SELECT SUM(pm.meta_value) FROM {$wpdb->prefix}postmeta as pm
    INNER JOIN {$wpdb->prefix}postmeta as pm2 ON pm.post_id = pm2.post_id
    INNER JOIN {$wpdb->prefix}posts as p ON pm.post_id = p.ID
    WHERE p.post_status LIKE 'wc-completed' AND p.post_type LIKE 'shop_order'
    AND pm.meta_key LIKE '_order_total' AND pm2.meta_key LIKE '_customer_user'
    AND pm2.meta_value LIKE '$current_user_id'");
}

This code goes on function.php file of your active child theme (or theme). Tested and works.

3) Or you can use your own question function code (but it's heavier). It's up to you.


The percentage discount (2 ways):

1) A negative fee:

The following code will set a percentage discount based on customer's total purchases sum (using my function above):

// Percentage discount based on customer's total purchases sum
add_action('woocommerce_cart_calculate_fees', 'customer_purchases_total_sum_percentage_discount', 20, 1 );
function customer_purchases_total_sum_percentage_discount( $cart ){
    // Only for logged in user
    if ( ( is_admin() && ! defined( 'DOING_AJAX' ) ) || ! is_user_logged_in() )
        return;

    ## 1. Get the customer's purchases total sum (and save it in WC sessions to avoid multiple queries

    // Check if it's saved in WC_Session
    $purchases_sum = WC()->session->get( 'purchases_sum' ); 
    // If not get it and save it
    if( empty($purchases_sum) ){ 
        // ==> HERE goes the function to get customer's purchases total sum
        $purchases_sum = get_customer_total_purchases_sum();
        // Save it in WC_Session
        WC()->session->set('purchases_sum', $purchases_sum); 
    }

    ## 2. Set the discount percentage based on customer's total purchases sum
    if( $purchases_sum >= 200 ){
        $percent =  5; // 5%
    }

    if( isset($percent) && $percent > 0){
        $discount = $cart->cart_contents_total * $percent / 100; // discount calculation
        // Set the discount (For discounts (negative fee) the taxes as always included)
        $cart->add_fee( __('Discount', 'woocommerce' ) . " (" . $percent . "%)", -$discount);
    }
}

This code goes on function.php file of your active child theme (or theme). Tested and works.


2) Auto adding a coupon code (percentage discount):

First you need to set a new coupon code (percentage discount type of 5%):

enter image description here

Then you will use the following code instead that will auto add a coupon code based on customer's total purchases sum (using my function above):

add_action( 'woocommerce_before_calculate_totals', 'customer_total_purchases_coupon_discount', 30, 1 );
function customer_total_purchases_coupon_discount( $cart ) {
    // Only for logged in user
    if ( ( is_admin() && ! defined( 'DOING_AJAX' ) ) || ! is_user_logged_in() )
        return;

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

    // HERE define your coupon code (in lowercase)
    $coupon_code = 'customersilver';

    ## 1. Get the customer's purchases total sum (and save it in WC sessions to avoid multiple queries

    // Check if it's saved in WC_Session
    $purchases_sum = WC()->session->get( 'purchases_sum' );
    // If not get it and save it
    if( empty($purchases_sum) ){
        // ==> HERE goes the function to get customer's purchases total sum
        $purchases_sum = get_customer_total_purchases_sum();
        // Save it in WC_Session
        WC()->session->set('purchases_sum', $purchases_sum);
    }

    ## 2. Auto applying or removing a coupon code (percentage discount coupon)

    // Apply the coupon if there is at least 2 units of "5 Reusable wet"
    if ( ! $cart->has_discount( $coupon_code ) && $purchases_sum >= 200 ) {
        $cart->add_discount( $coupon_code );
    } elseif( $cart->has_discount( $coupon_code ) && $purchases_sum < 200 ) {
        $cart->remove_coupon( $coupon_code );
    }
}

This code goes on function.php file of your active child theme (or theme). Tested and works.