Menu Close

WooCommerce: Get Total Sales By Product Category

default

It’s easy enough in WooCommerce to get/calculate product sales. What’s difficult, on the other hand, is calculating the total amount of sales for a specific category, because there is no core function that already does that.

Why sales by category – you may ask? Well, to me, that’s a very important metric. For example, I sell both consulting and non-consulting products on this same website, so it’s important for me to keep track of category sales year-on-year, especially when my goal is reducing 1-to-1 client work while increasing scalable product sales such as courses, plugins and memberships.

In this quick tutorial, we will first get the “WooCommerce orders that contain a target product category”, and after that we will loop through the array to calculate the total sales for that specific category. Sounds difficult? No worries – just copy and paste the snippets below.

Pity that the product categories dashboard page doesn’t give you an idea of the total spent by category… let’s find a way to calculate that! You can then print the total where you wish: on the frontend single product category page in case that can help customers, or in the backend, for example in the single product category edit page!

PHP Snippet: Get Total Purchase Amount For a Specific WooCommerce Product Category

/**
 * @snippet       Calculate Product Category Sales Amount
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 7
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */

// 1. ORDERS GETTER

function bbloomer_get_orders_by_product_cat( $cat_slug, $order_status = array( 'wc-completed' ) ) {
    global $wpdb;
	 $args = array(
		 'limit' => -1,
	 	 'status' => 'publish',
		 'return' => 'ids',
		 'category' => array( $cat_slug ),
	 );
	 $product_ids = wc_get_products( $args );
    $results = $wpdb->get_col( "
        SELECT order_items.order_id
        FROM {$wpdb->prefix}woocommerce_order_items as order_items
        LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta as order_item_meta ON order_items.order_item_id = order_item_meta.order_item_id
        LEFT JOIN {$wpdb->posts} AS posts ON order_items.order_id = posts.ID
        WHERE posts.post_type = 'shop_order'
        AND posts.post_status IN ( '" . implode( "','", $order_status ) . "' )
        AND order_items.order_item_type = 'line_item'
        AND order_item_meta.meta_key = '_product_id'
        AND order_item_meta.meta_value IN ( '" . implode( "','", $product_ids ) . "' )
    " );
    return $results;
}

// 2. SALES CALCULATOR

function bbloomer_cat_sales( $cat_slug ) {
	$orders = bbloomer_get_orders_by_product_cat( $cat_slug );
	$total = 0;
	foreach ( $orders as $order_id ) {
		foreach ( wc_get_order( $order_id )->get_items() as $key => $item ) {
			$product_id = $item->get_product_id();
			if ( ! $product_id ) continue;
			if ( has_term( $cat_slug, 'product_cat', $product_id ) ) $total += $item->get_total();
		}
	}
   return wc_price( $total );
}

// 3. USAGE
// E.G. YOU COULD PLACE THIS IN THE BACKEND OF FRONTEND:

echo bbloomer_cat_sales( 'tables' );
View Source
Posted in WooCommerce Tips