From a2b5e83c1f4046dc8e3be31ebbc7c9859b6e1865 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Tue, 2 Dec 2025 15:07:36 +0430 Subject: [PATCH 1/6] early return in isPayer function when policy does not exits --- src/libs/ReportUtils.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 5ce0be6833cd2..56637ecea9e0d 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -2645,6 +2645,10 @@ function isPayer(session: OnyxEntry, iouReport: OnyxEntry, only const isManager = iouReport?.managerID === session?.accountID; const reimbursementChoice = policy?.reimbursementChoice; + if (!policy) { + return false; + } + if (isPaidGroupPolicy(iouReport)) { if (reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES) { if (!policy?.achAccount?.reimburser) { From ea935af4085455cbfda91412044403137b7348b0 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Tue, 2 Dec 2025 16:13:08 +0430 Subject: [PATCH 2/6] added fakePolicy to canCancelPayment unit test to assume policy exist --- src/libs/actions/IOU.ts | 4 ++-- tests/actions/IOUTest.ts | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 1bb9173790934..48008567276d0 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -10531,8 +10531,8 @@ function canIOUBePaid( ); } -function canCancelPayment(iouReport: OnyxEntry, session: OnyxEntry) { - return isPayerReportUtils(session, iouReport) && (isSettled(iouReport) || iouReport?.isWaitingOnBankAccount) && isExpenseReport(iouReport); +function canCancelPayment(iouReport: OnyxEntry, session: OnyxEntry, reportPolicy?: OnyxTypes.OnyxInputOrEntry) { + return isPayerReportUtils(session, iouReport, false, reportPolicy) && (isSettled(iouReport) || iouReport?.isWaitingOnBankAccount) && isExpenseReport(iouReport); } function canSubmitReport( diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index a35380587c4dd..435e8ade1164d 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -6660,7 +6660,13 @@ describe('actions/IOU', () => { isWaitingOnBankAccount: true, managerID: RORY_ACCOUNT_ID, }; - expect(canCancelPayment(fakeReport, {accountID: RORY_ACCOUNT_ID})).toBeTruthy(); + + const fakePolicy: Policy = { + ...createRandomPolicy(Number('A')), + id: 'A', + }; + + expect(canCancelPayment(fakeReport, {accountID: RORY_ACCOUNT_ID}, fakePolicy)).toBeTruthy(); }); }); From e5a1b33a4b75976e5f6a1841b09a4427197f7960 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Thu, 4 Dec 2025 11:59:07 +0430 Subject: [PATCH 3/6] applied bot feedback --- src/libs/ReportUtils.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 58ef60bff868d..5accab77de1a8 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -2641,23 +2641,24 @@ function isOneOnOneChat(report: OnyxEntry): boolean { function isPayer(session: OnyxEntry, iouReport: OnyxEntry, onlyShowPayElsewhere = false, reportPolicy?: OnyxInputOrEntry) { const policy = reportPolicy ?? allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${iouReport?.policyID}`] ?? null; - const policyType = policy?.type; - const isAdmin = policyType !== CONST.POLICY.TYPE.PERSONAL && policy?.role === CONST.POLICY.ROLE.ADMIN; - const isManager = iouReport?.managerID === session?.accountID; - const reimbursementChoice = policy?.reimbursementChoice; if (!policy) { return false; } + const policyType = policy.type; + const isAdmin = policyType !== CONST.POLICY.TYPE.PERSONAL && policy.role === CONST.POLICY.ROLE.ADMIN; + const isManager = iouReport?.managerID === session?.accountID; + const reimbursementChoice = policy.reimbursementChoice; + if (isPaidGroupPolicy(iouReport)) { if (reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES) { - if (!policy?.achAccount?.reimburser) { + if (!policy.achAccount?.reimburser) { return isAdmin; } // If we are the reimburser and the report is approved or we are the manager then we can pay it. - const isReimburser = session?.email === policy?.achAccount?.reimburser; + const isReimburser = session?.email === policy.achAccount?.reimburser; return isReimburser; } if (reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL || onlyShowPayElsewhere) { From 248836cdb93b37d7b79fa31fd10e2e9b350a96aa Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Tue, 9 Dec 2025 22:01:39 +0430 Subject: [PATCH 4/6] remove redundant code --- src/libs/actions/IOU.ts | 5 ----- tests/actions/IOUTest.ts | 22 ---------------------- 2 files changed, 27 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 6d8b4c0822bd3..90cbff881c432 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -10594,10 +10594,6 @@ function canIOUBePaid( ); } -function canCancelPayment(iouReport: OnyxEntry, session: OnyxEntry, reportPolicy?: OnyxTypes.OnyxInputOrEntry) { - return isPayerReportUtils(session, iouReport, false, reportPolicy) && (isSettled(iouReport) || iouReport?.isWaitingOnBankAccount) && isExpenseReport(iouReport); -} - function canSubmitReport( report: OnyxEntry, policy: OnyxEntry, @@ -15072,7 +15068,6 @@ export { canUnapproveIOU, cancelPayment, canIOUBePaid, - canCancelPayment, cleanUpMoneyRequest, clearMoneyRequest, completeSplitBill, diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 9b0f7bdf66c9e..722ccd41f6815 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -16,7 +16,6 @@ import { approveMoneyRequest, calculateDiffAmount, canApproveIOU, - canCancelPayment, cancelPayment, canIOUBePaid, canUnapproveIOU, @@ -6869,27 +6868,6 @@ describe('actions/IOU', () => { }); }); - describe('canCancelPayment', () => { - it('should return true if the report is waiting for a bank account', () => { - const fakeReport: Report = { - ...createRandomReport(1, undefined), - type: CONST.REPORT.TYPE.EXPENSE, - policyID: 'A', - stateNum: CONST.REPORT.STATE_NUM.APPROVED, - statusNum: CONST.REPORT.STATUS_NUM.APPROVED, - isWaitingOnBankAccount: true, - managerID: RORY_ACCOUNT_ID, - }; - - const fakePolicy: Policy = { - ...createRandomPolicy(Number('A')), - id: 'A', - }; - - expect(canCancelPayment(fakeReport, {accountID: RORY_ACCOUNT_ID}, fakePolicy)).toBeTruthy(); - }); - }); - describe('canIOUBePaid', () => { it('should return false if the report has negative total and onlyShowPayElsewhere is false', async () => { const policyChat = createRandomReport(1, CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT); From bcaabb1a8f9899cef7edee0dcd2621817b502b84 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Thu, 11 Dec 2025 09:31:38 +0430 Subject: [PATCH 5/6] put a warn before early return --- src/libs/ReportUtils.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 025d1f5bf9c28..3938867458984 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -2644,6 +2644,8 @@ function isPayer(session: OnyxEntry, iouReport: OnyxEntry, only const policy = reportPolicy ?? allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${iouReport?.policyID}`] ?? null; if (!policy) { + Log.warn('Missing transactionID during the change of the money request hold status'); + return false; } From 08bc373423c8a3707cb435fb47aa95aaed2336a0 Mon Sep 17 00:00:00 2001 From: Maruf Sharifi Date: Fri, 12 Dec 2025 15:27:23 +0430 Subject: [PATCH 6/6] refined warning message --- src/libs/ReportUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 3938867458984..622ac433b953c 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -2644,7 +2644,7 @@ function isPayer(session: OnyxEntry, iouReport: OnyxEntry, only const policy = reportPolicy ?? allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${iouReport?.policyID}`] ?? null; if (!policy) { - Log.warn('Missing transactionID during the change of the money request hold status'); + Log.warn('Missing policy during isPayer check'); return false; }