From 5e6529b36fadd5d9a284af281717ef55ee692c17 Mon Sep 17 00:00:00 2001 From: Tyler Karaszewski Date: Wed, 17 Dec 2025 18:23:41 -0800 Subject: [PATCH] Revert "Early return in isPayer function when policy does not exist" --- src/libs/ReportUtils.ts | 17 +++++------------ src/libs/actions/IOU.ts | 5 +++++ tests/actions/IOUTest.ts | 16 ++++++++++++++++ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 9de3de0196af5..6e85b52ef1734 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -2678,26 +2678,19 @@ 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; - - if (!policy) { - Log.warn('Missing policy during isPayer check'); - - return false; - } - - const policyType = policy.type; - const isAdmin = policyType !== CONST.POLICY.TYPE.PERSONAL && policy.role === CONST.POLICY.ROLE.ADMIN; + 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; + 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) { diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index f7a8c5c979552..fd11c989c5011 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -10851,6 +10851,10 @@ function canIOUBePaid( ); } +function canCancelPayment(iouReport: OnyxEntry, session: OnyxEntry) { + return isPayerReportUtils(session, iouReport) && (isSettled(iouReport) || iouReport?.isWaitingOnBankAccount) && isExpenseReport(iouReport); +} + function canSubmitReport( report: OnyxEntry, policy: OnyxEntry, @@ -15333,6 +15337,7 @@ export { canUnapproveIOU, cancelPayment, canIOUBePaid, + canCancelPayment, cleanUpMoneyRequest, clearMoneyRequest, completeSplitBill, diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 1f3fb2e94e3d5..ecfd374df0fff 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -16,6 +16,7 @@ import { approveMoneyRequest, calculateDiffAmount, canApproveIOU, + canCancelPayment, cancelPayment, canIOUBePaid, canUnapproveIOU, @@ -7000,6 +7001,21 @@ 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, + }; + expect(canCancelPayment(fakeReport, {accountID: RORY_ACCOUNT_ID})).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);