Home > front end >  How to display a custom message during WooCommerce checkout to customers who previously purchase pro
How to display a custom message during WooCommerce checkout to customers who previously purchase pro

Time:01-03

I will like to display a message on the checkout page notifying the customers that they have purchased this product in the past (the product they are about to purchase), but this message should only run if these conditions are met.

  1. Customer must be logged in
  2. User role is administrator or customer
  3. previously purchased product should still have order status of 'processing.'

So far, I have been able to get the first 2 conditions working fine:

function user_logged_in_product_already_bought() {

    global $woocommerce;

    if ( ! is_user_logged_in() ) return;
            

    $items = $woocommerce->cart->get_cart();

    $has_bought = false;

    foreach($items as $item => $values) { 
        if ( wc_customer_bought_product( '', get_current_user_id(), $values['data']->get_id() ) ) {
            $has_bought = true;
            break;
        }
    } 


    
    $user = wp_get_current_user();
$allowed_roles = array( 'administrator', 'customer' );
if ( array_intersect( $allowed_roles, $user->roles ) ) {
    
    if( $has_bought ){
        wc_print_notice( "You purchased this in the past. Buy again?", 'success' );
    }
}
        


}
add_action( 'woocommerce_before_checkout_form', 'user_logged_in_product_already_bought' );

Note: the reason I'm using the foreach is that users only purchase one product at a time (can't have more than a single appointment product in the cart)

But I don't know how to go about with the third condition. Any advice?

CodePudding user response:

Your first 2 steps indeed work, for the 3rd step you will have to use a custom function which only checks for the order status 'processing'.

The advantage of this custom function is that it is much faster and lighter compared to going through all existing orders.

So you get:

