Commit afbdcfa65e5 for woocommerce
commit afbdcfa65e529df362b6ded698ee04392764fdb3
Author: Jan Lysý <lysyjan@users.noreply.github.com>
Date: Fri Aug 14 07:46:46 2026 +0200
Restore Taxes report orders_count filter string, fix cache gap (#67679)
Restore filter-carried orders_count SQL and close add_option cache gap
Follow-up to #67553 addressing internal regression-review findings:
- Revert the orders_count parent_id qualification in both Taxes data
stores. The report_columns array is carried by the public
woocommerce_admin_report_columns filter, so the released unqualified
string is a contract for extension callbacks that inspect or rewrite
it. Unqualified parent_id is unambiguous on every query path since
wc_order_stats is the only joined table carrying that column and the
join is now unconditional.
- Also hook add_option_woocommerce_date_type for report cache
invalidation: the first-ever save of the option takes the add_option
path, where the update_option hook never fires.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
diff --git a/plugins/woocommerce/changelog/fix-wooairr-48-taxes-report-columns-bc b/plugins/woocommerce/changelog/fix-wooairr-48-taxes-report-columns-bc
new file mode 100644
index 00000000000..40b9a685706
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-wooairr-48-taxes-report-columns-bc
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Analytics: restore the released unqualified parent_id form of the Taxes orders_count column carried by the woocommerce_admin_report_columns filter, and invalidate report caches on the first-ever save of the analytics date type.
diff --git a/plugins/woocommerce/src/Admin/API/Reports/Taxes/DataStore.php b/plugins/woocommerce/src/Admin/API/Reports/Taxes/DataStore.php
index d2a9f6752e9..34c78c974ac 100644
--- a/plugins/woocommerce/src/Admin/API/Reports/Taxes/DataStore.php
+++ b/plugins/woocommerce/src/Admin/API/Reports/Taxes/DataStore.php
@@ -87,8 +87,7 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
*/
protected function assign_report_columns() {
global $wpdb;
- $table_name = self::get_db_table_name();
- $order_stats_table = $wpdb->prefix . 'wc_order_stats';
+ $table_name = self::get_db_table_name();
// Using wp_woocommerce_tax_rates table limits the result to only the existing tax rates and
// omits the historical records which differs from the purpose of wp_wc_order_tax_lookup table.
@@ -108,8 +107,10 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
'total_tax' => 'SUM(total_tax) as total_tax',
'order_tax' => 'SUM(order_tax) as order_tax',
'shipping_tax' => 'SUM(shipping_tax) as shipping_tax',
- // parent_id is qualified to wc_order_stats to stay unambiguous now that the join is always present.
- 'orders_count' => "COUNT( DISTINCT ( CASE WHEN {$order_stats_table}.parent_id = 0 THEN {$table_name}.order_id END ) ) as orders_count",
+ // parent_id stays unqualified: wc_order_stats is the only joined table carrying it, and
+ // this string is carried by the public woocommerce_admin_report_columns filter, so it must
+ // match the released form for extension callbacks that inspect or rewrite it.
+ 'orders_count' => "COUNT( DISTINCT ( CASE WHEN parent_id = 0 THEN {$table_name}.order_id END ) ) as orders_count",
);
}
diff --git a/plugins/woocommerce/src/Admin/API/Reports/Taxes/Stats/DataStore.php b/plugins/woocommerce/src/Admin/API/Reports/Taxes/Stats/DataStore.php
index ca82185bd1f..f1c15045b6a 100644
--- a/plugins/woocommerce/src/Admin/API/Reports/Taxes/Stats/DataStore.php
+++ b/plugins/woocommerce/src/Admin/API/Reports/Taxes/Stats/DataStore.php
@@ -81,16 +81,16 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
* @override ReportsDataStore::assign_report_columns()
*/
protected function assign_report_columns() {
- global $wpdb;
$table_name = self::get_db_table_name();
- $order_stats_table = $wpdb->prefix . 'wc_order_stats';
$this->report_columns = array(
'tax_codes' => 'COUNT(DISTINCT tax_rate_id) as tax_codes',
'total_tax' => 'SUM(total_tax) AS total_tax',
'order_tax' => 'SUM(order_tax) as order_tax',
'shipping_tax' => 'SUM(shipping_tax) as shipping_tax',
- // parent_id is qualified to wc_order_stats to stay unambiguous now that the join is always present.
- 'orders_count' => "COUNT( DISTINCT ( CASE WHEN {$order_stats_table}.parent_id = 0 THEN {$table_name}.order_id END ) ) as orders_count",
+ // parent_id stays unqualified: wc_order_stats is the only joined table carrying it, and
+ // this string is carried by the public woocommerce_admin_report_columns filter, so it must
+ // match the released form for extension callbacks that inspect or rewrite it.
+ 'orders_count' => "COUNT( DISTINCT ( CASE WHEN parent_id = 0 THEN {$table_name}.order_id END ) ) as orders_count",
);
}
diff --git a/plugins/woocommerce/src/Admin/ReportsSync.php b/plugins/woocommerce/src/Admin/ReportsSync.php
index 7ef88d05b1a..9b96649b0b3 100644
--- a/plugins/woocommerce/src/Admin/ReportsSync.php
+++ b/plugins/woocommerce/src/Admin/ReportsSync.php
@@ -30,6 +30,8 @@ class ReportsSync {
add_action( 'update_option_woocommerce_notify_no_stock_amount', array( __CLASS__, 'clear_stock_count_cache' ) );
// Invalidate report caches when the analytics date type changes, so all report families
// (Orders, Revenue, Taxes) reflect the new date basis immediately instead of after the cache TTL.
+ // The very first save of the option takes the add_option path, so hook both.
+ add_action( 'add_option_woocommerce_date_type', array( ReportsCache::class, 'invalidate' ) );
add_action( 'update_option_woocommerce_date_type', array( ReportsCache::class, 'invalidate' ) );
add_action( 'trashed_post', array( __CLASS__, 'maybe_clear_stock_count_cache_for_post' ) );
add_action( 'untrashed_post', array( __CLASS__, 'maybe_clear_stock_count_cache_for_post' ) );
diff --git a/plugins/woocommerce/tests/php/src/Admin/API/Reports/Taxes/DataStoreTest.php b/plugins/woocommerce/tests/php/src/Admin/API/Reports/Taxes/DataStoreTest.php
index afb9291b37d..22f2a6cea9f 100644
--- a/plugins/woocommerce/tests/php/src/Admin/API/Reports/Taxes/DataStoreTest.php
+++ b/plugins/woocommerce/tests/php/src/Admin/API/Reports/Taxes/DataStoreTest.php
@@ -290,6 +290,10 @@ class DataStoreTest extends WC_Unit_Test_Case {
has_action( 'update_option_woocommerce_date_type', array( ReportsCache::class, 'invalidate' ) ),
'Changing the analytics date type should invalidate the report cache so all report families reflect the new basis immediately.'
);
+ $this->assertNotFalse(
+ has_action( 'add_option_woocommerce_date_type', array( ReportsCache::class, 'invalidate' ) ),
+ 'The very first save of the date type takes the add_option path and should invalidate the report cache too.'
+ );
}
/**