diff --git a/plugins/woocommerce-admin/client/analytics/report/categories/table.js b/plugins/woocommerce-admin/client/analytics/report/categories/table.js index dc9e277401d..3aaf7f5f771 100644 --- a/plugins/woocommerce-admin/client/analytics/report/categories/table.js +++ b/plugins/woocommerce-admin/client/analytics/report/categories/table.js @@ -19,6 +19,12 @@ import ReportTable from 'analytics/components/report-table'; import { numberFormat } from 'lib/number'; export default class CategoriesReportTable extends Component { + constructor( props ) { + super( props ); + + this.getRowsContent = this.getRowsContent.bind( this ); + } + getHeadersContent() { return [ { @@ -60,23 +66,27 @@ export default class CategoriesReportTable extends Component { getRowsContent( categories ) { return map( categories, category => { - const { category_id, items_sold, gross_revenue, products_count, orders_count } = category; - - // @TODO it should link to the Products report filtered by category - const productsLink = ( - - { numberFormat( products_count ) } - - ); + const { + category_id, + items_sold, + gross_revenue, + products_count, + orders_count, + extended_info, + } = category; + const { name } = extended_info; return [ - // @TODO it should be the category name, not the category ID { - display: category_id, - value: category_id, + display: ( + + { name } + + ), + value: name, }, { display: numberFormat( items_sold ), @@ -87,7 +97,7 @@ export default class CategoriesReportTable extends Component { value: getCurrencyFormatDecimal( gross_revenue ), }, { - display: productsLink, + display: numberFormat( products_count ), value: products_count, }, { @@ -135,6 +145,11 @@ export default class CategoriesReportTable extends Component { getSummary={ this.getSummary } itemIdField="category_id" query={ query } + tableQuery={ { + orderby: query.orderby || 'items_sold', + order: query.order || 'desc', + extended_info: true, + } } title={ __( 'Categories', 'wc-admin' ) } columnPrefsKey="categories_report_columns" /> diff --git a/plugins/woocommerce-admin/client/store/reports/items/resolvers.js b/plugins/woocommerce-admin/client/store/reports/items/resolvers.js index 3c6887dc95f..13dca9b6979 100644 --- a/plugins/woocommerce-admin/client/store/reports/items/resolvers.js +++ b/plugins/woocommerce-admin/client/store/reports/items/resolvers.js @@ -20,7 +20,7 @@ export default { async getReportItems( ...args ) { const [ endpoint, query ] = args.slice( -2 ); - const swaggerEndpoints = [ 'categories', 'coupons' ]; + const swaggerEndpoints = [ 'coupons' ]; if ( swaggerEndpoints.indexOf( endpoint ) >= 0 ) { try { const response = await fetch( diff --git a/plugins/woocommerce-admin/client/wc-api/reports/items/operations.js b/plugins/woocommerce-admin/client/wc-api/reports/items/operations.js index 9d9a90457c9..405fbb5d272 100644 --- a/plugins/woocommerce-admin/client/wc-api/reports/items/operations.js +++ b/plugins/woocommerce-admin/client/wc-api/reports/items/operations.js @@ -17,7 +17,7 @@ import { NAMESPACE } from '../../constants'; import { SWAGGERNAMESPACE } from 'store/constants'; // TODO: Remove once swagger endpoints are phased out. -const swaggerEndpoints = [ 'categories', 'coupons', 'customers' ]; +const swaggerEndpoints = [ 'coupons', 'customers' ]; const typeEndpointMap = { 'report-items-query-orders': 'orders', diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-categories-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-categories-controller.php index 31ee59c004a..98a6809ce74 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-categories-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-categories-controller.php @@ -38,15 +38,16 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_REST_Reports_Contro * @return array */ protected function prepare_reports_query( $request ) { - $args = array(); - $args['before'] = $request['before']; - $args['after'] = $request['after']; - $args['interval'] = $request['interval']; - $args['page'] = $request['page']; - $args['per_page'] = $request['per_page']; - $args['orderby'] = $request['orderby']; - $args['order'] = $request['order']; - $args['categories'] = (array) $request['categories']; + $args = array(); + $args['before'] = $request['before']; + $args['after'] = $request['after']; + $args['interval'] = $request['interval']; + $args['page'] = $request['page']; + $args['per_page'] = $request['per_page']; + $args['orderby'] = $request['orderby']; + $args['order'] = $request['order']; + $args['extended_info'] = $request['extended_info']; + $args['categories'] = (array) $request['categories']; $args['status_is'] = (array) $request['status_is']; $args['status_is_not'] = (array) $request['status_is_not']; @@ -190,6 +191,14 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_REST_Reports_Contro 'context' => array( 'view', 'edit' ), 'readonly' => true, ), + 'extended_info' => array( + 'name' => array( + 'type' => 'string', + 'readonly' => true, + 'context' => array( 'view', 'edit' ), + 'description' => __( 'Category name.', 'wc-admin' ), + ), + ), ), ); @@ -202,9 +211,9 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_REST_Reports_Contro * @return array */ public function get_collection_params() { - $params = array(); - $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); - $params['page'] = array( + $params = array(); + $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); + $params['page'] = array( 'description' => __( 'Current page of the collection.', 'wc-admin' ), 'type' => 'integer', 'default' => 1, @@ -212,7 +221,7 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_REST_Reports_Contro 'validate_callback' => 'rest_validate_request_arg', 'minimum' => 1, ); - $params['per_page'] = array( + $params['per_page'] = array( 'description' => __( 'Maximum number of items to be returned in result set.', 'wc-admin' ), 'type' => 'integer', 'default' => 10, @@ -221,26 +230,26 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_REST_Reports_Contro 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); - $params['after'] = array( + $params['after'] = array( 'description' => __( 'Limit response to resources published after a given ISO8601 compliant date.', 'wc-admin' ), 'type' => 'string', 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); - $params['before'] = array( + $params['before'] = array( 'description' => __( 'Limit response to resources published before a given ISO8601 compliant date.', 'wc-admin' ), 'type' => 'string', 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); - $params['order'] = array( + $params['order'] = array( 'description' => __( 'Order sort attribute ascending or descending.', 'wc-admin' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( 'asc', 'desc' ), 'validate_callback' => 'rest_validate_request_arg', ); - $params['orderby'] = array( + $params['orderby'] = array( 'description' => __( 'Sort collection by object attribute.', 'wc-admin' ), 'type' => 'string', 'default' => 'date', @@ -250,10 +259,11 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_REST_Reports_Contro 'gross_revenue', 'orders_count', 'products_count', + 'category', ), 'validate_callback' => 'rest_validate_request_arg', ); - $params['interval'] = array( + $params['interval'] = array( 'description' => __( 'Time interval to use for buckets in the returned data.', 'wc-admin' ), 'type' => 'string', 'default' => 'week', @@ -267,7 +277,7 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_REST_Reports_Contro ), 'validate_callback' => 'rest_validate_request_arg', ); - $params['status_is'] = array( + $params['status_is'] = array( 'description' => __( 'Limit result set to items that have the specified order status.', 'wc-admin' ), 'type' => 'array', 'sanitize_callback' => 'wp_parse_slug_list', @@ -277,7 +287,7 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_REST_Reports_Contro 'type' => 'string', ), ); - $params['status_is_not'] = array( + $params['status_is_not'] = array( 'description' => __( 'Limit result set to items that don\'t have the specified order status.', 'wc-admin' ), 'type' => 'array', 'sanitize_callback' => 'wp_parse_slug_list', @@ -287,7 +297,7 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_REST_Reports_Contro 'type' => 'string', ), ); - $params['categories'] = array( + $params['categories'] = array( 'description' => __( 'Limit result set to all items that have the specified term assigned in the categories taxonomy.', 'wc-admin' ), 'type' => 'array', 'sanitize_callback' => 'wp_parse_id_list', @@ -296,6 +306,13 @@ class WC_Admin_REST_Reports_Categories_Controller extends WC_REST_Reports_Contro 'type' => 'integer', ), ); + $params['extended_info'] = array( + 'description' => __( 'Add additional piece of info about each category to the report.', 'wc-admin' ), + 'type' => 'boolean', + 'default' => false, + 'sanitize_callback' => 'wc_string_to_bool', + 'validate_callback' => 'rest_validate_request_arg', + ); return $params; } diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-categories-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-categories-data-store.php index 9bdd6e4c2bb..75fb2bf542d 100644 --- a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-categories-data-store.php +++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-categories-data-store.php @@ -148,6 +148,22 @@ class WC_Admin_Reports_Categories_Data_Store extends WC_Admin_Reports_Data_Store return array_slice( $data, $offset, $items_per_page ); } + /** + * Enriches the category data. + * + * @param array $categories_data Categories data. + * @param array $query_args Query parameters. + */ + protected function include_extended_info( &$categories_data, $query_args ) { + foreach ( $categories_data as $key => $category_data ) { + $extended_info = new ArrayObject(); + if ( $query_args['extended_info'] ) { + $extended_info['name'] = get_the_category_by_ID( $category_data['category_id'] ); + } + $categories_data[ $key ]['extended_info'] = $extended_info; + } + } + /** * Returns the report data based on parameters supplied by the user. * @@ -163,16 +179,17 @@ class WC_Admin_Reports_Categories_Data_Store extends WC_Admin_Reports_Data_Store // These defaults are only partially applied when used via REST API, as that has its own defaults. $defaults = array( - 'per_page' => get_option( 'posts_per_page' ), - 'page' => 1, - 'order' => 'DESC', - 'orderby' => 'date', - 'before' => date( WC_Admin_Reports_Interval::$iso_datetime_format, $now ), - 'after' => date( WC_Admin_Reports_Interval::$iso_datetime_format, $week_back ), - 'fields' => '*', - 'categories' => array(), + 'per_page' => get_option( 'posts_per_page' ), + 'page' => 1, + 'order' => 'DESC', + 'orderby' => 'date', + 'before' => date( WC_Admin_Reports_Interval::$iso_datetime_format, $now ), + 'after' => date( WC_Admin_Reports_Interval::$iso_datetime_format, $week_back ), + 'fields' => '*', + 'categories' => array(), + 'extended_info' => false, // This is not a parameter for products reports per se, but maybe we should restricts order statuses here, too? - 'order_status' => parent::get_report_order_statuses(), + 'order_status' => parent::get_report_order_statuses(), ); $query_args = wp_parse_args( $query_args, $defaults ); @@ -246,6 +263,8 @@ class WC_Admin_Reports_Categories_Data_Store extends WC_Admin_Reports_Data_Store $this->sort_records( $categories_data, $query_args['orderby'], $query_args['order'] ); $categories_data = $this->page_records( $categories_data, $query_args['page'], $query_args['per_page'] ); + $this->include_extended_info( $categories_data, $query_args ); + $categories_data = array_map( array( $this, 'cast_numbers' ), $categories_data ); $data = (object) array( 'data' => $categories_data, diff --git a/plugins/woocommerce-admin/tests/api/reports-categories.php b/plugins/woocommerce-admin/tests/api/reports-categories.php index 7701a161dc8..50cb2525341 100644 --- a/plugins/woocommerce-admin/tests/api/reports-categories.php +++ b/plugins/woocommerce-admin/tests/api/reports-categories.php @@ -5,6 +5,13 @@ * @package WooCommerce\Tests\API * @since 3.5.0 */ + +/** + * Reports Categories REST API Test Class + * + * @package WooCommerce\Tests\API + * @since 3.5.0 + */ class WC_Tests_API_Reports_Categories extends WC_REST_Unit_Test_Case { /** @@ -102,11 +109,12 @@ class WC_Tests_API_Reports_Categories extends WC_REST_Unit_Test_Case { $data = $response->get_data(); $properties = $data['schema']['properties']; - $this->assertEquals( 5, count( $properties ) ); + $this->assertEquals( 6, count( $properties ) ); $this->assertArrayHasKey( 'category_id', $properties ); $this->assertArrayHasKey( 'items_sold', $properties ); $this->assertArrayHasKey( 'gross_revenue', $properties ); $this->assertArrayHasKey( 'orders_count', $properties ); $this->assertArrayHasKey( 'products_count', $properties ); + $this->assertArrayHasKey( 'extended_info', $properties ); } }