Skip to content
Open
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: 2 additions & 1 deletion src/libs/ReportPrimaryActionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ function isSubmitAction(

const reportTransactionsList = reportTransactions ?? [];
const hasNoSubmittableTransaction =
reportTransactionsList.length > 0 && reportTransactionsList.every((transaction) => isScanning(transaction) || hasSmartScanFailedWithMissingFields([transaction], report));
reportTransactionsList.length > 0 &&
reportTransactionsList.every((transaction) => isScanning(transaction) || isPending(transaction) || hasSmartScanFailedWithMissingFields([transaction], report));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep Submit visible for non-card pending expenses

When an open report contains a pending cash/manual transaction (a transaction with status: PENDING but no Expensify-card metadata), this isPending() check makes hasNoSubmittableTransaction true and removes the Submit primary action/to-do. Other submit entry points only block hasOnlyPendingCardTransactions(...), and the existing ReportPrimary/Secondary action tests treat pending non-card transactions as submittable, so this should gate pending status on card transactions instead of all pending transactions.

Useful? React with 👍 / 👎.


if (hasNoSubmittableTransaction) {
return false;
Expand Down
38 changes: 38 additions & 0 deletions tests/unit/TodosUtilsTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,25 @@ describe('TodosUtils', () => {
expect(result.reportsToSubmit).toEqual([]);
});

it('excludes a report whose expenses are all pending card transactions', () => {
const pendingOverride: Partial<Transaction> = {status: CONST.TRANSACTION.STATUS.PENDING};
const submitReport = createMockReport('pending_submit', {
stateNum: CONST.REPORT.STATE_NUM.OPEN,
statusNum: CONST.REPORT.STATUS_NUM.OPEN,
ownerAccountID: CURRENT_USER_ACCOUNT_ID,
});
const policy = createMockPolicy(POLICY_ID, {role: CONST.POLICY.ROLE.ADMIN, ownerAccountID: CURRENT_USER_ACCOUNT_ID});

const result = createTodosReportsAndTransactions({
...baseParams,
allReports: toReportsCollection([submitReport]),
allTransactions: toTransactionsCollection([createMockTransaction('trans_pending', 'pending_submit', pendingOverride)]),
allPolicies: toPoliciesCollection([policy]),
});

expect(result.reportsToSubmit).toEqual([]);
});

it('ignores non-expense reports', () => {
const chatReport = createMockReport('chat_report', {type: CONST.REPORT.TYPE.CHAT, ownerAccountID: CURRENT_USER_ACCOUNT_ID});
const policy = createMockPolicy(POLICY_ID, {role: CONST.POLICY.ROLE.ADMIN, ownerAccountID: CURRENT_USER_ACCOUNT_ID});
Expand Down Expand Up @@ -319,5 +338,24 @@ describe('TodosUtils', () => {

expect(result.reports).toEqual([]);
});

it('excludes a report whose expenses are all pending card transactions from its bucket', () => {
const pendingOverride: Partial<Transaction> = {status: CONST.TRANSACTION.STATUS.PENDING};
const submitReport = createMockReport('pending_submit', {
stateNum: CONST.REPORT.STATE_NUM.OPEN,
statusNum: CONST.REPORT.STATUS_NUM.OPEN,
ownerAccountID: CURRENT_USER_ACCOUNT_ID,
});
const policy = createMockPolicy(POLICY_ID, {role: CONST.POLICY.ROLE.ADMIN, ownerAccountID: CURRENT_USER_ACCOUNT_ID});

const result = getTodoReportsForSearchKey(CONST.SEARCH.SEARCH_KEYS.SUBMIT, {
...baseParams,
allReports: toReportsCollection([submitReport]),
allTransactions: toTransactionsCollection([createMockTransaction('trans_pending', 'pending_submit', pendingOverride)]),
allPolicies: toPoliciesCollection([policy]),
});

expect(result.reports).toEqual([]);
});
});
});
Loading