Commit dd0e513617d for woocommerce

commit dd0e513617dc4067f5c81484e72be43757229777
Author: Jan Lysý <lysyjan@users.noreply.github.com>
Date:   Thu Aug 6 15:58:49 2026 +0200

    Fix blank Date type selector in Analytics settings (#67423)

    * Fix blank Date type selector in Analytics settings

    * Add changelog entry for Analytics date type selector fix

diff --git a/plugins/woocommerce/changelog/fix-wooa7s-1589-date-type-selector-default b/plugins/woocommerce/changelog/fix-wooa7s-1589-date-type-selector-default
new file mode 100644
index 00000000000..f6326a18ce5
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-wooa7s-1589-date-type-selector-default
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Analytics: initialize the Date type selector in Analytics settings with the effective date_paid default instead of rendering blank when the option was never saved.
diff --git a/plugins/woocommerce/client/admin/client/analytics/settings/config.js b/plugins/woocommerce/client/admin/client/analytics/settings/config.js
index c2a3d40d349..1c4a65c0713 100644
--- a/plugins/woocommerce/client/admin/client/analytics/settings/config.js
+++ b/plugins/woocommerce/client/admin/client/analytics/settings/config.js
@@ -23,6 +23,7 @@ export const DEFAULT_ORDER_STATUSES = [
 	'on-hold',
 ];
 export const DEFAULT_DATE_RANGE = 'period=month&compare=previous_year';
+export const DEFAULT_DATE_TYPE = 'date_paid';
 export const SCHEDULED_IMPORT_SETTING_NAME =
 	'woocommerce_analytics_scheduled_import';

@@ -152,6 +153,7 @@ const baseConfig = {
 			'Database date field considered for Revenue and Orders reports',
 			'woocommerce'
 		),
+		defaultValue: DEFAULT_DATE_TYPE,
 	},
 };

