Commit fcf6887dbd2 for woocommerce
commit fcf6887dbd24199603ac5549277f9e872463c2b0
Author: Jan Lysý <lysyjan@users.noreply.github.com>
Date: Tue Aug 11 13:30:40 2026 +0200
Fix Analytics revenue % change when previous period is negative (#67490)
* Fix calculateDelta wrong sign when baseline revenue is negative
* Add changelog entry for negative-baseline calculateDelta fix
* Improve calculateDelta secondaryValue param doc wording
diff --git a/packages/js/number/changelog/wooplug-2965-negative-baseline-delta b/packages/js/number/changelog/wooplug-2965-negative-baseline-delta
new file mode 100644
index 00000000000..07d05f9407b
--- /dev/null
+++ b/packages/js/number/changelog/wooplug-2965-negative-baseline-delta
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix calculateDelta returning the wrong sign when the baseline is negative by dividing by the absolute value of the baseline (#54303).
diff --git a/packages/js/number/src/index.ts b/packages/js/number/src/index.ts
index c31b813a62c..cc389dfdcb7 100644
--- a/packages/js/number/src/index.ts
+++ b/packages/js/number/src/index.ts
@@ -91,7 +91,7 @@ export function formatValue(
* Calculates the delta/percentage change between two numbers.
*
* @param {number} primaryValue the value to calculate change for.
- * @param {number} secondaryValue the baseline which to calculdate the change against.
+ * @param {number} secondaryValue the baseline against which to calculate the change.
* @return {?number} Percent change between the primaryValue from the secondaryValue.
*/
export function calculateDelta( primaryValue: number, secondaryValue: number ) {
@@ -107,7 +107,7 @@ export function calculateDelta( primaryValue: number, secondaryValue: number ) {
}
return Math.round(
- ( ( primaryValue - secondaryValue ) / secondaryValue ) * 100
+ ( ( primaryValue - secondaryValue ) / Math.abs( secondaryValue ) ) * 100
);
}
diff --git a/packages/js/number/src/test/index.ts b/packages/js/number/src/test/index.ts
index f2db08195dc..fdc5141a86b 100644
--- a/packages/js/number/src/test/index.ts
+++ b/packages/js/number/src/test/index.ts
@@ -6,7 +6,7 @@ import { partial } from 'lodash';
/**
* Internal dependencies
*/
-import { numberFormat, parseNumber } from '../index';
+import { numberFormat, parseNumber, calculateDelta } from '../index';
const defaultNumberFormat = partial( numberFormat, {} );
@@ -49,6 +49,41 @@ describe( 'numberFormat', () => {
} );
} );
+describe( 'calculateDelta', () => {
+ it( 'returns a positive change when a negative baseline grows to a positive value', () => {
+ // From WOOPLUG-2965: $-755.90 → $480 is an increase, not a decrease.
+ expect( calculateDelta( 480, -755.9 ) ).toBe( 164 );
+ } );
+
+ it( 'calculates the change between two positive values', () => {
+ expect( calculateDelta( 1202.6, 685.6 ) ).toBe( 75 );
+ } );
+
+ it( 'calculates a decrease between two positive values', () => {
+ // A positive baseline is unaffected by the fix; the sign must stay negative.
+ expect( calculateDelta( 685.6, 1202.6 ) ).toBe( -43 );
+ } );
+
+ it( 'calculates the change between two negative values', () => {
+ // -450 → -900 is a further decline of 100%.
+ expect( calculateDelta( -900, -450 ) ).toBe( -100 );
+ } );
+
+ it( 'returns 0 when the baseline is 0', () => {
+ expect( calculateDelta( 480, 0 ) ).toBe( 0 );
+ } );
+
+ it( 'reports a full recovery from a negative baseline to break-even', () => {
+ // -500 → 0 is a 100% recovery of the loss.
+ expect( calculateDelta( 0, -500 ) ).toBe( 100 );
+ } );
+
+ it( 'returns null when either value is not finite', () => {
+ expect( calculateDelta( NaN, 100 ) ).toBeNull();
+ expect( calculateDelta( 100, Infinity ) ).toBeNull();
+ } );
+} );
+
describe( 'parseNumber', () => {
it( 'should remove thousand separator before parsing number', () => {
const config = {