I have a product loop in Woocommerce. If a customer has purchased a product before, I would like to replace the purchase product button with a message and the date of the order. For example.
"You purchased this product on Jan. 15, 2016"
I can get the product id and I can get the current user id, but can't figure out how to use those pieces of info to pull order ids.
$postid = get_the_ID();
$current_user = wp_get_current_user();
$has_product = wc_customer_bought_product( $current_user->user_email, $current_user->ID, $product->id);
Ideas?
You can use this function below
function _cmk_check_ordered_product( $id ) {
// Get All order of current user
$orders = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(),
'post_type' => wc_get_order_types( 'view-orders' ),
'post_status' => array_keys( wc_get_order_statuses() )
) );
if ( !$orders ) return false; // return if no order found
$all_ordered_product = array(); // store products ordered in an array
foreach ( $orders as $order => $data ) { // Loop through each order
$order_data = new WC_Order( $data->ID ); // create new object for each order
foreach ( $order_data->get_items() as $key => $item ) { // loop through each order item
// store in array with product ID as key and order date a value
$all_ordered_product[ $item['product_id'] ] = $data->post_date;
}
}
if ( isset( $all_ordered_product[ $id ] ) ) { // check if defined ID is found in array
return 'You purchased this product on '. date('M. d, Y', strtotime( $all_ordered_product[ $id ] ) );
} else {
return 'Product Never Purchased';
}
}
e.g.
Showing message on single product page echo _cmk_check_ordered_product( get_the_ID() );
Related
I would like to obtain the data of the products of the last purchase or the most recent purchase of the client.
Currently I have this but the results of the array give me those of a random purchase, it does not even give me the data of a completed purchase. It gives me the details of a purchase that is on hold, I need a little help here.
Here is the code:
// Get the current user Object
$current_user = wp_get_current_user();
// Check if the user is valid
if (0 == $current_user->ID) return;
//Create $args array
$args = array(
'numberposts' => 1,
'meta_key' => '_customer_user',
'meta_value' => $current_user->ID,
'orderby' => 'date',
'order' => 'DESC',
'post_type' => wc_get_order_types(),
'post_status' => array_keys(wc_get_is_paid_statuses()),
);
// Pass the $args to get_posts() function
$customer_orders = get_posts($args);
// loop through the orders and return the IDs
if (!$customer_orders) return;
$product_ids = array();
foreach ($customer_orders as $customer_order) {
$order = wc_get_order($customer_order->ID);
$items = $order->get_items();
foreach ($items as $item) {
$product_id = $item->get_product_id();
$product_ids[] = $product_id;
}
}
echo '<pre>';
var_dump($product_ids);
echo '</pre>';
You can use wc_get_customer_last_order( $user_id ) to get info about customer’s last order.
So you get:
// For logged in users only
if ( is_user_logged_in() ) {
// The current user ID
$user_id = get_current_user_id();
// Get the last WC_Order Object instance from current customer
$last_order = wc_get_customer_last_order( $user_id );
// NOT empty
if ( ! empty( $last_order ) ) {
// Initalize
$product_ids = array();
// Loop
foreach ( $last_order->get_items() as $item ) {
// Get product ID
$product_id = $item->get_product_id();
$product_ids[] = $product_id;
}
echo '<pre>';
var_dump( $product_ids );
echo '</pre>';
}
}
Related: How to display the last ordered product in WooCommerce via a shortcode
I want to display the order table found in woocommerce my-account recent orders for a specific product id on a separate page. To be more precise, display all recent orders for current user if the order has a product with the product_id of X.
I am trying to use these references:
Woocommerce - How to show Order details (my-account) on a separate page
Get all Orders IDs from a product ID in Woocommerce
Woocommerce: Get all orders for a product
But I am not able to relate $product_id to $user_id = get_current_user_id(); so that all the orders of the current user for a particular product id can be displayed on a separate page.
Edit: added code. I tried this code but its not working.
function orders_from_product_id( $product_id ) {
$order_statuses = array('wc-on-hold', 'wc-processing', 'wc-completed');
$customer_user_id = get_current_user_id(); // current user ID here for example
$customer_orders = wc_get_orders( array(
'meta_key' => '_customer_user',
'meta_value' => $customer_user_id,
'post_status' => $order_statuses,
'numberposts' => -1
) );
foreach($customer_orders as $order ){
$order_id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id;
foreach($order->get_items() as $item_id => $item){
$product_id = method_exists( $item, 'get_product_id' ) ? $item->get_product_id() : $item['product_id'];
if ( $product_id == 326 ) {
ob_start();
wc_get_template( 'myaccount/my-orders.php', array(
'current_user' => get_user_by( 'id', $user_id),
'order_count' => $order_count
) );
return ob_get_clean();
} else {
echo '<p> You donot have any orders.</p>';
}
}
}
}
add_shortcode('woocommerce_orders', 'orders_from_product_id');
From this code you to get the Current user-product id which product purchased by the user.
// GET CURR USER
$current_user = wp_get_current_user();
if ( 0 == $current_user->ID ) return;
// GET USER ORDERS (COMPLETED + PROCESSING)
$customer_orders = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => $current_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 ( $customer_orders as $customer_order ) {
$order = wc_get_order( $customer_order->ID );
$items = $order->get_items();
foreach ( $items as $item ) {
$product_id = $item->get_product_id();
$product_ids[] = $product_id;
}
}
$product_ids = array_unique( $product_ids );
I'm trying to implement a feature where customers receive a new user role after a certain amount of orders have been made, but all those orders must have been made within the same year.
I was able to assign the user role based on nth number of orders but can't seem to go beyond to where the date needs to be taken into consideration, can someone point me in the right direction or point out what I might be missing.
This is what I have tried so far.
function change_user_role_on_order_status_completed( $order_id ) {
$order = new WC_Order( $order_id );
$user_id = $order->user_id;
$order_this_year = false;
$current_date = date('Y');
$total_orders = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => $user_id,
'post_type' => 'shop_order',
) );
if ( $total_orders > 1 ) {
foreach ($order->get_items() as $item_key => $item_values):
// Get the item date
if ($item_date = $item_values->get_date_completed()->format ('Y') == $current_date) {
$order_this_year = true;
}
endforeach;
if ($order_this_year) {
$user = new WP_User( $order->user_id );
// Set role editor
$user->set_role( 'customer_club' );
}
}
}
add_action( 'woocommerce_order_status_completed', 'change_user_role_on_order_status_completed', 10, 1 );
Using WC_Order_Query here is a much lighter and simple way to change the user role based on yearly orders count:
add_action( 'woocommerce_order_status_completed', 'change_user_role_on_order_status_completed', 10, 2 );
function change_user_role_on_order_status_completed( $order_id, $order ) {
// Here set the minimal order count
$min_orders_count = 3;
// The WC_Order_Query
$queried_orders = wc_get_orders( array(
'limit' => -1,
'customer_id' => $order->get_customer_id(),
'date_paid' => '>=' . date('Y') . '-01-01', // or 'date_created'
'return' => 'ids'
) );
if ( sizeof($queried_orders) >= $min_orders_count ) {
// Get an instance of the customer WP_User Object
$user = $order->get_user();
// Change the user role
$user->set_role( 'customer_club' );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
In my Woocommerce website, I have a maximum order capacity of 50.
I am trying to communicate to the customer in their cart of the orders left before we close the ordering.
I need to get the total number of items already processing in each order + new orders in cart subtracted from the 50 maximum.
I have try it using this code:
function display_woocommerce_order_count() {
global $woocommerce;
$args = array(
'post_type' => 'shop_order',
'post_status' => 'publish',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'shop_order_status',
'field' => 'slug',
'terms' => array('processing')
)
)
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
$order_id = $loop->post->ID;
$order = new WC_Order($order_id);
$order_count = 0;
foreach( $order as $product ) {
$order_item = $product['qty'];
if($qty) {
$order_count += $order_item;
}
}
ob_start();
//Echo the number of items in cart.
$count = $woocommerce->cart->cart_contents_count;
//Difference max - orders processing - cart items
$total_diff = 50 - number_format($order_count) - $count;
echo $total_diff;
return ob_get_clean();
}
How can I make this works as expected?
Thanks
To get your remaining order calculation from existing customer "processing" orders items and actual cart items, you can try this custom function (with an optional $user_id argument).
This is the code:
function get_remaining_orders( $user_id = null ){
if( empty($user_id) && is_user_logged_in() )
$user_id = get_current_user_id();
if( ! empty($user_id) && ! is_admin() ){
$order_max = 50;
$processing_orders_items_count = 0;
$cart_count = 0;
$customer_orders = get_posts( array(
'meta_key' => '_customer_user',
'meta_value' => $user_id,
'post_type' => 'shop_order',
'numberposts' => -1,
'post_status' => 'wc-processing' // 'processing' order status only
) );
if(!empty($customer_orders))
foreach($customer_orders as $customer_order_values){
$customer_order = wc_get_order( $customer_order_values->ID );
$processing_orders_items_count += $customer_order->get_item_count('line_item');
}
if(!WC()->cart->is_empty())
$cart_count = WC()->cart->get_cart_contents_count( );
$ouput = $order_max - ($processing_orders_items_count + $cart_count);
return $ouput;
}
}
// USAGE: for a specific user ID (here for example $user_id is 22):
get_remaining_orders( 22 );
// USAGE: returning the value in a variable for current user:
$remaining_orders = get_remaining_orders();
// USAGE: displaying the value for current user (example):
echo 'Total remaining orders are ' . get_remaining_orders();
Code goes in function.php file of your active child theme (or theme). Or also in any plugin php files.
This code is tested and functional.
Update for a "not user specific case":
function get_remaining_orders(){
if( !is_admin() ){
$order_max = 50;
$processing_orders_items_count = 0;
$cart_count = 0;
$customer_orders = get_posts( array(
'post_type' => 'shop_order',
'numberposts' => -1,
'post_status' => 'wc-processing' // 'processing' order status only
) );
if(!empty($customer_orders))
foreach($customer_orders as $customer_order_values){
$customer_order = wc_get_order( $customer_order_values->ID );
$processing_orders_items_count += $customer_order->get_item_count('line_item');
}
if(!WC()->cart->is_empty())
$cart_count = WC()->cart->get_cart_contents_count( );
$ouput = $order_max - ($processing_orders_items_count + $cart_count);
return $ouput;
}
}
// USAGE: returning the value in a variable:
$remaining_orders = get_remaining_orders();
// USAGE: displaying the value (example):
echo 'Total remaining orders are ' . get_remaining_orders();
This should work as you expect…
In woocommerce how to check how many times a product has been bought by a customer across all order.
How can I check that how many times a product can bought by a customer across all order he made.
Example product buy history by current customer:
Product one = bought 5 times
Product five = bought 1 times
Product four = bought 2 times
Product two = bought 3 times
Product three = bought 6 times
I have a function to check if those product bought by a customer or not
function is_bought_items() {
$bought = false;
$_options = get_option( 'license_page_option_name' );
$ex_product_ids = $_options['ex_product_ids_warranty'];
$targeted_products= explode(",",$ex_product_ids); //id array(4,17,28,52)
// Get all customer orders
$customer_orders = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(),
'post_type' => 'shop_order', // WC orders post type
'post_status' => 'wc-completed' // Only orders with status "completed"
) );
// Going through each current customer orders
foreach ( $customer_orders as $customer_order ) {
$order = wc_get_order( $customer_order );
$order_id = $order->id;
$items = $order->get_items();
// Going through each current customer products bought in the order
foreach ($items as $item) {
// Your condition related to your 2 specific products Ids
if ( in_array( $item['product_id'], $targeted_products) ) {
$bought = true; //
}
}
}
// return "true" if one the specifics products have been bought before by customer
if ( $bought ) {
return true;
}
}
While looping through all the items... we can save product purchase count in our array from $item['item_meta']['_qty'].
Here is an example of possible implementation...
function get_purchased_products() {
$products = array();
// Get all customer orders
$customer_orders = get_posts( array(
'numberposts' => - 1,
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(),
'post_type' => 'shop_order', // WC orders post type
'post_status' => 'wc-completed' // Only orders with status "completed"
) );
// Going through each current customer orders
foreach ( $customer_orders as $customer_order ) {
$order = wc_get_order( $customer_order );
$items = $order->get_items();
// Going through each current customer products bought in the order
foreach ( $items as $item ) {
$id = $item['product_id'];
// If product not in array, add it
if ( ! array_key_exists( $item['product_id'], $products ) ) {
$products[ $id ] = array(
'name' => $item['name'],
'count' => 0,
);
}
// Increment Product `count` from cart quantity
$products[ $id ]['count'] += $item['item_meta']['_qty'][0];
}
}
return $products;
}
foreach ( get_purchased_products() as $id => $product ) {
echo "<p>$id <b>$product[name]</b> bought $product[count] times</p>";
}
This outputs...
70 Flying Ninja bought 7 times
37 Happy Ninja bought 5 times
19 Premium Quality bought 1 times
Please follow the following github link https://github.com/woocommerce/woocommerce/blob/master/includes/wc-user-functions.php#L227-L238
The MySQL query below will provide what you need:
$result = $wpdb->get_col( "
SELECT im.meta_value FROM {$wpdb->posts} AS p
INNER JOIN {$wpdb->postmeta} AS pm ON p.ID = pm.post_id
INNER JOIN {$wpdb->prefix}woocommerce_order_items AS i ON p.ID = i.order_id
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS im ON i.order_item_id = im.order_item_id
WHERE p.post_status IN ( 'wc-completed', 'wc-processing' )
AND pm.meta_key IN ( '_billing_email', '_customer_user' )
AND im.meta_key IN ( '_product_id', '_variation_id' )
AND im.meta_value != 0
AND pm.meta_value IN ( '" . implode( "','", $customer_data ) . "' )
" );
Try this:
$count = get_post_meta('Product Id','total_sales', true);