From ca8522aece25fba97063337512408ed0c404137e Mon Sep 17 00:00:00 2001 From: wjames111 Date: Thu, 21 May 2026 13:39:34 -0400 Subject: [PATCH 1/3] Fix Credit Card Fees formula percent precision in PDS Goal Calculator The Support Item step's Credit Card Fees formula label rounded the configured fee rate to 0 decimals, showing "1%" instead of the actual 0.6% used in the calculation. Format the rate with 2 fraction digits so the help text matches the underlying math. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../SupportItem/otherBreakdown.test.tsx | 19 +++++++++++++++++++ .../SupportItem/otherBreakdown.tsx | 4 +++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/components/HrTools/PdsGoalCalculator/SupportItem/otherBreakdown.test.tsx b/src/components/HrTools/PdsGoalCalculator/SupportItem/otherBreakdown.test.tsx index 9ab4797f29..9b6332af2a 100644 --- a/src/components/HrTools/PdsGoalCalculator/SupportItem/otherBreakdown.test.tsx +++ b/src/components/HrTools/PdsGoalCalculator/SupportItem/otherBreakdown.test.tsx @@ -157,6 +157,25 @@ describe('buildOtherBreakdownRows', () => { ]); }); + it('renders the credit-card-fees formula with the configured fee rate, not a rounded percent', () => { + const fractionalRateConstants: OtherExpensesConstants = { + ...constants, + creditCardFeeRate: 0.006, + }; + + const rows = buildOtherBreakdownRows( + fullTimeCalculation, + fractionalRateConstants, + 'en-US', + i18n.t, + ); + + const creditCardFees = rows.find((row) => row.id === 'credit-card-fees'); + expect(creditCardFees?.formula).toBe( + '(Subtotal + Attrition) ÷ (1 - 0.60%) - (Subtotal + Attrition)', + ); + }); + it('uses a subtotal formula without reimbursable/403b in Simple form', () => { const simpleCalculation: OtherExpensesFields = { ...fullTimeCalculation, diff --git a/src/components/HrTools/PdsGoalCalculator/SupportItem/otherBreakdown.tsx b/src/components/HrTools/PdsGoalCalculator/SupportItem/otherBreakdown.tsx index 7ff1638eb7..2cb3db8a5d 100644 --- a/src/components/HrTools/PdsGoalCalculator/SupportItem/otherBreakdown.tsx +++ b/src/components/HrTools/PdsGoalCalculator/SupportItem/otherBreakdown.tsx @@ -119,7 +119,9 @@ export const buildOtherBreakdownRows = ( formula: t( '(Subtotal + Attrition) ÷ (1 - {{rate}}) - (Subtotal + Attrition)', { - rate: percentageFormat(constants.creditCardFeeRate, locale), + rate: percentageFormat(constants.creditCardFeeRate, locale, { + fractionDigits: 2, + }), }, ), amount: totals.creditCardFees, From e73f66a4871b2b27ab1a370a2599f863b2c10a50 Mon Sep 17 00:00:00 2001 From: wjames111 Date: Thu, 21 May 2026 14:39:08 -0400 Subject: [PATCH 2/3] Update code-review.md --- .claude/rules/code-review.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.claude/rules/code-review.md b/.claude/rules/code-review.md index 1784089238..20975de1bf 100644 --- a/.claude/rules/code-review.md +++ b/.claude/rules/code-review.md @@ -130,12 +130,13 @@ MPDX displays and calculates donation/partner-giving aggregations across dozens **Trigger conditions:** - Any file under `src/components/Reports/**` -- Any file under `src/components/Reports/GoalCalculator/**` or `src/components/Reports/PdsGoalCalculator/**` -- Any file under `src/components/Reports/SalaryCalculator/**` +- Any file under `src/components/HrTools/**` +- Any file under `src/components/Reports/GoalCalculator/**`, `src/components/HrTools/GoalCalculator/**`, or `src/components/HrTools/PdsGoalCalculator/**` +- Any file under `src/components/Reports/SalaryCalculator/**` or `src/components/HrTools/SalaryCalculator/**` - Any file under `src/components/EditDonationModal/**` -- Any file under `src/components/Reports/AdditionalSalaryRequest/**`, `src/components/Reports/MinisterHousingAllowance/**` +- Any file under `src/components/Reports/AdditionalSalaryRequest/**`, `src/components/HrTools/AdditionalSalaryRequest/**`, or `src/components/HrTools/MinisterHousingAllowance/**` - Any file under `src/components/Dashboard/MonthlyGoal/**`, `src/components/Dashboard/DonationHistories/**` -- Diff content contains any of: `amount`, `currency`, `convertedAmount`, `pledgeAmount`, `goal`, `balance`, `total`, `sum(`, `reduce((`, `.toFixed(`, `Math.round(`, `Number(`, `parseFloat(`, `parseInt(` inside `src/components/Reports/**` or goal/donation components +- Diff content contains any of: `amount`, `currency`, `convertedAmount`, `pledgeAmount`, `goal`, `balance`, `total`, `sum(`, `reduce((`, `.toFixed(`, `Math.round(`, `Number(`, `parseFloat(`, `parseInt(` inside `src/components/Reports/**`, `src/components/HrTools/**`, or other goal/donation components **Focus areas:** From 4cce426f558b3b7147f2b550b1b82dfed1b7515c Mon Sep 17 00:00:00 2001 From: wjames111 Date: Thu, 21 May 2026 14:39:35 -0400 Subject: [PATCH 3/3] Have assessment label match credit card fees --- .../SupportItem/otherBreakdown.test.tsx | 26 +++++++++++++++++++ .../SupportItem/otherBreakdown.tsx | 20 ++++++++++---- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/components/HrTools/PdsGoalCalculator/SupportItem/otherBreakdown.test.tsx b/src/components/HrTools/PdsGoalCalculator/SupportItem/otherBreakdown.test.tsx index 9b6332af2a..8616077cd5 100644 --- a/src/components/HrTools/PdsGoalCalculator/SupportItem/otherBreakdown.test.tsx +++ b/src/components/HrTools/PdsGoalCalculator/SupportItem/otherBreakdown.test.tsx @@ -176,6 +176,32 @@ describe('buildOtherBreakdownRows', () => { ); }); + it('renders the attrition formula with the rate as a decimal value', () => { + const rows = buildOtherBreakdownRows( + fullTimeCalculation, + { ...constants, attritionRate: 0.06 }, + 'en-US', + i18n.t, + ); + + const attrition = rows.find((row) => row.id === 'attrition'); + expect(attrition?.formula).toBe('Subtotal × 0.06%'); + }); + + it('renders the assessment formula with the admin rate as a decimal value', () => { + const rows = buildOtherBreakdownRows( + fullTimeCalculation, + { ...constants, adminRate: 0.12 }, + 'en-US', + i18n.t, + ); + + const assessment = rows.find((row) => row.id === 'assessment'); + expect(assessment?.formula).toBe( + '(Subtotal + Attrition + Credit Card Fees) ÷ (1 − 0.12%) − (Subtotal + Attrition + Credit Card Fees)', + ); + }); + it('uses a subtotal formula without reimbursable/403b in Simple form', () => { const simpleCalculation: OtherExpensesFields = { ...fullTimeCalculation, diff --git a/src/components/HrTools/PdsGoalCalculator/SupportItem/otherBreakdown.tsx b/src/components/HrTools/PdsGoalCalculator/SupportItem/otherBreakdown.tsx index 2cb3db8a5d..dcf92ed103 100644 --- a/src/components/HrTools/PdsGoalCalculator/SupportItem/otherBreakdown.tsx +++ b/src/components/HrTools/PdsGoalCalculator/SupportItem/otherBreakdown.tsx @@ -7,7 +7,11 @@ import { DesignationSupportFormType, DesignationSupportStatus, } from 'src/graphql/types.generated'; -import { currencyFormat, percentageFormat } from 'src/lib/intlFormat'; +import { + currencyFormat, + numberFormat, + percentageFormat, +} from 'src/lib/intlFormat'; import { OtherExpensesConstants, OtherExpensesFields, @@ -106,8 +110,11 @@ export const buildOtherBreakdownRows = ( { id: 'attrition', category: t('Attrition'), - formula: t('Subtotal × {{rate}}', { - rate: percentageFormat(constants.attritionRate, locale), + formula: t('Subtotal × {{rate}}%', { + rate: numberFormat(constants.attritionRate, locale, { + minimumFractionDigits: 2, + maximumFractionDigits: 4, + }), }), amount: totals.attrition, testId: 'other-attrition', @@ -132,9 +139,12 @@ export const buildOtherBreakdownRows = ( id: 'assessment', category: t('Assessment'), formula: t( - '(Subtotal + Attrition + Credit Card Fees) ÷ (1 − {{rate}}) − (Subtotal + Attrition + Credit Card Fees)', + '(Subtotal + Attrition + Credit Card Fees) ÷ (1 − {{rate}}%) − (Subtotal + Attrition + Credit Card Fees)', { - rate: percentageFormat(constants.adminRate, locale), + rate: numberFormat(constants.adminRate, locale, { + minimumFractionDigits: 2, + maximumFractionDigits: 4, + }), }, ), amount: totals.assessment,