I'm trying to list the total amount of product sold at the top of each category page.
A portion of this total will be donated and my client wants to advertise the amount. I have been looking and trying things for hours now and have not had any luck. I found a plugin that displays total sales for the whole store, but I want just one category.
I tried adding another filter to this plugin, but no luck. Any thoughts?
function getSaleAmountbyCategoryID($product_cat_id)
{
//first getting all the Product ID by Category ID
$pro_args = [
'post_type' => 'product',
'pages_per_post' => -1,
'post_status' => 'publish',
'fields' => 'ids',
'tax_query' => [
[
'taxonomy' => 'product_cat',
'field' => 'term_id', //This is optional, as it defaults to 'term_id'
'terms' => $product_cat_id, //(int)
]
]
];
$product_ids_query = new WP_Query($pro_args);
$include_product_id = $product_ids_query->posts;
//getting all the success orders
$args = [
'post_type' => 'shop_order',
'posts_per_page' => '-1',
'post_status' => ['wc-processing', 'wc-completed', 'wc-onhold']
];
$my_query = new WP_Query($args);
$total = 0;
$orders = $my_query->posts;
foreach ($orders as $ctr => $value)
{
$order_id = $value->ID;
//getting order object
$order = wc_get_order($order_id);
$items = $order->get_items();
foreach ($items as $item_data)
{
$product_id = $item_data['item_meta']['_product_id'][0];
if (in_array($product_id, $include_product_id))
{
//getting product object
//$_product = wc_get_product($product_id);
//$qty = $item_data['item_meta']['_qty'][0];
$pro_price = $item_data['item_meta']['_line_total'][0];
$total += $pro_price;
}
}
}
return $total;
}
Add the ^^above code to your active theme functions.php
USAGE
In your product category page template call it like
echo getSaleAmountbyCategoryID(21); //replace it by your product caregory ID
Please Note: I won't say this is a best solution as it will be slow if you have 1000s of order. If I find out the better solution I'll update my answer.
Hope this helps!
Related
I'm writing some code to modify the related products section as follows:
If a product has cross sell products, show those first, and fill up to 4 total products with others from the same category*
Or
If a product has no cross sell products, show 4 products from the same category*
Here's my function to filter the related products so far:
add_filter( 'woocommerce_related_products', 'fivem_add_linked_to_related_products', 9999, 3 );
function fivem_add_linked_to_related_products( $related_posts, $product_id, $args ) {
$product = wc_get_product( $product_id );
$cross_sell_ids = $product->get_cross_sell_ids();
$product_categories = $product->get_category_ids();
// Get cross sell products
$cross_sell_products = get_posts( array(
'post_type' => 'product',
'post_status' => 'publish',
'fields' => 'ids',
'post__in' => $cross_sell_ids,
'posts_per_page' => 4,
'exclude' => array( $product_id ),
));
// Calculate how many filler products are needed
$category_product_count = 4 - count( $cross_sell_products );
// Exclude main product and cross sell products
$excluded_products = array_push( $cross_sell_ids, $product_id );
// Get filler products from same category
$category_products = get_posts( array(
'post_type' => 'product',
'post_status' => 'publish',
'orderby' => 'rand',
'fields' => 'ids',
'post__not_in' => $excluded_products,
'posts_per_page' => $category_product_count,
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $product_categories,
'operator' => 'IN',
)
)
));
// Merge cross sell products with filler products
$related_products = array_merge( $cross_sell_products, $category_products );
// Return related products
return $related_products;
}
Currently, the above code mostly works.
If cross-sells are set, it only displays those cross-sell products- ie. does not fill out to 4 total
If no cross-sells are set, it displays products from the same category as expected.
There are two problems I'm trying to solve:
Code above doesn't fill with category products. If I remove the post__not_in and tax_query arguments, it fills out, but obviously not with products from the same category.
I want to show cross-sell products first, then the category-related products. There appears to be another randomization somewhere that mixes the order up, and I can't work out where that comes from.
Any ideas how I can fix this? Thanks in advance.
Code contains
If a product has cross sell products, show those first, and fill up to 4 total products with others from the same category
If a product has no cross sell products, show 4 products from the same category
function filter_woocommerce_related_products( $related_posts, $product_id, $args ) {
// Taxonomy
$taxonomy = 'product_cat';
// Show products
$show_products = 4;
// Get product
$product = wc_get_product( $product_id );
// Get cross sell IDs
$cross_sell_ids = $product->get_cross_sell_ids();
// Calculate how many filler products are needed
$category_product_needed_count = $show_products - count( $cross_sell_ids );
// If category product needed
if ( $category_product_needed_count >= 1 ) {
// Retrieves product term ids for a taxonomy.
$product_cats_ids = wc_get_product_term_ids( $product_id, $taxonomy );
// Get product id(s) from a certain category, by category-id
$product_ids_from_cats_ids = get_posts( array(
'post_type' => 'product',
'numberposts' => $category_product_needed_count,
'post_status' => 'publish',
'fields' => 'ids',
'tax_query' => array(
array(
'taxonomy' => $taxonomy,
'field' => 'id',
'terms' => $product_cats_ids,
'operator' => 'IN',
)
),
));
// Merge array
$related_posts = array_merge( $cross_sell_ids, $product_ids_from_cats_ids );
} else {
// Slice array until show products
$related_posts = array_slice( $cross_sell_ids, 0, $show_products );
}
// Return
return $related_posts;
}
add_filter( 'woocommerce_related_products', 'filter_woocommerce_related_products', 10, 3 );
// Order by
function filter_woocommerce_output_related_products_args( $args ) {
$args['orderby'] = 'id';
$args['order'] = 'ASC';
return $args;
}
add_filter( 'woocommerce_output_related_products_args', 'filter_woocommerce_output_related_products_args', 10, 1 );
I'm building a woocommerce website using storefront.
On each category page, I wish to display product ordered by tag.
Each product has only one tag.
TAG 1
product a
product b
TAG 2
product x
product y
I think I can retrieve all the data I need from the DB.
But I have no clue how to use them to display my products ordered by tags.
EDITED
// GET CATEGORY ID
$currentCategory = get_queried_object();
$catSlug = $currentCategory->slug;
// GET PRODCUTS FROM CURRENT CATEGORY
$args = array(
'post_type' => 'product',
'product_cat' => $catSlug,
'orderby' => 'rand'
);
$prodLoop = new WP_Query( $args );
while ( $prodLoop->have_posts() ){
$prodLoop->the_post();
global $product;
echo the_title();
echo the_ID();
echo '</br>';
}
// GET TAGS ID
$tag_args = array(
'taxonomy' => 'product_tag',
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => false,
);
$tag_query = new WP_Term_Query($tag_args);
foreach($tag_query->get_terms() as $term){
print_r($term->term_id);
}
//GET ALL PRODUCTS ID
$prod_args = new WC_Product_Query( array(
'limit' => 5,
'order' => 'ASC',
'return' => 'ids',
));
$products = $prod_args->get_products();
foreach($products as $prod){
print_r($prod);
}
I read many things, maybe I could you a SELECT xxx query, something like a one to many realtionship query, or an usort function, but I don't know where to do... I tried many things, but by now all I got is a headache and feeling hopeless...
I have a custom post type of products, and each product belongs to a product category. I am trying to query the products to get all products sorted alphabetically by their product category i.e. First: Product: Lion
Category: Animals
Last:
Product: Snowmobile
Category: Winter
I am using a custom field for the product category, but my query doesn't sort them alphabetically - but instead by which date they are published. The product_cat_meta field is a regular text field set up in custom fields. Query is here:
function get_products()
{
$args = array(
'post_type' => 'products',
'post_status' => 'publish',
'meta_key' => 'product_cat_meta',
'orderby' => 'meta_value',
'order' => 'ASC',
'posts_per_page' => -1
);
$products = new WP_Query($args);
if ($products->have_posts()) {
$index = 0;
while ($products->have_posts()) {
$products->the_post();
$prod_meta = get_field('product_cat_meta');
echo $prod_meta;
);
$index++;
} // end while
} // end if
}
The result of this query just returns the prod category in the way they are set up in wordpress – the latest posts first, but not sorted alphabetically
You can try to put the code in functions.php file.
The code, which can be dropped into your current theme’s functions.php if you like:
function get_products()
{
$args = array(
'post_type' => 'products',
'post_status' => 'publish',
'meta_key' => 'product_cat_meta',
'orderby' => 'title',
'order' => 'ASC',
'posts_per_page' => -1
);
$products = new WP_Query($args);
if ($products->have_posts()) {
$index = 0;
while ($products->have_posts()) {
$products->the_post();
$prod_meta = get_field('product_cat_meta');
echo $prod_meta;
);
$index++;
} // end while
} // end if
}
Get More details, follow the link: https://codex.wordpress.org/Alphabetizing_Posts
I have this plugin. It shows all products from woocommerce, but I want to show products from all Completed User Orders.
// Change product query settings here
$product_posts = get_posts( array(
'post_type' => 'product',
'post_status' => 'publish',
'numberposts' => -1,
) );
// Display product options
$values = array();
foreach ( $product_posts as $product ) {
$values[] = $product->post_title;
}
Suggestion?
Thank you!
I have the following code and I need to display order data based on seller id or seller name:
$filters = array(
'post_status' => 'published',
'post_type' => 'shop_order',
'posts_per_page' => 200,
'paged' => 1,
'orderby' => 'modified',
'order' => 'ASC',
'author' => $seller_id,
'post_parent' => $order_id
);
$loop = new WP_Query($filters);
while ($loop->have_posts()) {
$loop->the_post();
$order = new WC_Order($loop->post->ID);
foreach ($order->get_items() as $key => $item)
{
$red = $item['product_id'];
$_sku = get_post_meta( $red, '_sku', true );
}
}
The above loop is not showing any sku or price on the invoice section.
How to display order details on author ID (or seller name)?
Thanks
Your main problem is the post_status here: For WooCommerce Orders "published" post_status doesn't exist. The available status for WooCommerce Orders are for example:
'wc-cancelled'
'wc-completed'
'wc-custom-status'
'wc-on-hold'
'wc-pending'
'wc-processing'
'wc-refunded'
You can have different order statuses in an array…
Also 'post_parent' is can't be the order ID as it always have a 0 value
To finish since WooCommerce 3+ Order items are now a WC_Order_Item_Product object (and you need to use available methods to access the properties values).
Last thing, to get the user ID from the user name, you can use WordPress function get_user_by().
So your code will be:
$args = array(
'post_status' => array( 'wc-completed' ), // <=== HERE
'post_type' => 'shop_order',
'posts_per_page' => 200,
'paged' => 1,
'orderby' => 'modified',
'author' => $seller_id
);
$loop = new WP_Query($args);
while ($loop->have_posts()) {
$loop->the_post();
$order_obj = wc_get_order($loop->post->ID);
foreach ($order_obj->get_items() as $item_id => $item_obj)
{
$item_data = $item_obj->get_data(); // Accessing WC_Order_Item_Product object protected data
$product_id = $item_data['product_id']; // Product ID
$product_sku = get_post_meta( $product_id, '_sku', true ); // SKU
// Just for Testing output
echo "Product ID is $product_id - Sku is $product_sku<br>";
}
}
This code is tested and works for WooCommerce 3+
Helpful Answer: How to get WooCommerce order details