@@ -12827,6 +12827,181 @@ describe('ReportUtils', () => {
1282712827
1282812828 await Onyx.clear();
1282912829 });
12830+
12831+ it('should return null for a processing (submitted) expense report whose only violation is a modifiedAmount NOTICE', async () => {
12832+ await Onyx.clear();
12833+
12834+ const policyID = 'policy-rbr-modified-amount-processing';
12835+ const chatReportID = 'chat-rbr-modified-amount-processing';
12836+ const expenseReportID = 'expense-rbr-modified-amount-processing';
12837+ const transactionID = 'transaction-rbr-modified-amount-processing';
12838+
12839+ const policyData: Policy = {
12840+ id: policyID,
12841+ name: 'Modified Amount Processing Workspace',
12842+ type: CONST.POLICY.TYPE.TEAM,
12843+ role: CONST.POLICY.ROLE.ADMIN,
12844+ outputCurrency: CONST.CURRENCY.USD,
12845+ reimbursementChoice: CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES,
12846+ approvalMode: CONST.POLICY.APPROVAL_MODE.BASIC,
12847+ employeeList: {
12848+ [currentUserEmail]: {
12849+ role: CONST.POLICY.ROLE.ADMIN,
12850+ },
12851+ },
12852+ owner: currentUserEmail,
12853+ isPolicyExpenseChatEnabled: true,
12854+ };
12855+
12856+ const chatReport: Report = {
12857+ ...createPolicyExpenseChat(820),
12858+ reportID: chatReportID,
12859+ ownerAccountID: currentUserAccountID,
12860+ policyID,
12861+ iouReportID: expenseReportID,
12862+ };
12863+
12864+ const expenseReport: Report = {
12865+ ...createExpenseReport(821),
12866+ reportID: expenseReportID,
12867+ chatReportID,
12868+ ownerAccountID: currentUserAccountID,
12869+ managerID: 42,
12870+ policyID,
12871+ type: CONST.REPORT.TYPE.EXPENSE,
12872+ currency: CONST.CURRENCY.USD,
12873+ total: 5000,
12874+ stateNum: CONST.REPORT.STATE_NUM.SUBMITTED,
12875+ statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED,
12876+ };
12877+
12878+ const baseTransaction = createRandomTransaction(820);
12879+ const transaction: Transaction = {
12880+ ...baseTransaction,
12881+ transactionID,
12882+ reportID: expenseReportID,
12883+ amount: 5000,
12884+ currency: CONST.CURRENCY.USD,
12885+ status: CONST.TRANSACTION.STATUS.POSTED,
12886+ reimbursable: true,
12887+ };
12888+
12889+ const transactionViolationsKey = `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}` as OnyxKey;
12890+ const transactionViolationsCollection: OnyxCollection<TransactionViolation[]> = {
12891+ [transactionViolationsKey]: [
12892+ {
12893+ name: CONST.VIOLATIONS.MODIFIED_AMOUNT,
12894+ type: CONST.VIOLATION_TYPES.NOTICE,
12895+ showInReview: true,
12896+ },
12897+ ],
12898+ };
12899+
12900+ await Onyx.merge(ONYXKEYS.SESSION, {accountID: currentUserAccountID, email: currentUserEmail});
12901+ await waitForBatchedUpdates();
12902+
12903+ await Promise.all([
12904+ Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, policyData),
12905+ Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, chatReport),
12906+ Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`, expenseReport),
12907+ Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`, transaction),
12908+ Onyx.merge(transactionViolationsKey, transactionViolationsCollection[transactionViolationsKey]),
12909+ ]);
12910+ await waitForBatchedUpdates();
12911+
12912+ const result = getViolatingReportIDForRBRInLHN(chatReport, transactionViolationsCollection);
12913+ expect(result).toBeNull();
12914+
12915+ await Onyx.clear();
12916+ });
12917+
12918+ it('should still surface RBR for an open expense report whose only violation is a modifiedAmount NOTICE', async () => {
12919+ await Onyx.clear();
12920+
12921+ const policyID = 'policy-rbr-modified-amount-open';
12922+ const chatReportID = 'chat-rbr-modified-amount-open';
12923+ const expenseReportID = 'expense-rbr-modified-amount-open';
12924+ const transactionID = 'transaction-rbr-modified-amount-open';
12925+
12926+ const policyData: Policy = {
12927+ id: policyID,
12928+ name: 'Modified Amount Open Workspace',
12929+ type: CONST.POLICY.TYPE.TEAM,
12930+ role: CONST.POLICY.ROLE.ADMIN,
12931+ outputCurrency: CONST.CURRENCY.USD,
12932+ reimbursementChoice: CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES,
12933+ approvalMode: CONST.POLICY.APPROVAL_MODE.BASIC,
12934+ employeeList: {
12935+ [currentUserEmail]: {
12936+ role: CONST.POLICY.ROLE.ADMIN,
12937+ },
12938+ },
12939+ owner: currentUserEmail,
12940+ isPolicyExpenseChatEnabled: true,
12941+ };
12942+
12943+ const chatReport: Report = {
12944+ ...createPolicyExpenseChat(822),
12945+ reportID: chatReportID,
12946+ ownerAccountID: currentUserAccountID,
12947+ policyID,
12948+ iouReportID: expenseReportID,
12949+ hasOutstandingChildRequest: true,
12950+ };
12951+
12952+ const expenseReport: Report = {
12953+ ...createExpenseReport(823),
12954+ reportID: expenseReportID,
12955+ chatReportID,
12956+ ownerAccountID: currentUserAccountID,
12957+ managerID: 42,
12958+ policyID,
12959+ type: CONST.REPORT.TYPE.EXPENSE,
12960+ currency: CONST.CURRENCY.USD,
12961+ total: 5000,
12962+ stateNum: CONST.REPORT.STATE_NUM.OPEN,
12963+ statusNum: CONST.REPORT.STATUS_NUM.OPEN,
12964+ };
12965+
12966+ const baseTransaction = createRandomTransaction(822);
12967+ const transaction: Transaction = {
12968+ ...baseTransaction,
12969+ transactionID,
12970+ reportID: expenseReportID,
12971+ amount: 5000,
12972+ currency: CONST.CURRENCY.USD,
12973+ status: CONST.TRANSACTION.STATUS.POSTED,
12974+ reimbursable: true,
12975+ };
12976+
12977+ const transactionViolationsKey = `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}` as OnyxKey;
12978+ const transactionViolationsCollection: OnyxCollection<TransactionViolation[]> = {
12979+ [transactionViolationsKey]: [
12980+ {
12981+ name: CONST.VIOLATIONS.MODIFIED_AMOUNT,
12982+ type: CONST.VIOLATION_TYPES.NOTICE,
12983+ showInReview: true,
12984+ },
12985+ ],
12986+ };
12987+
12988+ await Onyx.merge(ONYXKEYS.SESSION, {accountID: currentUserAccountID, email: currentUserEmail});
12989+ await waitForBatchedUpdates();
12990+
12991+ await Promise.all([
12992+ Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, policyData),
12993+ Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, chatReport),
12994+ Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`, expenseReport),
12995+ Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`, transaction),
12996+ Onyx.merge(transactionViolationsKey, transactionViolationsCollection[transactionViolationsKey]),
12997+ ]);
12998+ await waitForBatchedUpdates();
12999+
13000+ const result = getViolatingReportIDForRBRInLHN(chatReport, transactionViolationsCollection);
13001+ expect(result).toBe(expenseReportID);
13002+
13003+ await Onyx.clear();
13004+ });
1283013005 });
1283113006
1283213007 it('should surface a GBR for admin with held expenses requiring approval or payment and avoid showing an RBR', async () => {
0 commit comments