Commit c98203a8046 for woocommerce
commit c98203a80462f4d8e60510fb5cf5548b5be9e749
Author: Justin P <228780+layoutd@users.noreply.github.com>
Date: Thu Sep 24 17:33:15 2026 +0200
Show extension coupon discount type labels in the Analytics Coupons report (#68705)
* Show extension coupon discount type labels in the Analytics Coupons report
* Add tests for coupon discount type labels in Analytics
diff --git a/plugins/woocommerce/changelog/35667-analytics-coupon-custom-discount-types b/plugins/woocommerce/changelog/35667-analytics-coupon-custom-discount-types
new file mode 100644
index 00000000000..2963bcf34df
--- /dev/null
+++ b/plugins/woocommerce/changelog/35667-analytics-coupon-custom-discount-types
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Show the labels of coupon discount types added by extensions in the Analytics Coupons report instead of N/A.
diff --git a/plugins/woocommerce/client/admin/client/analytics/report/coupons/table.js b/plugins/woocommerce/client/admin/client/analytics/report/coupons/table.js
index d1f9bdfd6f5..2fc06266bbd 100644
--- a/plugins/woocommerce/client/admin/client/analytics/report/coupons/table.js
+++ b/plugins/woocommerce/client/admin/client/analytics/report/coupons/table.js
@@ -195,7 +195,9 @@ class CouponsReportTable extends Component {
}
getCouponType( discountType ) {
+ // Extension types use their wc_get_coupon_types() label; core types keep the shorter labels below.
const couponTypes = {
+ ...getAdminSetting( 'couponTypes', {} ),
percent: __( 'Percentage', 'woocommerce' ),
fixed_cart: __( 'Fixed cart', 'woocommerce' ),
fixed_product: __( 'Fixed product', 'woocommerce' ),
diff --git a/plugins/woocommerce/client/admin/client/analytics/report/coupons/test/table.test.js b/plugins/woocommerce/client/admin/client/analytics/report/coupons/test/table.test.js
new file mode 100644
index 00000000000..fd9256b6f45
--- /dev/null
+++ b/plugins/woocommerce/client/admin/client/analytics/report/coupons/test/table.test.js
@@ -0,0 +1,42 @@
+/**
+ * Internal dependencies
+ */
+import CouponsReportTable from '../table';
+
+const mockAdminSettings = {};
+
+jest.mock( '~/utils/admin-settings', () => ( {
+ getAdminSetting: ( key, fallback ) => mockAdminSettings[ key ] ?? fallback,
+} ) );
+
+describe( 'CouponsReportTable getCouponType', () => {
+ const table = new CouponsReportTable();
+
+ beforeEach( () => {
+ mockAdminSettings.couponTypes = {
+ percent: 'Percentage discount',
+ custom_type: 'Custom discount',
+ };
+ } );
+
+ it( 'keeps the core label for a built-in discount type', () => {
+ expect( table.getCouponType( 'percent' ) ).toBe( 'Percentage' );
+ } );
+
+ it( 'uses the admin setting label for a discount type added by an extension', () => {
+ expect( table.getCouponType( 'custom_type' ) ).toBe(
+ 'Custom discount'
+ );
+ } );
+
+ it( 'returns N/A for a discount type without a label', () => {
+ expect( table.getCouponType( 'unknown_type' ) ).toBe( 'N/A' );
+ } );
+
+ it( 'falls back to the core labels when the admin setting is missing', () => {
+ delete mockAdminSettings.couponTypes;
+
+ expect( table.getCouponType( 'fixed_cart' ) ).toBe( 'Fixed cart' );
+ expect( table.getCouponType( 'custom_type' ) ).toBe( 'N/A' );
+ } );
+} );
diff --git a/plugins/woocommerce/src/Internal/Admin/Settings.php b/plugins/woocommerce/src/Internal/Admin/Settings.php
index f17e43bd3c4..188022dfd23 100644
--- a/plugins/woocommerce/src/Internal/Admin/Settings.php
+++ b/plugins/woocommerce/src/Internal/Admin/Settings.php
@@ -339,6 +339,7 @@ class Settings {
// E.g. an extension that added statuses is now inactive or removed.
$settings['unregisteredOrderStatuses'] = $this->get_unregistered_order_statuses();
$settings['usesNewFullRefundData'] = OrderUtil::uses_new_full_refund_data();
+ $settings['couponTypes'] = wc_get_coupon_types();
}
// The separator used for attributes found in Variation titles.
diff --git a/plugins/woocommerce/tests/php/src/Internal/Admin/SettingsTest.php b/plugins/woocommerce/tests/php/src/Internal/Admin/SettingsTest.php
index 497bb389cef..7869126a13e 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Admin/SettingsTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Admin/SettingsTest.php
@@ -289,6 +289,30 @@ class SettingsTest extends WC_Unit_Test_Case {
$this->assertSame( array(), Settings::get_default_excluded_order_statuses(), 'The UI and runtime consumers should agree.' );
}
+ /**
+ * @testdox The preloaded component settings expose coupon discount types, including ones added by extensions.
+ */
+ public function test_component_settings_expose_coupon_types(): void {
+ $add_type = function ( $types ) {
+ $types['custom_discount'] = 'Custom discount';
+ return $types;
+ };
+ add_filter( 'woocommerce_coupon_discount_types', $add_type );
+ $this->added_filters[] = array( 'woocommerce_coupon_discount_types', $add_type );
+ // Coupon types are only injected on wc-admin pages; the base tearDown unsets the current screen.
+ set_current_screen( 'dashboard' );
+ $_GET['page'] = 'wc-admin'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+
+ try {
+ $settings = $this->sut->add_component_settings( array() );
+ } finally {
+ unset( $_GET['page'] );
+ }
+
+ $this->assertSame( 'Custom discount', $settings['couponTypes']['custom_discount'] ?? null, 'A discount type added through the filter should reach the client.' );
+ $this->assertArrayHasKey( 'percent', $settings['couponTypes'], 'Core discount types should still be included.' );
+ }
+
/**
* Get the resolved wc_admin group settings via the REST settings controller.
*