Make products and rates endpoints return zero-value items (https://github.com/woocommerce/woocommerce-admin/pull/1722)
* Make products endpoint return zero-value items * Make rates endpoint return zero-value items * Several fixes * Add tests * Simplify code * Merge both queries into one to simplify code * Rename 'get_outer_from_sql_params' to 'get_from_sql_params'
This commit is contained in:
parent
4d80cad52e
commit
d2c0dd5555
|
@ -606,6 +606,53 @@ class WC_Admin_Reports_Data_Store {
|
||||||
return $sql_query;
|
return $sql_query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a virtual table given a list of IDs.
|
||||||
|
*
|
||||||
|
* @param array $ids Array of IDs.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function get_ids_table( $ids ) {
|
||||||
|
$selects = array();
|
||||||
|
foreach ( $ids as $id ) {
|
||||||
|
array_push( $selects, "SELECT {$id} AS id" );
|
||||||
|
}
|
||||||
|
return join( ' UNION ', $selects );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a comma separated list of the fields in the `query_args`, if there aren't, returns `report_columns` keys.
|
||||||
|
*
|
||||||
|
* @param array $query_args Parameters supplied by the user.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function get_fields( $query_args ) {
|
||||||
|
if ( isset( $query_args['fields'] ) && is_array( $query_args['fields'] ) ) {
|
||||||
|
return $query_args['fields'];
|
||||||
|
}
|
||||||
|
return array_keys( $this->report_columns );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a comma separated list of the field names prepared to be used for a selection after a join with `default_results`.
|
||||||
|
*
|
||||||
|
* @param array $fields Array of fields name.
|
||||||
|
* @param string $id_field Name of the column used as an identifier.
|
||||||
|
* @param array $outer_selections Array of fields that are not selected in the inner query.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function format_join_selections( $fields, $id_field, $outer_selections = array() ) {
|
||||||
|
foreach ( $fields as $i => $field ) {
|
||||||
|
if ( $field === $id_field ) {
|
||||||
|
$fields[ $i ] = "default_results.id AS {$field}";
|
||||||
|
}
|
||||||
|
if ( in_array( $field, $outer_selections, true ) && array_key_exists( $field, $this->report_columns ) ) {
|
||||||
|
$fields[ $i ] = $this->report_columns[ $field ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return implode( ', ', $fields );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fills ORDER BY clause of SQL request based on user supplied parameters.
|
* Fills ORDER BY clause of SQL request based on user supplied parameters.
|
||||||
*
|
*
|
||||||
|
@ -683,12 +730,12 @@ class WC_Admin_Reports_Data_Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns comma separated ids of allowed products, based on query arguments from the user.
|
* Returns an array of ids of allowed products, based on query arguments from the user.
|
||||||
*
|
*
|
||||||
* @param array $query_args Parameters supplied by the user.
|
* @param array $query_args Parameters supplied by the user.
|
||||||
* @return string
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function get_included_products( $query_args ) {
|
protected function get_included_products_array( $query_args ) {
|
||||||
$included_products = array();
|
$included_products = array();
|
||||||
$operator = $this->get_match_operator( $query_args );
|
$operator = $this->get_match_operator( $query_args );
|
||||||
|
|
||||||
|
@ -710,8 +757,18 @@ class WC_Admin_Reports_Data_Store {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$included_products_str = implode( ',', $included_products );
|
return $included_products;
|
||||||
return $included_products_str;
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns comma separated ids of allowed products, based on query arguments from the user.
|
||||||
|
*
|
||||||
|
* @param array $query_args Parameters supplied by the user.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function get_included_products( $query_args ) {
|
||||||
|
$included_products = $this->get_included_products_array( $query_args );
|
||||||
|
return implode( ',', $included_products );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -106,18 +106,6 @@ class WC_Admin_Reports_Products_Data_Store extends WC_Admin_Reports_Data_Store i
|
||||||
if ( isset( $query_args['orderby'] ) ) {
|
if ( isset( $query_args['orderby'] ) ) {
|
||||||
$sql_query['order_by_clause'] = $this->normalize_order_by( $query_args['orderby'] );
|
$sql_query['order_by_clause'] = $this->normalize_order_by( $query_args['orderby'] );
|
||||||
}
|
}
|
||||||
// Order by product name requires extra JOIN.
|
|
||||||
if ( false !== strpos( $sql_query['order_by_clause'], '_products' ) ) {
|
|
||||||
$sql_query['from_clause'] .= " JOIN {$wpdb->prefix}posts AS _products ON {$order_product_lookup_table}.product_id = _products.ID";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( 'postmeta.meta_value' === $sql_query['order_by_clause'] ) {
|
|
||||||
$sql_query['from_clause'] .= " JOIN {$wpdb->prefix}postmeta AS postmeta ON {$order_product_lookup_table}.product_id = postmeta.post_id AND postmeta.meta_key = '_sku'";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( 'variations' === $sql_query['order_by_clause'] ) {
|
|
||||||
$sql_query['from_clause'] .= " LEFT JOIN ( SELECT post_parent, COUNT(*) AS variations FROM {$wpdb->prefix}posts WHERE post_type = 'product_variation' GROUP BY post_parent ) AS _variations ON {$order_product_lookup_table}.product_id = _variations.post_parent";
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( isset( $query_args['order'] ) ) {
|
if ( isset( $query_args['order'] ) ) {
|
||||||
$sql_query['order_by_clause'] .= ' ' . $query_args['order'];
|
$sql_query['order_by_clause'] .= ' ' . $query_args['order'];
|
||||||
|
@ -128,6 +116,32 @@ class WC_Admin_Reports_Products_Data_Store extends WC_Admin_Reports_Data_Store i
|
||||||
return $sql_query;
|
return $sql_query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fills FROM clause of SQL request based on user supplied parameters.
|
||||||
|
*
|
||||||
|
* @param array $query_args Parameters supplied by the user.
|
||||||
|
* @param string $arg_name Name of the FROM sql param.
|
||||||
|
* @param string $id_cell ID cell identifier, like `table_name.id_column_name`.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function get_from_sql_params( $query_args, $arg_name, $id_cell ) {
|
||||||
|
global $wpdb;
|
||||||
|
$sql_query['outer_from_clause'] = '';
|
||||||
|
|
||||||
|
// Order by product name requires extra JOIN.
|
||||||
|
if ( 'product_name' === $query_args['orderby'] ) {
|
||||||
|
$sql_query[ $arg_name ] .= " JOIN {$wpdb->prefix}posts AS _products ON {$id_cell} = _products.ID";
|
||||||
|
}
|
||||||
|
if ( 'sku' === $query_args['orderby'] ) {
|
||||||
|
$sql_query[ $arg_name ] .= " JOIN {$wpdb->prefix}postmeta AS postmeta ON {$id_cell} = postmeta.post_id AND postmeta.meta_key = '_sku'";
|
||||||
|
}
|
||||||
|
if ( 'variations' === $query_args['orderby'] ) {
|
||||||
|
$sql_query[ $arg_name ] .= " LEFT JOIN ( SELECT post_parent, COUNT(*) AS variations FROM {$wpdb->prefix}posts WHERE post_type = 'product_variation' GROUP BY post_parent ) AS _variations ON {$id_cell} = _variations.post_parent";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sql_query;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the database query with parameters used for Products report: categories and order status.
|
* Updates the database query with parameters used for Products report: categories and order status.
|
||||||
*
|
*
|
||||||
|
@ -144,7 +158,10 @@ class WC_Admin_Reports_Products_Data_Store extends WC_Admin_Reports_Data_Store i
|
||||||
|
|
||||||
$included_products = $this->get_included_products( $query_args );
|
$included_products = $this->get_included_products( $query_args );
|
||||||
if ( $included_products ) {
|
if ( $included_products ) {
|
||||||
|
$sql_query_params = array_merge( $sql_query_params, $this->get_from_sql_params( $query_args, 'outer_from_clause', 'default_results.id' ) );
|
||||||
$sql_query_params['where_clause'] .= " AND {$order_product_lookup_table}.product_id IN ({$included_products})";
|
$sql_query_params['where_clause'] .= " AND {$order_product_lookup_table}.product_id IN ({$included_products})";
|
||||||
|
} else {
|
||||||
|
$sql_query_params = array_merge( $sql_query_params, $this->get_from_sql_params( $query_args, 'from_clause', "{$order_product_lookup_table}.product_id" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
$included_variations = $this->get_included_variations( $query_args );
|
$included_variations = $this->get_included_variations( $query_args );
|
||||||
|
@ -175,10 +192,10 @@ class WC_Admin_Reports_Products_Data_Store extends WC_Admin_Reports_Data_Store i
|
||||||
return $order_product_lookup_table . '.date_created';
|
return $order_product_lookup_table . '.date_created';
|
||||||
}
|
}
|
||||||
if ( 'product_name' === $order_by ) {
|
if ( 'product_name' === $order_by ) {
|
||||||
return '_products.post_title';
|
return 'post_title';
|
||||||
}
|
}
|
||||||
if ( 'sku' === $order_by ) {
|
if ( 'sku' === $order_by ) {
|
||||||
return 'postmeta.meta_value';
|
return 'meta_value';
|
||||||
}
|
}
|
||||||
return $order_by;
|
return $order_by;
|
||||||
}
|
}
|
||||||
|
@ -257,32 +274,57 @@ class WC_Admin_Reports_Products_Data_Store extends WC_Admin_Reports_Data_Store i
|
||||||
'page_no' => 0,
|
'page_no' => 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
$selections = $this->selected_columns( $query_args );
|
$selections = $this->selected_columns( $query_args );
|
||||||
$sql_query_params = $this->get_sql_query_params( $query_args );
|
$sql_query_params = $this->get_sql_query_params( $query_args );
|
||||||
|
$included_products = $this->get_included_products_array( $query_args );
|
||||||
|
|
||||||
$db_records_count = (int) $wpdb->get_var(
|
if ( count( $included_products ) > 0 ) {
|
||||||
"SELECT COUNT(*) FROM (
|
$total_results = count( $included_products );
|
||||||
SELECT
|
$total_pages = (int) ceil( $total_results / $sql_query_params['per_page'] );
|
||||||
product_id
|
|
||||||
FROM
|
|
||||||
{$table_name}
|
|
||||||
{$sql_query_params['from_clause']}
|
|
||||||
WHERE
|
|
||||||
1=1
|
|
||||||
{$sql_query_params['where_time_clause']}
|
|
||||||
{$sql_query_params['where_clause']}
|
|
||||||
GROUP BY
|
|
||||||
product_id
|
|
||||||
) AS tt"
|
|
||||||
); // WPCS: cache ok, DB call ok, unprepared SQL ok.
|
|
||||||
|
|
||||||
$total_pages = (int) ceil( $db_records_count / $sql_query_params['per_page'] );
|
if ( 'date' === $query_args['orderby'] ) {
|
||||||
if ( $query_args['page'] < 1 || $query_args['page'] > $total_pages ) {
|
$selections .= ", {$table_name}.date_created";
|
||||||
return $data;
|
}
|
||||||
|
|
||||||
|
$fields = $this->get_fields( $query_args );
|
||||||
|
$join_selections = $this->format_join_selections( $fields, 'product_id' );
|
||||||
|
$ids_table = $this->get_ids_table( $included_products, 'product_id' );
|
||||||
|
$prefix = "SELECT {$join_selections} FROM (";
|
||||||
|
$suffix = ") AS {$table_name}";
|
||||||
|
$right_join = "RIGHT JOIN ( {$ids_table} ) AS default_results
|
||||||
|
ON default_results.id = {$table_name}.product_id";
|
||||||
|
} else {
|
||||||
|
$db_records_count = (int) $wpdb->get_var(
|
||||||
|
"SELECT COUNT(*) FROM (
|
||||||
|
SELECT
|
||||||
|
product_id
|
||||||
|
FROM
|
||||||
|
{$table_name}
|
||||||
|
{$sql_query_params['from_clause']}
|
||||||
|
WHERE
|
||||||
|
1=1
|
||||||
|
{$sql_query_params['where_time_clause']}
|
||||||
|
{$sql_query_params['where_clause']}
|
||||||
|
GROUP BY
|
||||||
|
product_id
|
||||||
|
) AS tt"
|
||||||
|
); // WPCS: cache ok, DB call ok, unprepared SQL ok.
|
||||||
|
|
||||||
|
$total_results = $db_records_count;
|
||||||
|
$total_pages = (int) ceil( $db_records_count / $sql_query_params['per_page'] );
|
||||||
|
|
||||||
|
if ( ( $query_args['page'] < 1 || $query_args['page'] > $total_pages ) ) {
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
$prefix = '';
|
||||||
|
$suffix = '';
|
||||||
|
$right_join = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$product_data = $wpdb->get_results(
|
$product_data = $wpdb->get_results(
|
||||||
"SELECT
|
"${prefix}
|
||||||
|
SELECT
|
||||||
{$selections}
|
{$selections}
|
||||||
FROM
|
FROM
|
||||||
{$table_name}
|
{$table_name}
|
||||||
|
@ -293,6 +335,9 @@ class WC_Admin_Reports_Products_Data_Store extends WC_Admin_Reports_Data_Store i
|
||||||
{$sql_query_params['where_clause']}
|
{$sql_query_params['where_clause']}
|
||||||
GROUP BY
|
GROUP BY
|
||||||
product_id
|
product_id
|
||||||
|
{$suffix}
|
||||||
|
{$right_join}
|
||||||
|
{$sql_query_params['outer_from_clause']}
|
||||||
ORDER BY
|
ORDER BY
|
||||||
{$sql_query_params['order_by_clause']}
|
{$sql_query_params['order_by_clause']}
|
||||||
{$sql_query_params['limit']}
|
{$sql_query_params['limit']}
|
||||||
|
@ -309,7 +354,7 @@ class WC_Admin_Reports_Products_Data_Store extends WC_Admin_Reports_Data_Store i
|
||||||
$product_data = array_map( array( $this, 'cast_numbers' ), $product_data );
|
$product_data = array_map( array( $this, 'cast_numbers' ), $product_data );
|
||||||
$data = (object) array(
|
$data = (object) array(
|
||||||
'data' => $product_data,
|
'data' => $product_data,
|
||||||
'total' => $db_records_count,
|
'total' => $total_results,
|
||||||
'pages' => $total_pages,
|
'pages' => $total_pages,
|
||||||
'page_no' => (int) $query_args['page'],
|
'page_no' => (int) $query_args['page'],
|
||||||
);
|
);
|
||||||
|
|
|
@ -74,6 +74,33 @@ class WC_Admin_Reports_Taxes_Data_Store extends WC_Admin_Reports_Data_Store impl
|
||||||
add_action( 'woocommerce_refund_deleted', array( __CLASS__, 'sync_on_refund_delete' ), 10, 2 );
|
add_action( 'woocommerce_refund_deleted', array( __CLASS__, 'sync_on_refund_delete' ), 10, 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fills FROM clause of SQL request based on user supplied parameters.
|
||||||
|
*
|
||||||
|
* @param array $query_args Query arguments supplied by the user.
|
||||||
|
* @param string $order_status_filter Order status subquery.
|
||||||
|
* @return array Array of parameters used for SQL query.
|
||||||
|
*/
|
||||||
|
protected function get_from_sql_params( $query_args, $order_status_filter ) {
|
||||||
|
global $wpdb;
|
||||||
|
$table_name = $wpdb->prefix . self::TABLE_NAME;
|
||||||
|
|
||||||
|
$sql_query['from_clause'] = '';
|
||||||
|
$sql_query['outer_from_clause'] = '';
|
||||||
|
|
||||||
|
if ( $order_status_filter ) {
|
||||||
|
$sql_query['from_clause'] .= " JOIN {$wpdb->prefix}wc_order_stats ON {$table_name}.order_id = {$wpdb->prefix}wc_order_stats.order_id";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isset( $query_args['taxes'] ) && ! empty( $query_args['taxes'] ) ) {
|
||||||
|
$sql_query['outer_from_clause'] .= " JOIN {$wpdb->prefix}woocommerce_tax_rates ON default_results.id = {$wpdb->prefix}woocommerce_tax_rates.tax_rate_id";
|
||||||
|
} else {
|
||||||
|
$sql_query['from_clause'] .= " JOIN {$wpdb->prefix}woocommerce_tax_rates ON {$table_name}.tax_rate_id = {$wpdb->prefix}woocommerce_tax_rates.tax_rate_id";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sql_query;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the database query with parameters used for Taxes report: categories and order status.
|
* Updates the database query with parameters used for Taxes report: categories and order status.
|
||||||
*
|
*
|
||||||
|
@ -85,23 +112,21 @@ class WC_Admin_Reports_Taxes_Data_Store extends WC_Admin_Reports_Data_Store impl
|
||||||
|
|
||||||
$order_tax_lookup_table = $wpdb->prefix . self::TABLE_NAME;
|
$order_tax_lookup_table = $wpdb->prefix . self::TABLE_NAME;
|
||||||
|
|
||||||
$sql_query_params = $this->get_time_period_sql_params( $query_args, $order_tax_lookup_table );
|
$sql_query_params = $this->get_time_period_sql_params( $query_args, $order_tax_lookup_table );
|
||||||
$sql_query_params = array_merge( $sql_query_params, $this->get_limit_sql_params( $query_args ) );
|
$sql_query_params = array_merge( $sql_query_params, $this->get_limit_sql_params( $query_args ) );
|
||||||
$sql_query_params = array_merge( $sql_query_params, $this->get_order_by_sql_params( $query_args ) );
|
$sql_query_params = array_merge( $sql_query_params, $this->get_order_by_sql_params( $query_args ) );
|
||||||
|
$order_status_filter = $this->get_status_subquery( $query_args );
|
||||||
|
$sql_query_params = array_merge( $sql_query_params, $this->get_from_sql_params( $query_args, $order_status_filter ) );
|
||||||
|
|
||||||
if ( isset( $query_args['taxes'] ) && ! empty( $query_args['taxes'] ) ) {
|
if ( isset( $query_args['taxes'] ) && ! empty( $query_args['taxes'] ) ) {
|
||||||
$allowed_taxes = implode( ',', $query_args['taxes'] );
|
$allowed_taxes = implode( ',', $query_args['taxes'] );
|
||||||
$sql_query_params['where_clause'] .= " AND {$order_tax_lookup_table}.tax_rate_id IN ({$allowed_taxes})";
|
$sql_query_params['where_clause'] .= " AND {$order_tax_lookup_table}.tax_rate_id IN ({$allowed_taxes})";
|
||||||
}
|
}
|
||||||
|
|
||||||
$order_status_filter = $this->get_status_subquery( $query_args );
|
|
||||||
if ( $order_status_filter ) {
|
if ( $order_status_filter ) {
|
||||||
$sql_query_params['from_clause'] .= " JOIN {$wpdb->prefix}wc_order_stats ON {$order_tax_lookup_table}.order_id = {$wpdb->prefix}wc_order_stats.order_id";
|
|
||||||
$sql_query_params['where_clause'] .= " AND ( {$order_status_filter} )";
|
$sql_query_params['where_clause'] .= " AND ( {$order_status_filter} )";
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql_query_params['from_clause'] .= " JOIN {$wpdb->prefix}woocommerce_tax_rates ON {$order_tax_lookup_table}.tax_rate_id = {$wpdb->prefix}woocommerce_tax_rates.tax_rate_id";
|
|
||||||
|
|
||||||
return $sql_query_params;
|
return $sql_query_params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,42 +187,70 @@ class WC_Admin_Reports_Taxes_Data_Store extends WC_Admin_Reports_Data_Store impl
|
||||||
'page_no' => 0,
|
'page_no' => 0,
|
||||||
);
|
);
|
||||||
|
|
||||||
$selections = $this->selected_columns( $query_args );
|
|
||||||
$sql_query_params = $this->get_sql_query_params( $query_args );
|
$sql_query_params = $this->get_sql_query_params( $query_args );
|
||||||
|
|
||||||
$db_records_count = (int) $wpdb->get_var(
|
if ( isset( $query_args['taxes'] ) && ! empty( $query_args['taxes'] ) ) {
|
||||||
"SELECT COUNT(*) FROM (
|
$total_results = count( $query_args['taxes'] );
|
||||||
SELECT
|
$total_pages = (int) ceil( $total_results / $sql_query_params['per_page'] );
|
||||||
{$table_name}.tax_rate_id
|
|
||||||
FROM
|
|
||||||
{$table_name}
|
|
||||||
{$sql_query_params['from_clause']}
|
|
||||||
WHERE
|
|
||||||
1=1
|
|
||||||
{$sql_query_params['where_time_clause']}
|
|
||||||
{$sql_query_params['where_clause']}
|
|
||||||
GROUP BY
|
|
||||||
{$table_name}.tax_rate_id
|
|
||||||
) AS tt"
|
|
||||||
); // WPCS: cache ok, DB call ok, unprepared SQL ok.
|
|
||||||
|
|
||||||
$total_pages = (int) ceil( $db_records_count / $sql_query_params['per_page'] );
|
$inner_selections = array( 'tax_rate_id', 'total_tax', 'order_tax', 'shipping_tax', 'orders_count' );
|
||||||
if ( $query_args['page'] < 1 || $query_args['page'] > $total_pages ) {
|
$outer_selections = array( 'name', 'tax_rate', 'country', 'state', 'priority' );
|
||||||
return $data;
|
|
||||||
|
$selections = $this->selected_columns( array( 'fields' => $inner_selections ) );
|
||||||
|
$fields = $this->get_fields( $query_args );
|
||||||
|
$join_selections = $this->format_join_selections( $fields, 'tax_rate_id', $outer_selections );
|
||||||
|
$ids_table = $this->get_ids_table( $query_args['taxes'], 'tax_rate_id' );
|
||||||
|
$prefix = "SELECT {$join_selections} FROM (";
|
||||||
|
$suffix = ") AS {$table_name}";
|
||||||
|
$right_join = "RIGHT JOIN ( {$ids_table} ) AS default_results
|
||||||
|
ON default_results.id = {$table_name}.tax_rate_id";
|
||||||
|
} else {
|
||||||
|
$db_records_count = (int) $wpdb->get_var(
|
||||||
|
"SELECT COUNT(*) FROM (
|
||||||
|
SELECT
|
||||||
|
{$table_name}.tax_rate_id
|
||||||
|
FROM
|
||||||
|
{$table_name}
|
||||||
|
{$sql_query_params['from_clause']}
|
||||||
|
WHERE
|
||||||
|
1=1
|
||||||
|
{$sql_query_params['where_time_clause']}
|
||||||
|
{$sql_query_params['where_clause']}
|
||||||
|
GROUP BY
|
||||||
|
{$table_name}.tax_rate_id
|
||||||
|
) AS tt"
|
||||||
|
); // WPCS: cache ok, DB call ok, unprepared SQL ok.
|
||||||
|
|
||||||
|
$total_results = $db_records_count;
|
||||||
|
$total_pages = (int) ceil( $db_records_count / $sql_query_params['per_page'] );
|
||||||
|
|
||||||
|
if ( $query_args['page'] < 1 || $query_args['page'] > $total_pages ) {
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
$selections = $this->selected_columns( $query_args );
|
||||||
|
|
||||||
|
$prefix = '';
|
||||||
|
$suffix = '';
|
||||||
|
$right_join = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$tax_data = $wpdb->get_results(
|
$tax_data = $wpdb->get_results(
|
||||||
"SELECT
|
"{$prefix}
|
||||||
{$selections}
|
SELECT
|
||||||
FROM
|
{$selections}
|
||||||
{$table_name}
|
FROM
|
||||||
{$sql_query_params['from_clause']}
|
{$table_name}
|
||||||
WHERE
|
{$sql_query_params['from_clause']}
|
||||||
1=1
|
WHERE
|
||||||
{$sql_query_params['where_time_clause']}
|
1=1
|
||||||
{$sql_query_params['where_clause']}
|
{$sql_query_params['where_time_clause']}
|
||||||
GROUP BY
|
{$sql_query_params['where_clause']}
|
||||||
{$table_name}.tax_rate_id
|
GROUP BY
|
||||||
|
{$table_name}.tax_rate_id
|
||||||
|
{$suffix}
|
||||||
|
{$right_join}
|
||||||
|
{$sql_query_params['outer_from_clause']}
|
||||||
ORDER BY
|
ORDER BY
|
||||||
{$sql_query_params['order_by_clause']}
|
{$sql_query_params['order_by_clause']}
|
||||||
{$sql_query_params['limit']}
|
{$sql_query_params['limit']}
|
||||||
|
@ -212,7 +265,7 @@ class WC_Admin_Reports_Taxes_Data_Store extends WC_Admin_Reports_Data_Store impl
|
||||||
$tax_data = array_map( array( $this, 'cast_numbers' ), $tax_data );
|
$tax_data = array_map( array( $this, 'cast_numbers' ), $tax_data );
|
||||||
$data = (object) array(
|
$data = (object) array(
|
||||||
'data' => $tax_data,
|
'data' => $tax_data,
|
||||||
'total' => $db_records_count,
|
'total' => $total_results,
|
||||||
'pages' => $total_pages,
|
'pages' => $total_pages,
|
||||||
'page_no' => (int) $query_args['page'],
|
'page_no' => (int) $query_args['page'],
|
||||||
);
|
);
|
||||||
|
|
|
@ -84,6 +84,62 @@ class WC_Tests_API_Reports_Products extends WC_REST_Unit_Test_Case {
|
||||||
$this->assertArrayHasKey( 'product', $product_report['_links'] );
|
$this->assertArrayHasKey( 'product', $product_report['_links'] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test getting reports with the `products` param.
|
||||||
|
*
|
||||||
|
* @since 3.5.0
|
||||||
|
*/
|
||||||
|
public function test_get_reports_products_param() {
|
||||||
|
wp_set_current_user( $this->user );
|
||||||
|
WC_Helper_Reports::reset_stats_dbs();
|
||||||
|
|
||||||
|
// Populate all of the data.
|
||||||
|
$product = new WC_Product_Simple();
|
||||||
|
$product->set_name( 'Test Product' );
|
||||||
|
$product->set_regular_price( 25 );
|
||||||
|
$product->save();
|
||||||
|
|
||||||
|
$product_2 = new WC_Product_Simple();
|
||||||
|
$product_2->set_name( 'Test Product 2' );
|
||||||
|
$product_2->set_regular_price( 25 );
|
||||||
|
$product_2->save();
|
||||||
|
|
||||||
|
$order = WC_Helper_Order::create_order( 1, $product );
|
||||||
|
$order->set_status( 'completed' );
|
||||||
|
$order->set_total( 100 ); // $25 x 4.
|
||||||
|
$order->save();
|
||||||
|
|
||||||
|
WC_Helper_Queue::run_all_pending();
|
||||||
|
|
||||||
|
$request = new WP_REST_Request( 'GET', $this->endpoint );
|
||||||
|
$request->set_query_params(
|
||||||
|
array(
|
||||||
|
'products' => $product->get_id() . ',' . $product_2->get_id(),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$response = $this->server->dispatch( $request );
|
||||||
|
$reports = $response->get_data();
|
||||||
|
|
||||||
|
$this->assertEquals( 200, $response->get_status() );
|
||||||
|
$this->assertEquals( 2, count( $reports ) );
|
||||||
|
|
||||||
|
$product_report = reset( $reports );
|
||||||
|
|
||||||
|
$this->assertEquals( $product->get_id(), $product_report['product_id'] );
|
||||||
|
$this->assertEquals( 4, $product_report['items_sold'] );
|
||||||
|
$this->assertEquals( 1, $product_report['orders_count'] );
|
||||||
|
$this->assertArrayHasKey( '_links', $product_report );
|
||||||
|
$this->assertArrayHasKey( 'product', $product_report['_links'] );
|
||||||
|
|
||||||
|
$product_report = next( $reports );
|
||||||
|
|
||||||
|
$this->assertEquals( $product_2->get_id(), $product_report['product_id'] );
|
||||||
|
$this->assertEquals( null, $product_report['items_sold'] );
|
||||||
|
$this->assertEquals( null, $product_report['orders_count'] );
|
||||||
|
$this->assertArrayHasKey( '_links', $product_report );
|
||||||
|
$this->assertArrayHasKey( 'product', $product_report['_links'] );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test getting reports without valid permissions.
|
* Test getting reports without valid permissions.
|
||||||
*
|
*
|
||||||
|
|
|
@ -112,6 +112,106 @@ class WC_Tests_API_Reports_Taxes extends WC_REST_Unit_Test_Case {
|
||||||
$this->assertEquals( 1, $tax_report['orders_count'] );
|
$this->assertEquals( 1, $tax_report['orders_count'] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test getting reports with the `taxes` report.
|
||||||
|
*
|
||||||
|
* @since 3.5.0
|
||||||
|
*/
|
||||||
|
public function test_get_reports_taxes_param() {
|
||||||
|
global $wpdb;
|
||||||
|
wp_set_current_user( $this->user );
|
||||||
|
WC_Helper_Reports::reset_stats_dbs();
|
||||||
|
|
||||||
|
// Populate all of the data.
|
||||||
|
$product = new WC_Product_Simple();
|
||||||
|
$product->set_name( 'Test Product' );
|
||||||
|
$product->set_regular_price( 25 );
|
||||||
|
$product->save();
|
||||||
|
|
||||||
|
$wpdb->insert(
|
||||||
|
$wpdb->prefix . 'woocommerce_tax_rates',
|
||||||
|
array(
|
||||||
|
'tax_rate_id' => 1,
|
||||||
|
'tax_rate' => '7',
|
||||||
|
'tax_rate_country' => 'US',
|
||||||
|
'tax_rate_state' => 'GA',
|
||||||
|
'tax_rate_name' => 'TestTax',
|
||||||
|
'tax_rate_priority' => 1,
|
||||||
|
'tax_rate_order' => 1,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$wpdb->insert(
|
||||||
|
$wpdb->prefix . 'woocommerce_tax_rates',
|
||||||
|
array(
|
||||||
|
'tax_rate_id' => 2,
|
||||||
|
'tax_rate' => '8',
|
||||||
|
'tax_rate_country' => 'CA',
|
||||||
|
'tax_rate_state' => 'ON',
|
||||||
|
'tax_rate_name' => 'TestTax 2',
|
||||||
|
'tax_rate_priority' => 1,
|
||||||
|
'tax_rate_order' => 1,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$order = WC_Helper_Order::create_order( 1, $product );
|
||||||
|
$order->set_status( 'completed' );
|
||||||
|
$order->set_total( 100 ); // $25 x 4.
|
||||||
|
$order->save();
|
||||||
|
|
||||||
|
// @todo Remove this once order data is synced to wc_order_tax_lookup
|
||||||
|
$wpdb->insert(
|
||||||
|
$wpdb->prefix . 'wc_order_tax_lookup',
|
||||||
|
array(
|
||||||
|
'order_id' => $order->get_id(),
|
||||||
|
'tax_rate_id' => 1,
|
||||||
|
'date_created' => date( 'Y-m-d H:i:s' ),
|
||||||
|
'shipping_tax' => 2,
|
||||||
|
'order_tax' => 5,
|
||||||
|
'total_tax' => 7,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
WC_Helper_Queue::run_all_pending();
|
||||||
|
|
||||||
|
$response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) );
|
||||||
|
$request = new WP_REST_Request( 'GET', $this->endpoint );
|
||||||
|
$request->set_query_params(
|
||||||
|
array(
|
||||||
|
'taxes' => '1,2',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$response = $this->server->dispatch( $request );
|
||||||
|
$reports = $response->get_data();
|
||||||
|
|
||||||
|
$this->assertEquals( 200, $response->get_status() );
|
||||||
|
$this->assertEquals( 2, count( $reports ) );
|
||||||
|
|
||||||
|
$tax_report = reset( $reports );
|
||||||
|
|
||||||
|
$this->assertEquals( 2, $tax_report['tax_rate_id'] );
|
||||||
|
$this->assertEquals( 'TestTax 2', $tax_report['name'] );
|
||||||
|
$this->assertEquals( 8, $tax_report['tax_rate'] );
|
||||||
|
$this->assertEquals( 'CA', $tax_report['country'] );
|
||||||
|
$this->assertEquals( 'ON', $tax_report['state'] );
|
||||||
|
$this->assertEquals( 0, $tax_report['total_tax'] );
|
||||||
|
$this->assertEquals( 0, $tax_report['order_tax'] );
|
||||||
|
$this->assertEquals( 0, $tax_report['shipping_tax'] );
|
||||||
|
$this->assertEquals( 0, $tax_report['orders_count'] );
|
||||||
|
|
||||||
|
$tax_report = next( $reports );
|
||||||
|
|
||||||
|
$this->assertEquals( 1, $tax_report['tax_rate_id'] );
|
||||||
|
$this->assertEquals( 'TestTax', $tax_report['name'] );
|
||||||
|
$this->assertEquals( 7, $tax_report['tax_rate'] );
|
||||||
|
$this->assertEquals( 'US', $tax_report['country'] );
|
||||||
|
$this->assertEquals( 'GA', $tax_report['state'] );
|
||||||
|
$this->assertEquals( 7, $tax_report['total_tax'] );
|
||||||
|
$this->assertEquals( 5, $tax_report['order_tax'] );
|
||||||
|
$this->assertEquals( 2, $tax_report['shipping_tax'] );
|
||||||
|
$this->assertEquals( 1, $tax_report['orders_count'] );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test getting reports without valid permissions.
|
* Test getting reports without valid permissions.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue