diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 2f4ccdeb322b0..f11888f22e05d 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -10822,12 +10822,11 @@ function getTripIDFromTransactionParentReportID(transactionParentReportID: strin /** * Checks if report contains actions with errors */ -function hasActionWithErrorsForTransaction(reportID: string | undefined, transaction: Transaction | undefined): boolean { +function hasActionWithErrorsForTransaction(reportID: string | undefined, transaction: Transaction | undefined, reportActions: OnyxEntry | undefined): boolean { if (!reportID) { return false; } - const reportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {}; - return Object.values(reportActions) + return Object.values(reportActions ?? {}) .filter(Boolean) .some((action) => { if (isMoneyRequestAction(action) && getOriginalMessage(action)?.IOUTransactionID) { diff --git a/src/libs/TransactionPreviewUtils.ts b/src/libs/TransactionPreviewUtils.ts index d7db2dd81673a..cf96f3c04e5c4 100644 --- a/src/libs/TransactionPreviewUtils.ts +++ b/src/libs/TransactionPreviewUtils.ts @@ -229,7 +229,7 @@ function getTransactionPreviewTextAndTranslationPaths({ // eslint-disable-next-line @typescript-eslint/no-deprecated const policy = getPolicy(iouReport?.policyID); const hasViolationsOfTypeNotice = hasNoticeTypeViolation(transaction, violations, currentUserEmail ?? '', currentUserAccountID, iouReport, policy, true) && isPaidGroupPolicy; - const hasActionWithErrors = hasActionWithErrorsForTransaction(iouReport?.reportID, transaction); + const hasActionWithErrors = hasActionWithErrorsForTransaction(iouReport?.reportID, transaction, reportActions); const {amount: requestAmount, currency: requestCurrency} = transactionDetails; @@ -419,7 +419,8 @@ function createTransactionPreviewConditionals({ (violation) => violation.name === CONST.VIOLATIONS.MODIFIED_AMOUNT && (violation.type === CONST.VIOLATION_TYPES.VIOLATION || violation.type === CONST.VIOLATION_TYPES.NOTICE), )); const hasErrorOrOnHold = hasFieldErrors || (!isFullySettled && !isFullyApproved && isTransactionOnHold); - const hasReportViolationsOrActionErrors = (isReportOwner(iouReport) && hasReportViolations(iouReport?.reportID)) || hasActionWithErrorsForTransaction(iouReport?.reportID, transaction); + const hasReportViolationsOrActionErrors = + (isReportOwner(iouReport) && hasReportViolations(iouReport?.reportID)) || hasActionWithErrorsForTransaction(iouReport?.reportID, transaction, reportActions); const isDEWSubmitFailed = hasDynamicExternalWorkflow(policy) && !!getMostRecentActiveDEWSubmitFailedAction(reportActions); const shouldShowRBR = hasAnyViolations || hasErrorOrOnHold || hasReportViolationsOrActionErrors || hasReceiptError(transaction) || isDEWSubmitFailed; diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 50dd39b850638..efe60d0a7926f 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -87,6 +87,7 @@ import { getReportStatusTranslation, getWorkspaceIcon, getWorkspaceNameUpdatedMessage, + hasActionWithErrorsForTransaction, hasEmptyReportsForPolicy, hasReceiptError, isAllowedToApproveExpenseReport, @@ -11774,6 +11775,82 @@ describe('ReportUtils', () => { }); }); + describe('hasActionWithErrorsForTransaction', () => { + it('should return false when reportID is undefined', () => { + const transaction = createRandomTransaction(1); + const result = hasActionWithErrorsForTransaction(undefined, transaction, undefined); + expect(result).toBe(false); + }); + + it('should return false when there are no report actions with errors', () => { + const reportID = '123'; + const transaction = createRandomTransaction(1); + const reportAction = createRandomReportAction(1); + const reportActions = { + [reportAction.reportActionID]: reportAction, + }; + + const result = hasActionWithErrorsForTransaction(reportID, transaction, reportActions); + expect(result).toBe(false); + }); + + it('should return true when there is a report action with errors', () => { + const reportID = '124'; + const transaction = createRandomTransaction(2); + const reportAction: ReportAction = { + ...createRandomReportAction(2), + errors: {someError: 'This is an error'}, + }; + const reportActions = { + [reportAction.reportActionID]: reportAction, + }; + + const result = hasActionWithErrorsForTransaction(reportID, transaction, reportActions); + expect(result).toBe(true); + }); + + it('should return true when a money request action has errors matching the transaction', () => { + const reportID = '125'; + const transaction = createRandomTransaction(3); + const reportAction: ReportAction = { + ...createRandomReportAction(3), + actionName: CONST.REPORT.ACTIONS.TYPE.IOU, + originalMessage: { + IOUTransactionID: transaction.transactionID, + type: CONST.IOU.REPORT_ACTION_TYPE.CREATE, + }, + errors: {transactionError: 'Transaction has an error'}, + } as ReportAction; + const reportActions = { + [reportAction.reportActionID]: reportAction, + }; + + const result = hasActionWithErrorsForTransaction(reportID, transaction, reportActions); + expect(result).toBe(true); + }); + + it('should return false when a money request action has errors but for a different transaction', () => { + const reportID = '126'; + const transaction = createRandomTransaction(4); + const differentTransaction = createRandomTransaction(5); + const reportAction: ReportAction = { + ...createRandomReportAction(4), + actionName: CONST.REPORT.ACTIONS.TYPE.IOU, + originalMessage: { + IOUTransactionID: differentTransaction.transactionID, + type: CONST.IOU.REPORT_ACTION_TYPE.CREATE, + }, + errors: {transactionError: 'Transaction has an error'}, + } as ReportAction; + const reportActions = { + [reportAction.reportActionID]: reportAction, + }; + + const result = hasActionWithErrorsForTransaction(reportID, transaction, reportActions); + expect(result).toBe(false); + }); + }); + describe('getPolicyName', () => { const testPolicy: Policy = { ...createRandomPolicy(1),