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
7 changes: 6 additions & 1 deletion src/libs/TransactionUtils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1928,7 +1928,8 @@ function isViolationDismissed(
return dismissedByEmails.length > 0;
}

// If the admin is looking at an open report, we check for both, submitter and admin.
// On an open report, dismissals are honored across roles: admin/approver viewing accepts a dismissal recorded by the submitter,
// and submitter viewing accepts a dismissal recorded by an admin/approver.
if (!iouReport) {
return false;
}
Expand All @@ -1943,6 +1944,10 @@ function isViolationDismissed(
}
}

if (isSubmitter && isOpenExpenseReport(iouReport) && dismissedByEmails.length > 0) {
return true;
}

return false;
}

Expand Down
33 changes: 30 additions & 3 deletions tests/unit/TransactionUtilsTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -933,14 +933,14 @@ describe('TransactionUtils', () => {
expect(result).toBe(false);
});

it('should return false when submitter views their own open report (not condition 2)', () => {
it('should return true when submitter views their own OPEN report and an admin dismissed the violation', () => {
// Given an OPEN report owned by current user
const iouReport: Report = {
...openReport,
ownerAccountID: CURRENT_USER_ID,
};

// And a transaction where someone else dismissed a violation
// And a transaction where an admin dismissed a violation
const transaction = generateTransaction({
reportID: iouReport.reportID,
comment: {
Expand All @@ -956,7 +956,34 @@ describe('TransactionUtils', () => {
// When current user (the submitter) checks if violation is dismissed
const result = TransactionUtils.isViolationDismissed(transaction, violation, CURRENT_USER_EMAIL, CURRENT_USER_ID, iouReport, undefined);

// Then it should return false (condition 2 doesn't apply to submitters)
// Then it should return true: on an open report the submitter accepts a dismissal recorded by an admin/approver.
expect(result).toBe(true);
});

it('should return false when submitter views their own PROCESSING report and only an admin dismissed the violation', () => {
// Given a PROCESSING report owned by current user
const iouReport: Report = {
...processingReport,
ownerAccountID: CURRENT_USER_ID,
};

// And a transaction where an admin dismissed a violation
const transaction = generateTransaction({
reportID: iouReport.reportID,
comment: {
dismissedViolations: {
[CONST.VIOLATIONS.DUPLICATED_TRANSACTION]: {
[OTHER_USER_EMAIL]: DateUtils.getDBTime(),
},
},
},
});
const violation = {type: CONST.VIOLATION_TYPES.VIOLATION, name: CONST.VIOLATIONS.DUPLICATED_TRANSACTION};

// When current user (the submitter) checks if violation is dismissed
const result = TransactionUtils.isViolationDismissed(transaction, violation, CURRENT_USER_EMAIL, CURRENT_USER_ID, iouReport, undefined);

// Then it should return false: cross-role dismissal is only honored on OPEN reports.
expect(result).toBe(false);
});
});
Expand Down
Loading