function has_bought_items( $user_id = 0, $product_ids = 0 ) {
    // When empty, return false
    if ( empty ( $product_ids ) ) return false;

    global $wpdb;
    
    $product_ids = is_array( $product_ids ) ? implode( ',', $product_ids ) : $product_ids;

    $line_meta_value = $product_ids != 0 ? 'AND woim.meta_value IN (' . $product_ids . ')' : 'AND woim.meta_value != 0';

    // Count the number of products
    $count = $wpdb->get_var( "
        SELECT COUNT(p.ID) FROM {$wpdb->prefix}posts AS p
        INNER JOIN {$wpdb->prefix}postmeta AS pm ON p.ID = pm.post_id
        INNER JOIN {$wpdb->prefix}woocommerce_order_items AS woi ON p.ID = woi.order_id
        INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS woim ON woi.order_item_id = woim.order_item_id
        WHERE p.post_status IN ( 'wc-processing' )
        AND pm.meta_key = '_customer_user'
        AND pm.meta_value = '$user_id'
        AND woim.meta_key IN ( '_product_id', '_variation_id' ) $line_meta_value 
    " );

    // Return true if count is higher than 0 (or false)
    return $count > 0 ? true : false;
}
 
function action_woocommerce_before_checkout_form() {
    // Customer must be logged in
    if ( ! is_user_logged_in() ) return;
    
    // Get current user
    $user = wp_get_current_user();
    
    // Allowed user roles
    $allowed_roles = array( 'administrator', 'customer' );
    
    // Compare
    if ( array_intersect( $allowed_roles, $user->roles ) ) {
        // WC Cart NOT null
        if ( ! is_null( WC()->cart ) ) {
            // Initialize
            $product_ids = array();
            
            // Loop through cart contents
            foreach ( WC()->cart->get_cart_contents() as $cart_item ) {
                // Get product ID and push to array
                $product_ids[] = $cart_item['variation_id'] > 0 ? $cart_item['variation_id'] : $cart_item['product_id'];
            }
            
            // Call function, and if true
            if ( has_bought_items( $user->ID, $product_ids ) ) {
                // Notice
                wc_print_notice( __( 'You purchased this in the past. Buy again?', 'woocommerce' ), 'success' );
            }
        }
    }
}
add_action( 'woocommerce_before_checkout_form', 'action_woocommerce_before_checkout_form' );

Result: a general message

enter image description here


Optional: Instead of displaying a general message, but showing this separately per product, you can use the woocommerce_checkout_cart_item_quantity hook

So you would get:

function has_bought_items( $user_id = 0, $product_ids = 0 ) {
    // When empty, return false
    if ( empty ( $product_ids ) ) return false;

    global $wpdb;
    
    $product_ids = is_array( $product_ids ) ? implode( ',', $product_ids ) : $product_ids;

    $line_meta_value = $product_ids != 0 ? 'AND woim.meta_value IN (' . $product_ids . ')' : 'AND woim.meta_value != 0';

    // Count the number of products
    $count = $wpdb->get_var( "
        SELECT COUNT(p.ID) FROM {$wpdb->prefix}posts AS p
        INNER JOIN {$wpdb->prefix}postmeta AS pm ON p.ID = pm.post_id
        INNER JOIN {$wpdb->prefix}woocommerce_order_items AS woi ON p.ID = woi.order_id
        INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS woim ON woi.order_item_id = woim.order_item_id
        WHERE p.post_status IN ( 'wc-processing' )
        AND pm.meta_key = '_customer_user'
        AND pm.meta_value = '$user_id'
        AND woim.meta_key IN ( '_product_id', '_variation_id' ) $line_meta_value 
    " );

    // Return true if count is higher than 0 (or false)
    return $count > 0 ? true : false;
}
 
function filter_woocommerce_checkout_cart_item_quantity( $item_qty, $cart_item, $cart_item_key ) {
    // Customer must be logged in
    if ( ! is_user_logged_in() ) return;
    
    // Get current user
    $user = wp_get_current_user();
    
    // Allowed user roles
    $allowed_roles = array( 'administrator', 'customer' );
    
    // Initialize
    $message = '';
    
    // Compare
    if ( array_intersect( $allowed_roles, $user->roles ) ) {
        // Get product id
        $product_id = $cart_item['variation_id'] > 0 ? $cart_item['variation_id'] : $cart_item['product_id'];
        
        // Call function, and if true
        if ( has_bought_items( $user->ID, $product_id ) ) {
            $message = '<p>' . __( 'You purchased this in the past. Buy again?', 'woocommerce' ) . '</p>';
        }
    }

    // Return
    return $item_qty . $message;
}
add_filter( 'woocommerce_checkout_cart_item_quantity', 'filter_woocommerce_checkout_cart_item_quantity', 10, 3 );

Result: show separately by product

enter image description here


Note: the has_bought_items() function is based on Check if a user has purchased specific products in WooCommerce answer code

Related: Display message below product name on WooCommerce cart page if user has bought product before

CodePudding user response:

according to this article:

you can implement such a login as below :

$customer_orders = get_posts( array(
    'numberposts' => -1,
    'meta_key'    => '_customer_user',
    'meta_value'  =>  $user->ID,
    'post_type'   => wc_get_order_types(),
    'post_status' => array_keys( wc_get_is_paid_statuses() ),
) );

// LOOP THROUGH ORDERS AND GET PRODUCT IDS
if ( ! $customer_orders ) return;

$product_ids = array();
foreach($items as $item) { 
   foreach ( $customer_orders as $customer_order ) {
       $order = wc_get_order( $customer_order->ID );
       $orderItems = $order->get_items();
       foreach ( $orderItems as $orderItem ) {
          if ($orderItem->get_product_id() == $item->get_product_id() )
             $has_bought = true;
             break;
       }
   }
} 

CodePudding user response:

Regarding 3rd point you can get the customer processing orders easily using wc_get_orders()

$user              = wp_get_current_user();
$processing_orders = wc_get_orders(
    array(
       'customer' => $user->ID,
       'status'   => 'wc-processing',
    )
);

You can check if the processing orders are empty or not. and you can loop over the orders products to get details about each product.

foreach ( $processing_orders as $p_order ) {
   $order_products = $p_order->get_items();
   foreach ( $order_products as $product_item ) {
      $product_id = $product_item->get_id();
   }
}
  • Related