I'm trying to get the price of all products on hold (i.e user has placed order but haven't made a payment) by a user in woocommerce.
I have the following code which detects all products on-hold orders by a user
function get_user_on_hold_product_price() {
global $product, $woocommerce;
// GET USER
$current_user = wp_get_current_user();
// GET USER ON-HOLD ORDERS
$customer_orders = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => $current_user->ID,
'post_type' => 'shop_order',
'post_status' => 'wc-on-hold',
) );
I'm not sure what to do from here to get only the total price of all on-hold orders by the user.
Adding/hooking this function to a shortcode, like this;
add_shortcode('get_on-hold_price', 'get_user_on_hold_product_price')
Thanks
To get the total amount of customer "on-hold" orders using a WC_Order_Query for improved usability and compatibility:
add_shortcode('user_on_hold_total', 'get_user_orders_on_hold_total');
function get_user_orders_on_hold_total() {
$total_amount = 0; // Initializing
// Get current user
if( $user = wp_get_current_user() ){
// Get 'on-hold' customer ORDERS
$on_hold_orders = wc_get_orders( array(
'limit' => -1,
'customer_id' => $user->ID,
'status' => 'on-hold',
) );
foreach( $on_hold_orders as $order) {
$total_amount += $order->get_total();
}
}
return $total_amount;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
To get a formatted total amount replace return $total_amount; by return wc_price($total_amount);
Shortcode usage: [user_on_hold_total]
Related documentation: Woocommerce wc_get_orders() and WC_Order_Query
Related
I want to display the total number of purchases made on my site to my site users; Previously, I wrote the code that displayed the total number of products published on my site, and now I want the code to display the total number of successful purchases from my site to the user.
The code I wrote to display the number of products on my site is as follows:
function product_count_shortcode() {
$count_posts = wp_count_posts( 'product' );
return $count_posts->publish;
}
add_shortcode( 'product_counthalsho', 'product_count_shortcode' );
You will basically have to show the number of orders that have the status completed. Just create a function that will query the order post_type and with the status completed.
You can simply use get_posts and use the php function count the check how many results you have, or use WP_Query that already has a property in the return object that tells you how many orders you have with that status.
Later Edit:
function mrc_total_completed_orders() {
$args = array(
'post_type' => 'order',
'posts_per_page' => -1,
'post_status' => 'completed',
);
$orders = get_posts( $args );
return count( $orders ); }
Or you can use the WC_Order_Query
function mrc_mrc_total_completed_Orders() {
$query = new WC_Order_Query( array(
'limit' => 99999,
'status' => array( 'completed' ),
'return' => 'ids',
) );
$orders = $query->get_orders();
return count( $orders ); }
Also some documentation here
Note that I haven't tested these solutions, but its enough to get you started :)
Usage:
echo mrc_mrc_total_completed_Orders();
I am currently developing a WordPress project and I am using WooCommerce with WooCommerce Subscriptions plugin to offer subscriptions to my users. I need help on how to get the quantity of a subscription in PHP.
I am using this code to get subscription but I can not retrieve quantity:
$subscriptions = wcs_get_subscriptions( array(
'customer_id' => get_current_user_id(),
'subscription_status' => 'wc-active',
'order_by' => 'DESC',
'subscriptions_per_page' => - 1
) );
When a user purchases a subscription, the user can select the quantity of subscriptions. So I need to get the value of this field:
Your code is correct and wcs_get_subscriptions() is the right and best way to get customer active subscriptions.
But you have missed a something after your code to get the customer subscription item quantity (code commented):
// Get current customer active subscriptions
$subscriptions = wcs_get_subscriptions( array(
'customer_id' => get_current_user_id(),
'subscription_status' => 'wc-active',
'order_by' => 'DESC',
'subscriptions_per_page' => - 1
) );
if ( count( $subscriptions ) > 0 ) {
// Loop through customer subscriptions
foreach ( $subscriptions as $subscription ) {
// Get the initial WC_Order object instance from the subscription
$order = wc_get_order( $subscription->get_parent_id() );
// Loop through order items
foreach ( $order->get_items() as $item ) {
$product = $item->get_product(); // Get the product object instance
// Target only subscriptions products type
if( in_array( $product->get_type(), ['subscription', 'subscription_variation'] ) ) {
$quantity = $item->get_quantity(); // Get the quantity
echo '<p>Quantity: ' . $quantity . '</p>';
}
}
}
}
Tested and works.
Here is my working code try this
$current_user_id = get_current_user_id();
$customer_subscriptions = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(), // Or $user_id
'post_type' => 'shop_subscription', // WC orders post type
'post_status' => 'wc-active' // Only orders with status "completed"
) );
And if you want get all post_status subscription then use this
$customer_subscriptions_for_other_cases = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(), // Or $user_id
'post_type' => 'shop_subscription', // WC orders post type
'post_status' => array('wc-on-hold','wc-pending-cancel','wc-active') // Only orders with status "completed"
) );
Thanks
I have an issue with my Woocommerce products. This issue is fixed if I just update the product (edit the product and click in the Update button) with no changes at all.
I have around 2000 products in my site, then I am thinking of doing this using a function in my function.php file.
It should be something like this, I just need the line which update the product.
function update_all_products(){
// getting all products
$products = get_posts( $args );
// Going through all products
foreach ( $products as $key => $value ) {
// the product ID
$product_id = $value->ID;
// update product
update_post_meta...(NEED HELP HERE)...
} //..end foreach
}
// fire the function
update_all_products();
Try the following, that will update your products by 200 each time to avoid problems
(if you have variable products also, the post_type arg will need to be product & product_variation):
add_action( 'woocommerce_loaded', 'update_products_by_x' );
function update_products_by_x(){
$limit = 200;
// getting all products
$products_ids = get_posts( array(
'post_type' => 'product', // or ['product','product_variation'],
'numberposts' => $limit,
'post_status' => 'publish',
'fields' => 'ids',
'meta_query' => array( array(
'key' => '_sync_updated',
'compare' => 'NOT EXISTS',
) )
) );
// Loop through product Ids
foreach ( $products_ids as $product_id ) {
// Get the WC_Product object
$product = wc_get_product($product_id);
// Mark product as updated
$product->update_meta_data( '_sync_updated', true );
$product->save();
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Each time you will browse a page of your site the function will be triggered. processing products by 200 is just more secure and will avoid a timeout or errors.
You can increase that number to 500 for example, setting the $limit to 500
How can I iterate through all current active woo subscriptions and print the user ID of the user who published the product related to each active subscription (PHP)? I think something like this will give just the subscriptions:
$args = array( 'subscriptions_per_page' => -1, 'post_type' => 'shop_subscription', // WC orders post type
'post_status' => 'wc-active' );
$subscriptions = wcs_get_subscriptions( $args );
The following code will query all active subscriptions to get the author Id (that published the product of the active subscription):
// Get all active subscriptions
$subscriptions = wcs_get_subscriptions( array(
'subscriptions_per_page' => -1,
'subscription_status' => array('active') // Active subscriptions
) );
// 1) Loop through quieried active subscriptions
foreach($subscriptions as $subscription)
{
// 2) Loop through subscription items
foreach( $subscription->get_items() as $item_id => $item )
{
// Get the subscription product author
$author_id = get_post_field ('post_author', $item->get_product_id());
// Display
echo $author_id . '<br>';
}
}
Tested and works.
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.