Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/libs/SearchUIUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
3 changes: 1 addition & 2 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand Down
127 changes: 127 additions & 0 deletions tests/unit/Search/SearchUIUtilsTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down