diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-products-stats-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-products-stats-data-store.php index 37714b3674b..44ec6bcb364 100644 --- a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-products-stats-data-store.php +++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-products-stats-data-store.php @@ -115,27 +115,29 @@ class WC_Admin_Reports_Products_Stats_Data_Store extends WC_Admin_Reports_Produc $intervals_query = array(); $this->update_sql_query_params( $query_args, $totals_query, $intervals_query ); - $db_records_count = (int) $wpdb->get_var( - "SELECT COUNT(*) FROM ( - SELECT - {$intervals_query['select_clause']} AS time_interval - FROM - {$table_name} - {$intervals_query['from_clause']} - WHERE - 1=1 - {$intervals_query['where_time_clause']} - {$intervals_query['where_clause']} - GROUP BY - time_interval - ) AS t" - ); // WPCS: cache ok, DB call ok, unprepared SQL ok. + $db_intervals = $wpdb->get_col( + "SELECT + {$intervals_query['select_clause']} AS time_interval + FROM + {$table_name} + {$intervals_query['from_clause']} + WHERE + 1=1 + {$intervals_query['where_time_clause']} + {$intervals_query['where_clause']} + GROUP BY + time_interval" + ); // WPCS: cache ok, DB call ok, , unprepared SQL ok. - $total_pages = (int) ceil( $db_records_count / $intervals_query['per_page'] ); + $db_interval_count = count( $db_intervals ); + $expected_interval_count = WC_Admin_Reports_Interval::intervals_between( $query_args['after'], $query_args['before'], $query_args['interval'] ); + $total_pages = (int) ceil( $expected_interval_count / $intervals_query['per_page'] ); if ( $query_args['page'] < 1 || $query_args['page'] > $total_pages ) { return array(); } + $this->update_intervals_sql_params( $intervals_query, $query_args, $db_interval_count, $expected_interval_count ); + $totals = $wpdb->get_results( "SELECT {$selections} @@ -183,21 +185,41 @@ class WC_Admin_Reports_Products_Stats_Data_Store extends WC_Admin_Reports_Produc $totals = (object) $this->cast_numbers( $totals[0] ); - $this->update_interval_boundary_dates( $query_args['after'], $query_args['before'], $query_args['interval'], $intervals ); - $this->create_interval_subtotals( $intervals ); - $data = (object) array( 'totals' => $totals, 'intervals' => $intervals, - 'total' => $db_records_count, + 'total' => $expected_interval_count, 'pages' => $total_pages, 'page_no' => (int) $query_args['page'], ); + if ( WC_Admin_Reports_Interval::intervals_missing( $expected_interval_count, $db_interval_count, $intervals_query['per_page'], $query_args['page'], $query_args['order'], $query_args['orderby'], count( $intervals ) ) ) { + $this->fill_in_missing_intervals( $db_intervals, $query_args['adj_after'], $query_args['adj_before'], $query_args['interval'], $data ); + $this->sort_intervals( $data, $query_args['orderby'], $query_args['order'] ); + $this->remove_extra_records( $data, $query_args['page'], $intervals_query['per_page'], $db_interval_count, $expected_interval_count, $query_args['orderby'] ); + } else { + $this->update_interval_boundary_dates( $query_args['after'], $query_args['before'], $query_args['interval'], $data->intervals ); + } + $this->create_interval_subtotals( $data->intervals ); + wp_cache_set( $cache_key, $data, $this->cache_group ); } return $data; } + /** + * Normalizes order_by clause to match to SQL query. + * + * @param string $order_by Order by option requeste by user. + * @return string + */ + protected function normalize_order_by( $order_by ) { + if ( 'date' === $order_by ) { + return 'time_interval'; + } + + return $order_by; + } + } diff --git a/plugins/woocommerce-admin/tests/api/reports-products-stats.php b/plugins/woocommerce-admin/tests/api/reports-products-stats.php index a3e6248260e..319005f1a9b 100644 --- a/plugins/woocommerce-admin/tests/api/reports-products-stats.php +++ b/plugins/woocommerce-admin/tests/api/reports-products-stats.php @@ -74,8 +74,8 @@ class WC_Tests_API_Reports_Products_Stats extends WC_REST_Unit_Test_Case { $request = new WP_REST_Request( 'GET', $this->endpoint ); $request->set_query_params( array( - 'before' => date( 'Y-m-d H:00:00', $time + DAY_IN_SECONDS ), - 'after' => date( 'Y-m-d H:00:00', $time - DAY_IN_SECONDS ), + 'before' => date( 'Y-m-d 23:59:59', $time ), + 'after' => date( 'Y-m-d 00:00:00', $time ), 'interval' => 'day', ) );