Commit 8d7a4921692 for woocommerce

commit 8d7a49216921305821c580184ea67396a47de4b9
Author: Peter Petrov <peter.petrov89@gmail.com>
Date:   Tue Sep 8 16:17:40 2026 +0300

    Fix Taxes report counting placeholder tax entries as taxable amount (#68468)

    * Ignore placeholder tax entries when computing taxable amounts

    * Skip non-numeric tax values in the non-compound pre-sum

diff --git a/plugins/woocommerce/src/Admin/API/Reports/Taxes/DataStore.php b/plugins/woocommerce/src/Admin/API/Reports/Taxes/DataStore.php
index a320f607e68..7bed1a044ed 100644
--- a/plugins/woocommerce/src/Admin/API/Reports/Taxes/DataStore.php
+++ b/plugins/woocommerce/src/Admin/API/Reports/Taxes/DataStore.php
@@ -690,7 +690,7 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {

 			$non_compound_tax = 0.0;
 			foreach ( $taxes['total'] as $rate_id => $tax ) {
-				if ( ! in_array( (int) $rate_id, $compound_rate_ids, true ) ) {
+				if ( is_numeric( $tax ) && ! in_array( (int) $rate_id, $compound_rate_ids, true ) ) {
 					$non_compound_tax += (float) $tax;
 				}
 			}
@@ -702,6 +702,12 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
 			// only mis-split the base between multiple compound rates, not the total.
 			$compound_running_tax = 0.0;
 			foreach ( $taxes['total'] as $rate_id => $tax ) {
+				// Admin saves without recalculating store '' for rates that never applied
+				// to the item. Numeric zero still counts (zero-rated sales).
+				if ( ! is_numeric( $tax ) ) {
+					continue;
+				}
+
 				$base = (float) $item->get_total();
 				if ( in_array( (int) $rate_id, $compound_rate_ids, true ) ) {
 					$base                 += $non_compound_tax + $compound_running_tax;
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 1e8b912917c..38f30eb211f 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
@@ -557,6 +557,45 @@ class DataStoreTest extends WC_Unit_Test_Case {
 		$this->assertSame( 0.0, (float) $lookup_row->taxable_amount, 'A tax line applied to no order item should record a zero taxable amount.' );
 	}

+	/**
+	 * @testdox An admin order save that leaves empty tax placeholders on items records no base for that rate.
+	 */
+	public function test_sync_order_taxes_ignores_placeholder_tax_entries(): void {
+		global $wpdb;
+		WC_Helper_Reports::reset_stats_dbs();
+
+		$rate_id       = $this->insert_tax_rate();
+		$other_rate_id = $this->insert_tax_rate( '7', 2 );
+		$order         = $this->create_taxed_de_order();
+
+		// An admin save without recalculating stores '' for rates that never applied to the
+		// item. Blank the second rate on the fee and shipping only, so its base must come
+		// from the product line alone.
+		foreach ( $order->get_items( array( OrderItemType::FEE, OrderItemType::SHIPPING ) ) as $item ) {
+			$taxes                            = $item->get_taxes();
+			$taxes['total'][ $other_rate_id ] = '';
+			if ( isset( $taxes['subtotal'] ) ) {
+				$taxes['subtotal'][ $other_rate_id ] = '';
+			}
+			$item->set_taxes( $taxes );
+			$item->save();
+		}
+		$order->update_taxes();
+		$order->save();
+
+		DataStore::sync_order_taxes( $order->get_id() );
+
+		$amounts = $wpdb->get_results(
+			$wpdb->prepare(
+				"SELECT tax_rate_id, taxable_amount FROM {$wpdb->prefix}wc_order_tax_lookup WHERE order_id = %d",
+				$order->get_id()
+			),
+			OBJECT_K
+		);
+		$this->assertSame( 200.0, (float) $amounts[ $other_rate_id ]->taxable_amount, 'Placeholder entries must not add the fee and shipping totals to the rate.' );
+		$this->assertSame( 215.0, (float) $amounts[ $rate_id ]->taxable_amount, 'The rate without placeholders must keep its full base.' );
+	}
+
 	/**
 	 * @testdox Syncing an order records the base of a compound tax rate including the taxes it compounds over.
 	 */