Commit a11b1ac55da for woocommerce
commit a11b1ac55dab262e94b9f0a35171520299759bc9
Author: Jorge A. Torres <jorge.torres@automattic.com>
Date: Wed Aug 19 10:34:39 2026 +0100
Fix `has_orders_pending_sync()` false negative after a full sync (#67830)
diff --git a/plugins/woocommerce/changelog/fix-hpos-sync-pending-null-count b/plugins/woocommerce/changelog/fix-hpos-sync-pending-null-count
new file mode 100644
index 00000000000..54066aae3bb
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-hpos-sync-pending-null-count
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix has_orders_pending_sync() incorrectly returning false when an order changes after a full HPOS backfill
diff --git a/plugins/woocommerce/src/Internal/DataStores/Orders/DataSynchronizer.php b/plugins/woocommerce/src/Internal/DataStores/Orders/DataSynchronizer.php
index 00c368cd093..43d5bb047fd 100644
--- a/plugins/woocommerce/src/Internal/DataStores/Orders/DataSynchronizer.php
+++ b/plugins/woocommerce/src/Internal/DataStores/Orders/DataSynchronizer.php
@@ -592,7 +592,7 @@ $limit_clause",
$sql = $wpdb->prepare(
"
SELECT(
- ($missing_orders_count_sql)
+ COALESCE(($missing_orders_count_sql), 0)
+
(SELECT COUNT(1) FROM (
SELECT orders.id FROM $orders_table orders
diff --git a/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/DataSynchronizerTests.php b/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/DataSynchronizerTests.php
index b2a191b44fe..35c7ebb770e 100644
--- a/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/DataSynchronizerTests.php
+++ b/plugins/woocommerce/tests/php/src/Internal/DataStores/Orders/DataSynchronizerTests.php
@@ -150,6 +150,24 @@ class DataSynchronizerTests extends \HposTestCase {
$this->assertFalse( $this->sut->has_orders_pending_sync() );
}
+ /**
+ * @testDox An order edited after a full backfill is still detected as pending sync.
+ */
+ public function test_has_orders_pending_sync_detects_stale_order_after_backfill_with_no_missing_orders() {
+ update_option( CustomOrdersTableController::CUSTOM_ORDERS_TABLE_USAGE_ENABLED_OPTION, 'yes' );
+ update_option( $this->sut::ORDERS_DATA_SYNC_ENABLED_OPTION, 'no' );
+
+ $order = OrderHelper::create_complex_data_store_order();
+ $this->sut->process_batch( array( $order->get_id() ) );
+ $this->assertFalse( $this->sut->has_orders_pending_sync(), 'No orders should be pending sync right after a full backfill.' );
+
+ $order->set_date_modified( time() + 1000 );
+ $order->save();
+
+ $this->assertTrue( $this->sut->has_orders_pending_sync() );
+ $this->assertEquals( 1, $this->sut->get_current_orders_pending_sync_count() );
+ }
+
/**
* When the CPT data store is authoritative, and an order is updated, we should propagate those changes to
* the COT store immediately (rather than wait for sync to catch up). This guards against a situation where