diff --git a/plugins/woocommerce-admin/client/analytics/report/taxes/config.js b/plugins/woocommerce-admin/client/analytics/report/taxes/config.js index e240f493355..5852fcd18d0 100644 --- a/plugins/woocommerce-admin/client/analytics/report/taxes/config.js +++ b/plugins/woocommerce-admin/client/analytics/report/taxes/config.js @@ -3,11 +3,17 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; +import apiFetch from '@wordpress/api-fetch'; +import { find } from 'lodash'; + +/** + * WooCommerce dependencies + */ +import { getIdsFromQuery, stringifyQuery } from '@woocommerce/navigation'; /** * Internal dependencies */ -import { getRequestByIdString } from 'lib/async-requests'; import { getTaxCode } from './utils'; import { NAMESPACE } from 'wc-api/constants'; @@ -52,15 +58,30 @@ export const filters = [ { label: __( 'All Taxes', 'wc-admin' ), value: 'all' }, { label: __( 'Comparison', 'wc-admin' ), - value: 'compare-tax-codes', + value: 'compare-taxes', chartMode: 'item-comparison', settings: { type: 'taxes', param: 'taxes', - getLabels: getRequestByIdString( NAMESPACE + '/taxes', tax => ( { - id: tax.id, - label: getTaxCode( tax ), - } ) ), + // @TODO: Core /taxes endpoint should support a collection param 'include'. + getLabels: function( queryString = '' ) { + const idList = getIdsFromQuery( queryString ); + if ( idList.length < 1 ) { + return Promise.resolve( [] ); + } + const payload = stringifyQuery( { + per_page: -1, + } ); + return apiFetch( { path: NAMESPACE + '/taxes' + payload } ).then( taxes => { + return idList.map( id => { + const tax = find( taxes, { id } ); + return { + id: tax.id, + label: getTaxCode( tax ), + }; + } ); + } ); + }, labels: { helpText: __( 'Select at least two tax codes to compare', 'wc-admin' ), placeholder: __( 'Search for tax codes to compare', 'wc-admin' ), diff --git a/plugins/woocommerce-admin/client/analytics/report/taxes/index.js b/plugins/woocommerce-admin/client/analytics/report/taxes/index.js index 9414958c59c..40860866d09 100644 --- a/plugins/woocommerce-admin/client/analytics/report/taxes/index.js +++ b/plugins/woocommerce-admin/client/analytics/report/taxes/index.js @@ -4,6 +4,7 @@ */ import { Component, Fragment } from '@wordpress/element'; import PropTypes from 'prop-types'; +import { __ } from '@wordpress/i18n'; /** * WooCommerce dependencies @@ -20,22 +21,46 @@ import ReportSummary from 'analytics/components/report-summary'; import TaxesReportTable from './table'; export default class TaxesReport extends Component { + getChartMeta() { + const { query } = this.props; + const isCompareTaxView = 'compare-taxes' === query.filter; + const mode = isCompareTaxView ? 'item-comparison' : 'time-comparison'; + const itemsLabel = __( '%d taxes', 'wc-admin' ); + + return { + itemsLabel, + mode, + }; + } + render() { const { query, path } = this.props; + const { mode, itemsLabel } = this.getChartMeta(); + + const chartQuery = { + ...query, + }; + + if ( 'item-comparison' === mode ) { + chartQuery.segmentby = 'tax_rate_id'; + } return ( diff --git a/plugins/woocommerce-admin/includes/class-wc-admin-reports-segmenting.php b/plugins/woocommerce-admin/includes/class-wc-admin-reports-segmenting.php index 84f264d09c2..232ccc28359 100644 --- a/plugins/woocommerce-admin/includes/class-wc-admin-reports-segmenting.php +++ b/plugins/woocommerce-admin/includes/class-wc-admin-reports-segmenting.php @@ -355,6 +355,7 @@ class WC_Admin_Reports_Segmenting { $args['include'] = $this->query_args['categories']; } + // @todo: Look into `wc_get_products` or data store methods and not directly touching the database or post types. $categories = get_categories( $args ); $segments = wp_list_pluck( $categories, 'cat_ID' ); @@ -374,15 +375,17 @@ class WC_Admin_Reports_Segmenting { // 1 -- returning customer $segments = array( 0, 1 ); } elseif ( 'tax_rate_id' === $this->query_args['segmentby'] ) { - // @todo Do we need to include tax rates that existed in the past, but have never been used? I guess there are other, more pressing problems... - // Current tax rates UNION previously used tax rates. - $tax_rate_ids = $wpdb->get_results( - "SELECT tax_rate_id FROM {$wpdb->prefix}woocommerce_tax_rates - UNION - SELECT DISTINCT meta_value FROM {$wpdb->prefix}woocommerce_order_itemmeta where meta_key='rate_id'", - ARRAY_A - ); // WPCS: cache ok, DB call ok, unprepared SQL ok. - $segments = wp_list_pluck( $tax_rate_ids, 'tax_rate_id' ); + $args = array(); + if ( isset( $this->query_args['taxes'] ) ) { + $args['include'] = $this->query_args['taxes']; + } + $taxes = WC_Admin_Reports_Taxes_Stats_Data_Store::get_taxes( $args ); + + foreach ( $taxes as $tax ) { + $id = $tax['tax_rate_id']; + $segments[] = $id; + $segment_labels[ $id ] = WC_Tax::get_rate_code( (object) $tax ); + } } else { // Catch all default. $segments = array(); diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php index f028a318d65..767d2f3b7ec 100644 --- a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php +++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php @@ -102,6 +102,30 @@ class WC_Admin_Reports_Taxes_Stats_Data_Store extends WC_Admin_Reports_Data_Stor $intervals_params['where_clause'] .= $taxes_where_clause; } + /** + * Get taxes associated with a store. + * + * @param array $args Array of args to filter the query by. Supports `include`. + * @return array An array of all taxes. + */ + public static function get_taxes( $args ) { + global $wpdb; + $query = " + SELECT + tax_rate_id, + tax_rate_country, + tax_rate_state, + tax_rate_name, + tax_rate_priority + FROM {$wpdb->prefix}woocommerce_tax_rates + "; + if ( ! empty( $args['include'] ) ) { + $included_taxes = implode( ',', $args['include'] ); + $query .= " WHERE tax_rate_id IN ({$included_taxes})"; + } + return $wpdb->get_results( $query, ARRAY_A ); // WPCS: cache ok, DB call ok, unprepared SQL ok. + } + /** * Returns the report data based on parameters supplied by the user. *