Skip to content

Commit 4a4cfa5

Browse files
Merge pull request #79538 from nkdengineer/fix/78928
fix: Unexpected error occurs when a category/Tag approver submits an expense
2 parents 2af2cc3 + f48b1a3 commit 4a4cfa5

File tree

2 files changed

+74
-11
lines changed

2 files changed

+74
-11
lines changed

src/libs/PolicyUtils.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,8 @@ function getRuleApprovers(policy: OnyxEntry<Policy>, expenseReport: OnyxEntry<Re
856856
}
857857
}
858858

859-
return [...categoryApprovers, ...tagApprovers];
859+
// Return the unique approvers list
860+
return [...new Set([...categoryApprovers, ...tagApprovers])];
860861
}
861862

862863
function getManagerAccountID(policy: OnyxEntry<Policy>, expenseReport: OnyxEntry<Report> | {ownerAccountID: number}) {
@@ -884,7 +885,7 @@ function getSubmitToAccountID(policy: OnyxEntry<Policy>, expenseReport: OnyxEntr
884885
const ruleApprovers = getRuleApprovers(policy, expenseReport);
885886
const employeeAccountID = expenseReport?.ownerAccountID ?? CONST.DEFAULT_NUMBER_ID;
886887
const employeeLogin = getLoginsByAccountIDs([employeeAccountID]).at(0) ?? '';
887-
if (ruleApprovers.length > 0 && ruleApprovers.at(0) === employeeLogin && policy?.preventSelfApproval) {
888+
if (ruleApprovers.length > 0 && ruleApprovers.at(0) === employeeLogin) {
888889
ruleApprovers.shift();
889890
}
890891
if (ruleApprovers.length > 0 && !isSubmitAndClose(policy)) {

tests/unit/PolicyUtilsTest.ts

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,17 @@ const rules = {
187187
approver: 'tagapprover2@test.com',
188188
id: '4',
189189
},
190+
{
191+
applyWhen: [
192+
{
193+
condition: 'matches',
194+
field: 'category',
195+
value: 'cat3',
196+
},
197+
],
198+
approver: 'categoryapprover1@test.com',
199+
id: '5',
200+
},
190201
],
191202
};
192203
const policyTags = {
@@ -531,9 +542,11 @@ describe('PolicyUtils', () => {
531542
category: '',
532543
reportID: expenseReport.reportID,
533544
};
534-
await Onyx.set(ONYXKEYS.COLLECTION.TRANSACTION, {
535-
[transaction1.transactionID]: transaction1,
536-
[transaction2.transactionID]: transaction2,
545+
await Onyx.multiSet({
546+
[ONYXKEYS.COLLECTION.TRANSACTION]: {
547+
[transaction1.transactionID]: transaction1,
548+
[transaction2.transactionID]: transaction2,
549+
},
537550
});
538551
expect(getSubmitToAccountID(policy, expenseReport)).toBe(categoryApprover1AccountID);
539552
});
@@ -560,9 +573,7 @@ describe('PolicyUtils', () => {
560573
tag: '',
561574
};
562575

563-
await Onyx.set(ONYXKEYS.COLLECTION.TRANSACTION, {
564-
[transaction.transactionID]: transaction,
565-
});
576+
await Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`, transaction);
566577
expect(getSubmitToAccountID(policy, expenseReport)).toBe(adminAccountID);
567578
});
568579
it('should return the category approver of the first transaction sorted by created if we have many transaction categories match with the category approver rule', async () => {
@@ -592,12 +603,63 @@ describe('PolicyUtils', () => {
592603
created: DateUtils.subtractMillisecondsFromDateTime(testDate, 1),
593604
reportID: expenseReport.reportID,
594605
};
595-
await Onyx.set(ONYXKEYS.COLLECTION.TRANSACTION, {
596-
[transaction1.transactionID]: transaction1,
597-
[transaction2.transactionID]: transaction2,
606+
await Onyx.multiSet({
607+
[ONYXKEYS.COLLECTION.TRANSACTION]: {
608+
[transaction1.transactionID]: transaction1,
609+
[transaction2.transactionID]: transaction2,
610+
},
598611
});
599612
expect(getSubmitToAccountID(policy, expenseReport)).toBe(categoryApprover2AccountID);
600613
});
614+
it('should return the first rule approver who is not the current submitter', async () => {
615+
const policy: Policy = {
616+
...createRandomPolicy(0),
617+
approver: 'owner@test.com',
618+
owner: 'owner@test.com',
619+
type: CONST.POLICY.TYPE.CORPORATE,
620+
employeeList,
621+
rules,
622+
approvalMode: CONST.POLICY.APPROVAL_MODE.ADVANCED,
623+
};
624+
const expenseReport: Report = {
625+
...createRandomReport(0, undefined),
626+
ownerAccountID: categoryApprover1AccountID,
627+
type: CONST.REPORT.TYPE.EXPENSE,
628+
};
629+
const transaction1: Transaction = {
630+
...createRandomTransaction(0),
631+
category: 'cat1',
632+
reportID: expenseReport.reportID,
633+
tag: '',
634+
created: DateUtils.subtractMillisecondsFromDateTime(testDate, 2),
635+
};
636+
637+
const transaction2: Transaction = {
638+
...createRandomTransaction(1),
639+
category: 'cat3',
640+
reportID: expenseReport.reportID,
641+
tag: '',
642+
created: DateUtils.subtractMillisecondsFromDateTime(testDate, 1),
643+
};
644+
645+
const transaction3: Transaction = {
646+
...createRandomTransaction(2),
647+
category: '',
648+
reportID: expenseReport.reportID,
649+
tag: 'tag1',
650+
created: testDate,
651+
};
652+
653+
await Onyx.multiSet({
654+
[ONYXKEYS.COLLECTION.TRANSACTION]: {
655+
[transaction1.transactionID]: transaction1,
656+
[transaction2.transactionID]: transaction2,
657+
[transaction3.transactionID]: transaction3,
658+
},
659+
});
660+
661+
expect(getSubmitToAccountID(policy, expenseReport)).toBe(tagApprover1AccountID);
662+
});
601663
describe('Has no transaction match with the category approver rule', () => {
602664
it('should return the first tag approver if has any transaction tag match with with the tag approver rule ', async () => {
603665
const policy: Policy = {

0 commit comments

Comments
 (0)