diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index aa27dbaa0ce41..c6b5d0691d7c1 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -547,8 +547,7 @@ function getAction(data: OnyxTypes.SearchResults['data'], key: string): SearchTr const hasOnlyPendingCardOrScanningTransactions = allReportTransactions.length > 0 && allReportTransactions.every(isPendingCardOrScanningTransaction); const isAllowedToApproveExpenseReport = isAllowedToApproveExpenseReportUtils(report, undefined, policy); - - if (canApproveIOU(report, policy) && isAllowedToApproveExpenseReport && !hasOnlyPendingCardOrScanningTransactions) { + if (canApproveIOU(report, policy, allReportTransactions) && isAllowedToApproveExpenseReport && !hasOnlyPendingCardOrScanningTransactions) { return CONST.SEARCH.ACTION_TYPES.APPROVE; } diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index d7fe7dc36a7dd..bc2837ed81dc4 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -9133,8 +9133,7 @@ function canIOUBePaid( const {reimbursableSpend} = getMoneyRequestSpendBreakdown(iouReport); const isAutoReimbursable = policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES ? false : canBeAutoReimbursed(iouReport, policy); - const shouldBeApproved = canApproveIOU(iouReport, policy); - + const shouldBeApproved = canApproveIOU(iouReport, policy, transactions); const isPayAtEndExpenseReport = isPayAtEndExpenseReportReportUtils(iouReport?.reportID, transactions); return ( isPayer && diff --git a/tests/unit/Search/SearchUIUtilsTest.ts b/tests/unit/Search/SearchUIUtilsTest.ts index 10d49770c3998..b43a8a7cf7df3 100644 --- a/tests/unit/Search/SearchUIUtilsTest.ts +++ b/tests/unit/Search/SearchUIUtilsTest.ts @@ -995,6 +995,133 @@ describe('SearchUIUtils', () => { }); }); + test('Should show `Approve` for report', () => { + Onyx.merge(ONYXKEYS.SESSION, {accountID: adminAccountID}); + + const result: OnyxTypes.SearchResults = { + data: { + personalDetailsList: { + adminAccountID: { + accountID: adminAccountID, + avatar: 'https://d1wpcgnaa73g0y.cloudfront.net/fake.jpeg', + displayName: 'You', + login: 'you@expensifail.com', + }, + // eslint-disable-next-line @typescript-eslint/naming-convention + '2074551': { + accountID: 2074551, + avatar: 'https://d1wpcgnaa73g0y.cloudfront.net/fake2.jpeg', + displayName: 'Jason', + login: 'jason@expensifail.com', + }, + }, + // eslint-disable-next-line @typescript-eslint/naming-convention + policy_137DA25D273F2423: { + approvalMode: 'ADVANCED', + approver: '', + autoReimbursement: { + limit: 500000, + }, + autoReimbursementLimit: 500000, + autoReporting: true, + autoReportingFrequency: 'immediate', + harvesting: { + enabled: true, + }, + id: '137DA25D273F2423', + name: 'Expenses - Expensify US', + owner: 'accounting@expensifail.com', + preventSelfApproval: true, + reimbursementChoice: 'reimburseYes', + role: 'user', + rules: { + approvalRules: [], + expenseRules: [], + }, + type: 'corporate', + }, + // eslint-disable-next-line @typescript-eslint/naming-convention + report_6523565988285061: { + accountID: 2074551, + chatReportID: '4128157185472356', + created: '2025-05-26 19:49:56', + currency: 'USD', + isOneTransactionReport: true, + isOwnPolicyExpenseChat: false, + isPolicyExpenseChat: false, + isWaitingOnBankAccount: false, + managerID: adminAccountID, + nonReimbursableTotal: 0, + oldPolicyName: '', + ownerAccountID: 2074551, + parentReportActionID: '5568426544518647396', + parentReportID: '4128157185472356', + policyID: '137DA25D273F2423', + private_isArchived: '', + reportID: '6523565988285061', + reportName: 'Expense Report #6523565988285061', + stateNum: 1, + statusNum: 1, + total: -1000, + type: 'expense', + unheldTotal: -1000, + }, + // eslint-disable-next-line @typescript-eslint/naming-convention + transactions_1805965960759424086: { + accountID: 2074551, + amount: 0, + canDelete: false, + canHold: true, + canUnhold: false, + category: 'Employee Meals Remote (Fringe Benefit)', + action: 'approve', + comment: { + comment: '', + }, + created: '2025-05-26', + currency: 'USD', + hasEReceipt: false, + isFromOneTransactionReport: true, + managerID: adminAccountID, + merchant: '(none)', + modifiedAmount: -1000, + modifiedCreated: '2025-05-22', + modifiedCurrency: 'USD', + modifiedMerchant: 'Costco Wholesale', + parentTransactionID: '', + policyID: '137DA25D273F2423', + receipt: { + source: 'https://www.expensify.com/receipts/fake.jpg', + state: 'SCANCOMPLETE', + }, + reportID: '6523565988285061', + reportType: 'expense', + tag: '', + transactionID: '1805965960759424086', + transactionThreadReportID: '4139222832581831', + transactionType: 'cash', + }, + }, + search: { + type: 'expense', + status: 'all', + offset: 0, + hasMoreResults: false, + hasResults: true, + isLoading: false, + columnsToShow: { + shouldShowCategoryColumn: true, + shouldShowTagColumn: true, + shouldShowTaxColumn: true, + }, + }, + }; + return waitForBatchedUpdates().then(() => { + const action = SearchUIUtils.getAction(result.data, 'report_6523565988285061'); + expect(action).toEqual(CONST.SEARCH.ACTION_TYPES.APPROVE); + }); + }); + test('Should return true if the search result has valid type', () => { expect(SearchUIUtils.shouldShowEmptyState(false, reportsListItems.length, searchResults.search.type)).toBe(true); expect(SearchUIUtils.shouldShowEmptyState(true, 0, searchResults.search.type)).toBe(true);