Prepares a sparkline to show sales in the last X days.
/** * Renders the sales widget in the dashboard. * This method is an almost exact clone of global woocommerce_dashboard_status() * function, with the main difference being that the correct totals in base * currency are taken before being aggregated. Due to the lack of filters in * the original function, the whole code had to be duplicated. */ public function woocommerce_dashboard_status_widget() { global $wpdb; $wpdb->show_errors(); include_once $this->woocommerce_admin_path() . '/reports/class-wc-admin-report.php'; $reports = new \WC_Admin_Report(); // Get sales $sales = $wpdb->get_var("SELECT SUM( postmeta.meta_value ) FROM {$wpdb->posts} as posts\r\n\t\t\tLEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID=rel.object_ID\r\n\t\t\tLEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )\r\n\t\t\tLEFT JOIN {$wpdb->terms} AS term USING( term_id )\r\n\t\t\tLEFT JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id\r\n\t\t\tWHERE \tposts.post_type \t= 'shop_order'\r\n\t\t\tAND \tposts.post_status \t= 'publish'\r\n\t\t\tAND \ttax.taxonomy\t\t= 'shop_order_status'\r\n\t\t\tAND\t\tterm.slug\t\t\tIN ( 'completed', 'processing', 'on-hold' )\r\n\t\t\tAND \tpostmeta.meta_key = '_order_total_base_currency'\r\n\t\t\tAND \tposts.post_date >= '" . date('Y-m-01', current_time('timestamp')) . "'\r\n\t\t\tAND \tposts.post_date <= '" . date('Y-m-d H:i:s', current_time('timestamp')) . "'\r\n\t\t"); // Get top seller $top_seller = $wpdb->get_row("SELECT SUM( order_item_meta.meta_value ) as qty, order_item_meta_2.meta_value as product_id\r\n\t\t\tFROM {$wpdb->posts} as posts\r\n\t\t\tLEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID=rel.object_ID\r\n\t\t\tLEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )\r\n\t\t\tLEFT JOIN {$wpdb->terms} AS term USING( term_id )\r\n\t\t\tLEFT JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON posts.ID = order_id\r\n\t\t\tLEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta ON order_items.order_item_id = order_item_meta.order_item_id\r\n\t\t\tLEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta_2 ON order_items.order_item_id = order_item_meta_2.order_item_id\r\n\t\t\tWHERE \tposts.post_type \t= 'shop_order'\r\n\t\t\tAND \tposts.post_status \t= 'publish'\r\n\t\t\tAND \ttax.taxonomy\t\t= 'shop_order_status'\r\n\t\t\tAND\t\tterm.slug\t\t\tIN ( 'completed', 'processing', 'on-hold' )\r\n\t\t\tAND \torder_item_meta.meta_key = '_qty'\r\n\t\t\tAND \torder_item_meta_2.meta_key = '_product_id'\r\n\t\t\tAND \tposts.post_date >= '" . date('Y-m-01', current_time('timestamp')) . "'\r\n\t\t\tAND \tposts.post_date <= '" . date('Y-m-d H:i:s', current_time('timestamp')) . "'\r\n\t\t\tGROUP BY product_id\r\n\t\t\tORDER BY qty DESC\r\n\t\t\tLIMIT 1\r\n\t\t"); // Counts $on_hold_count = get_term_by('slug', 'on-hold', 'shop_order_status')->count; $processing_count = get_term_by('slug', 'processing', 'shop_order_status')->count; // Get products using a query - this is too advanced for get_posts :( $stock = absint(max(get_option('woocommerce_notify_low_stock_amount'), 1)); $nostock = absint(max(get_option('woocommerce_notify_no_stock_amount'), 0)); $query_from = "FROM {$wpdb->posts} as posts\r\n\t\t\tINNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id\r\n\t\t\tINNER JOIN {$wpdb->postmeta} AS postmeta2 ON posts.ID = postmeta2.post_id\r\n\t\t\tWHERE 1=1\r\n\t\t\t\tAND posts.post_type IN ('product', 'product_variation')\r\n\t\t\t\tAND posts.post_status = 'publish'\r\n\t\t\t\tAND (\r\n\t\t\t\t\tpostmeta.meta_key = '_stock' AND CAST(postmeta.meta_value AS SIGNED) <= '{$stock}' AND CAST(postmeta.meta_value AS SIGNED) > '{$nostock}' AND postmeta.meta_value != ''\r\n\t\t\t\t)\r\n\t\t\t\tAND (\r\n\t\t\t\t\t( postmeta2.meta_key = '_manage_stock' AND postmeta2.meta_value = 'yes' ) OR ( posts.post_type = 'product_variation' )\r\n\t\t\t\t)\r\n\t\t\t"; $lowinstock_count = absint($wpdb->get_var("SELECT COUNT( DISTINCT posts.ID ) {$query_from};")); $query_from = "FROM {$wpdb->posts} as posts\r\n\t\t\tINNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id\r\n\t\t\tINNER JOIN {$wpdb->postmeta} AS postmeta2 ON posts.ID = postmeta2.post_id\r\n\t\t\tWHERE 1=1\r\n\t\t\t\tAND posts.post_type IN ('product', 'product_variation')\r\n\t\t\t\tAND posts.post_status = 'publish'\r\n\t\t\t\tAND (\r\n\t\t\t\t\tpostmeta.meta_key = '_stock' AND CAST(postmeta.meta_value AS SIGNED) <= '{$stock}' AND postmeta.meta_value != ''\r\n\t\t\t\t)\r\n\t\t\t\tAND (\r\n\t\t\t\t\t( postmeta2.meta_key = '_manage_stock' AND postmeta2.meta_value = 'yes' ) OR ( posts.post_type = 'product_variation' )\r\n\t\t\t\t)\r\n\t\t\t"; $outofstock_count = absint($wpdb->get_var("SELECT COUNT( DISTINCT posts.ID ) {$query_from};")); ?> <ul class="wc_status_list"> <li class="sales-this-month"> <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=orders&range=month'); ?> "> <?php echo $reports->sales_sparkline('', max(7, date('d', current_time('timestamp')))); ?> <?php printf(__("<strong>%s</strong> sales this month", 'woocommerce'), wc_price($sales)); ?> </a> </li> <?php if ($top_seller && $top_seller->qty) { ?> <li class="best-seller-this-month"> <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=orders&report=sales_by_product&range=month&product_ids=' . $top_seller->product_id); ?> "> <?php echo $reports->sales_sparkline($top_seller->product_id, max(7, date('d', current_time('timestamp'))), 'count'); ?> <?php printf(__("%s top seller this month (sold %d)", 'woocommerce'), "<strong>" . get_the_title($top_seller->product_id) . "</strong>", $top_seller->qty); ?> </a> </li> <?php } ?> <li class="processing-orders"> <a href="<?php echo admin_url('edit.php?s&post_status=all&post_type=shop_order&shop_order_status=processing'); ?> "> <?php printf(_n("<strong>%s order</strong> awaiting processing", "<strong>%s orders</strong> awaiting processing", $processing_count, 'woocommerce'), $processing_count); ?> </a> </li> <li class="on-hold-orders"> <a href="<?php echo admin_url('edit.php?s&post_status=all&post_type=shop_order&shop_order_status=on-hold'); ?> "> <?php printf(_n("<strong>%s order</strong> on-hold", "<strong>%s orders</strong> on-hold", $on_hold_count, 'woocommerce'), $on_hold_count); ?> </a> </li> <li class="low-in-stock"> <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=stock&report=low_in_stock'); ?> "> <?php printf(_n("<strong>%s product</strong> low in stock", "<strong>%s products</strong> low in stock", $lowinstock_count, 'woocommerce'), $lowinstock_count); ?> </a> </li> <li class="out-of-stock"> <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=stock&report=out_of_stock'); ?> "> <?php printf(_n("<strong>%s product</strong> out of stock", "<strong>%s products</strong> out of stock", $outofstock_count, 'woocommerce'), $outofstock_count); ?> </a> </li> </ul> <?php }
/** * Show status widget */ public function status_widget() { global $wpdb; include_once 'reports/class-wc-admin-report.php'; $reports = new WC_Admin_Report(); // Sales $query = array(); $query['fields'] = "SELECT SUM( postmeta.meta_value ) FROM {$wpdb->posts} as posts"; $query['join'] = "INNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id LEFT JOIN {$wpdb->posts} AS parent ON posts.post_parent = parent.ID"; $query['where'] = "WHERE posts.post_type IN ( '" . implode("','", array_merge(wc_get_order_types('sales-reports'), array('shop_order_refund'))) . "' ) "; $query['where'] .= "AND posts.post_status IN ( 'wc-" . implode("','wc-", apply_filters('woocommerce_reports_order_statuses', array('completed', 'processing', 'on-hold'))) . "' ) "; $query['where'] .= "AND ( parent.post_status IN ( 'wc-" . implode("','wc-", apply_filters('woocommerce_reports_order_statuses', array('completed', 'processing', 'on-hold'))) . "' ) OR parent.ID IS NULL ) "; $query['where'] .= "AND postmeta.meta_key = '_order_total' "; $query['where'] .= "AND posts.post_date >= '" . date('Y-m-01', current_time('timestamp')) . "' "; $query['where'] .= "AND posts.post_date <= '" . date('Y-m-d H:i:s', current_time('timestamp')) . "' "; $sales = $wpdb->get_var(implode(' ', apply_filters('woocommerce_dashboard_status_widget_sales_query', $query))); // Get top seller $query = array(); $query['fields'] = "SELECT SUM( order_item_meta.meta_value ) as qty, order_item_meta_2.meta_value as product_id\n\t\t\tFROM {$wpdb->posts} as posts"; $query['join'] = "INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON posts.ID = order_id "; $query['join'] .= "INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta ON order_items.order_item_id = order_item_meta.order_item_id "; $query['join'] .= "INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta_2 ON order_items.order_item_id = order_item_meta_2.order_item_id "; $query['where'] = "WHERE posts.post_type IN ( '" . implode("','", wc_get_order_types('order-count')) . "' ) "; $query['where'] .= "AND posts.post_status IN ( 'wc-" . implode("','wc-", apply_filters('woocommerce_reports_order_statuses', array('completed', 'processing', 'on-hold'))) . "' ) "; $query['where'] .= "AND order_item_meta.meta_key = '_qty' "; $query['where'] .= "AND order_item_meta_2.meta_key = '_product_id' "; $query['where'] .= "AND posts.post_date >= '" . date('Y-m-01', current_time('timestamp')) . "' "; $query['where'] .= "AND posts.post_date <= '" . date('Y-m-d H:i:s', current_time('timestamp')) . "' "; $query['groupby'] = "GROUP BY product_id"; $query['orderby'] = "ORDER BY qty DESC"; $query['limits'] = "LIMIT 1"; $top_seller = $wpdb->get_row(implode(' ', apply_filters('woocommerce_dashboard_status_widget_top_seller_query', $query))); // Counts $on_hold_count = 0; $processing_count = 0; foreach (wc_get_order_types('order-count') as $type) { $counts = (array) wp_count_posts($type); $on_hold_count += isset($counts['wc-on-hold']) ? $counts['wc-on-hold'] : 0; $processing_count += isset($counts['wc-processing']) ? $counts['wc-processing'] : 0; } // Get products using a query - this is too advanced for get_posts :( $stock = absint(max(get_option('woocommerce_notify_low_stock_amount'), 1)); $nostock = absint(max(get_option('woocommerce_notify_no_stock_amount'), 0)); $transient_name = 'wc_low_stock_count'; if (false === ($lowinstock_count = get_transient($transient_name))) { $query_from = apply_filters('woocommerce_report_low_in_stock_query_from', "FROM {$wpdb->posts} as posts\n\t\t\t\tINNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id\n\t\t\t\tINNER JOIN {$wpdb->postmeta} AS postmeta2 ON posts.ID = postmeta2.post_id\n\t\t\t\tWHERE 1=1\n\t\t\t\tAND posts.post_type IN ( 'product', 'product_variation' )\n\t\t\t\tAND posts.post_status = 'publish'\n\t\t\t\tAND postmeta2.meta_key = '_manage_stock' AND postmeta2.meta_value = 'yes'\n\t\t\t\tAND postmeta.meta_key = '_stock' AND CAST(postmeta.meta_value AS SIGNED) <= '{$stock}'\n\t\t\t\tAND postmeta.meta_key = '_stock' AND CAST(postmeta.meta_value AS SIGNED) > '{$nostock}'\n\t\t\t"); $lowinstock_count = absint($wpdb->get_var("SELECT COUNT( DISTINCT posts.ID ) {$query_from};")); set_transient($transient_name, $lowinstock_count, DAY_IN_SECONDS * 30); } $transient_name = 'wc_outofstock_count'; if (false === ($outofstock_count = get_transient($transient_name))) { $query_from = apply_filters('woocommerce_report_out_of_stock_query_from', "FROM {$wpdb->posts} as posts\n\t\t\t\tINNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id\n\t\t\t\tINNER JOIN {$wpdb->postmeta} AS postmeta2 ON posts.ID = postmeta2.post_id\n\t\t\t\tWHERE 1=1\n\t\t\t\tAND posts.post_type IN ( 'product', 'product_variation' )\n\t\t\t\tAND posts.post_status = 'publish'\n\t\t\t\tAND postmeta2.meta_key = '_manage_stock' AND postmeta2.meta_value = 'yes'\n\t\t\t\tAND postmeta.meta_key = '_stock' AND CAST(postmeta.meta_value AS SIGNED) <= '{$nostock}'\n\t\t\t"); $outofstock_count = absint($wpdb->get_var("SELECT COUNT( DISTINCT posts.ID ) {$query_from};")); set_transient($transient_name, $outofstock_count, DAY_IN_SECONDS * 30); } ?> <ul class="wc_status_list"> <li class="sales-this-month"> <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=orders&range=month'); ?> "> <?php echo $reports->sales_sparkline('', max(7, date('d', current_time('timestamp')))); ?> <?php printf(__("<strong>%s</strong> sales this month", 'woocommerce'), wc_price($sales)); ?> </a> </li> <?php if ($top_seller && $top_seller->qty) { ?> <li class="best-seller-this-month"> <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=orders&report=sales_by_product&range=month&product_ids=' . $top_seller->product_id); ?> "> <?php echo $reports->sales_sparkline($top_seller->product_id, max(7, date('d', current_time('timestamp'))), 'count'); ?> <?php printf(__("%s top seller this month (sold %d)", 'woocommerce'), "<strong>" . get_the_title($top_seller->product_id) . "</strong>", $top_seller->qty); ?> </a> </li> <?php } ?> <li class="processing-orders"> <a href="<?php echo admin_url('edit.php?post_status=wc-processing&post_type=shop_order'); ?> "> <?php printf(_n("<strong>%s order</strong> awaiting processing", "<strong>%s orders</strong> awaiting processing", $processing_count, 'woocommerce'), $processing_count); ?> </a> </li> <li class="on-hold-orders"> <a href="<?php echo admin_url('edit.php?post_status=wc-on-hold&post_type=shop_order'); ?> "> <?php printf(_n("<strong>%s order</strong> on-hold", "<strong>%s orders</strong> on-hold", $on_hold_count, 'woocommerce'), $on_hold_count); ?> </a> </li> <li class="low-in-stock"> <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=stock&report=low_in_stock'); ?> "> <?php printf(_n("<strong>%s product</strong> low in stock", "<strong>%s products</strong> low in stock", $lowinstock_count, 'woocommerce'), $lowinstock_count); ?> </a> </li> <li class="out-of-stock"> <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=stock&report=out_of_stock'); ?> "> <?php printf(_n("<strong>%s product</strong> out of stock", "<strong>%s products</strong> out of stock", $outofstock_count, 'woocommerce'), $outofstock_count); ?> </a> </li> <?php do_action('woocommerce_after_dashboard_status_widget', $reports); ?> </ul> <?php }
/** * Show status widget. */ public function status_widget() { include_once dirname(__FILE__) . '/reports/class-wc-admin-report.php'; $reports = new WC_Admin_Report(); echo '<ul class="wc_status_list">'; if (current_user_can('view_woocommerce_reports') && ($report_data = $this->get_sales_report_data())) { ?> <li class="sales-this-month"> <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=orders&range=month'); ?> "> <?php echo $reports->sales_sparkline('', max(7, date('d', current_time('timestamp')))); ?> <?php printf(__('<strong>%s</strong> net sales this month', 'woocommerce'), wc_price($report_data->net_sales)); ?> </a> </li> <?php } if (current_user_can('view_woocommerce_reports') && ($top_seller = $this->get_top_seller()) && $top_seller->qty) { ?> <li class="best-seller-this-month"> <a href="<?php echo admin_url('admin.php?page=wc-reports&tab=orders&report=sales_by_product&range=month&product_ids=' . $top_seller->product_id); ?> "> <?php echo $reports->sales_sparkline($top_seller->product_id, max(7, date('d', current_time('timestamp'))), 'count'); ?> <?php printf(__('%s top seller this month (sold %d)', 'woocommerce'), '<strong>' . get_the_title($top_seller->product_id) . '</strong>', $top_seller->qty); ?> </a> </li> <?php } $this->status_widget_order_rows(); $this->status_widget_stock_rows(); do_action('woocommerce_after_dashboard_status_widget', $reports); echo '</ul>'; }