diff --git a/plugins/woocommerce/client/admin/client/analytics/settings/test/date-type.test.js b/plugins/woocommerce/client/admin/client/analytics/settings/test/date-type.test.js
new file mode 100644
index 00000000000..dd4f4aed62b
--- /dev/null
+++ b/plugins/woocommerce/client/admin/client/analytics/settings/test/date-type.test.js
@@ -0,0 +1,82 @@
+/**
+ * External dependencies
+ */
+import { render, screen, fireEvent } from '@testing-library/react';
+import { useSettings } from '@woocommerce/data';
+
+/**
+ * Internal dependencies
+ */
+import Settings from '../index';
+import { config } from '../config';
+
+jest.mock( '@woocommerce/data', () => ( {
+	useSettings: jest.fn(),
+} ) );
+
+jest.mock( '@woocommerce/tracks', () => ( {
+	recordEvent: jest.fn(),
+} ) );
+
+jest.mock( '../historical-data', () => ( {
+	__esModule: true,
+	default: () => <div>Historical Data</div>,
+} ) );
+
+jest.mock( '../default-date', () => ( {
+	__esModule: true,
+	default: () => <div>Default Date</div>,
+} ) );
+
+describe( 'Analytics settings - date type', () => {
+	const mockUpdateAndPersistSettings = jest.fn();
+
+	beforeEach( () => {
+		jest.clearAllMocks();
+
+		useSettings.mockReturnValue( {
+			settingsError: false,
+			isRequesting: false,
+			isDirty: false,
+			persistSettings: jest.fn(),
+			updateAndPersistSettings: mockUpdateAndPersistSettings,
+			updateSettings: jest.fn(),
+			wcAdminSettings: {
+				woocommerce_date_type: 'date_completed',
+			},
+		} );
+	} );
+
+	afterEach( () => {
+		jest.restoreAllMocks();
+	} );
+
+	it( 'defines date_paid as the default value, matching reports behavior', () => {
+		expect( config.woocommerce_date_type.defaultValue ).toBe( 'date_paid' );
+	} );
+
+	it( 'renders the date type selector with the saved value', () => {
+		render( <Settings createNotice={ jest.fn() } query={ {} } /> );
+
+		expect( screen.getByRole( 'combobox' ) ).toHaveValue(
+			'date_completed'
+		);
+	} );
+
+	it( 'resets the date type to date_paid when resetting to defaults', () => {
+		jest.spyOn( window, 'confirm' ).mockReturnValue( true );
+
+		render( <Settings createNotice={ jest.fn() } query={ {} } /> );
+
+		fireEvent.click(
+			screen.getByRole( 'button', { name: /reset defaults/i } )
+		);
+
+		expect( mockUpdateAndPersistSettings ).toHaveBeenCalledWith(
+			'wcAdminSettings',
+			expect.objectContaining( {
+				woocommerce_date_type: 'date_paid',
+			} )
+		);
+	} );
+} );
diff --git a/plugins/woocommerce/src/Internal/Admin/Settings.php b/plugins/woocommerce/src/Internal/Admin/Settings.php
index 26ab01b4207..c70fdf98c06 100644
--- a/plugins/woocommerce/src/Internal/Admin/Settings.php
+++ b/plugins/woocommerce/src/Internal/Admin/Settings.php
@@ -352,6 +352,7 @@ class Settings {
 			'option_key'  => 'woocommerce_date_type',
 			'label'       => __( 'Date Type', 'woocommerce' ),
 			'description' => __( 'Database date field considered for Revenue and Orders reports', 'woocommerce' ),
+			'default'     => 'date_paid',
 			'type'        => 'select',
 			'options'     => array(
 				'date_created'   => 'date_created',
diff --git a/plugins/woocommerce/tests/php/src/Internal/Admin/SettingsTest.php b/plugins/woocommerce/tests/php/src/Internal/Admin/SettingsTest.php
new file mode 100644
index 00000000000..2dae4cf06d0
--- /dev/null
+++ b/plugins/woocommerce/tests/php/src/Internal/Admin/SettingsTest.php
@@ -0,0 +1,79 @@
+<?php
+declare( strict_types = 1 );
+
+namespace Automattic\WooCommerce\Tests\Internal\Admin;
+
+use Automattic\WooCommerce\Internal\Admin\Settings;
+use WC_REST_Setting_Options_Controller;
+use WC_Unit_Test_Case;
+
+/**
+ * Tests for the Settings class.
+ */
+class SettingsTest extends WC_Unit_Test_Case {
+
+	/**
+	 * @testdox Should register the date type setting with a 'date_paid' default, matching the reports data stores.
+	 */
+	public function test_date_type_setting_has_date_paid_default(): void {
+		$sut = new Settings();
+
+		$date_type = $this->get_setting_by_id( $sut->add_settings( array() ), 'woocommerce_date_type' );
+
+		$this->assertNotNull( $date_type, 'The woocommerce_date_type setting should be registered in the wc_admin group' );
+		$this->assertSame( 'date_paid', $date_type['default'] ?? null, 'The date type default should match the date_paid fallback used by the reports data stores' );
+	}
+
+	/**
+	 * @testdox Should resolve the date type value to 'date_paid' when the option has never been saved.
+	 */
+	public function test_date_type_value_falls_back_to_date_paid_when_option_is_unset(): void {
+		delete_option( 'woocommerce_date_type' );
+
+		$date_type = $this->get_setting_by_id( $this->get_wc_admin_group_settings(), 'woocommerce_date_type' );
+
+		$this->assertNotNull( $date_type, 'The woocommerce_date_type setting should be registered in the wc_admin group' );
+		$this->assertSame( 'date_paid', $date_type['value'], 'An unset date type option should resolve to the effective default, date_paid' );
+	}
+
+	/**
+	 * @testdox Should resolve the date type value to the saved option value when one exists.
+	 */
+	public function test_date_type_value_reflects_saved_option(): void {
+		update_option( 'woocommerce_date_type', 'date_completed' );
+
+		$date_type = $this->get_setting_by_id( $this->get_wc_admin_group_settings(), 'woocommerce_date_type' );
+
+		$this->assertNotNull( $date_type, 'The woocommerce_date_type setting should be registered in the wc_admin group' );
+		$this->assertSame( 'date_completed', $date_type['value'], 'A saved date type option should be reflected as the setting value' );
+	}
+
+	/**
+	 * Get the resolved wc_admin group settings via the REST settings controller.
+	 *
+	 * @return array
+	 */
+	private function get_wc_admin_group_settings(): array {
+		$settings = ( new WC_REST_Setting_Options_Controller() )->get_group_settings( 'wc_admin' );
+
+		$this->assertIsArray( $settings, 'The wc_admin settings group should resolve to an array of settings' );
+
+		return $settings;
+	}
+
+	/**
+	 * Find a setting by id in a list of settings.
+	 *
+	 * @param array  $settings List of setting definitions.
+	 * @param string $id       Setting id to look for.
+	 * @return array|null The first matching setting, or null if none matches.
+	 */
+	private function get_setting_by_id( array $settings, string $id ): ?array {
+		foreach ( $settings as $setting ) {
+			if ( ( $setting['id'] ?? '' ) === $id ) {
+				return $setting;
+			}
+		}
+		return null;
+	}
+}