diff --git a/src/libs/ReportPreviewActionUtils.ts b/src/libs/ReportPreviewActionUtils.ts index 35e30fda030f..048182205482 100644 --- a/src/libs/ReportPreviewActionUtils.ts +++ b/src/libs/ReportPreviewActionUtils.ts @@ -9,6 +9,7 @@ import { getMoneyRequestSpendBreakdown, getParentReport, getReportTransactions, + hasExportError as hasExportErrorUtil, hasOnlyNonReimbursableTransactions, isClosedReport, isCurrentUserSubmitter, @@ -122,7 +123,7 @@ function canPay( const isReimbursed = isSettled(report); const isExported = report.isExportedToIntegration ?? false; - const hasExportError = report?.hasExportError ?? false; + const hasExportError = hasExportErrorUtil(undefined, report); const didExportFail = !isExported && hasExportError; if ( @@ -177,7 +178,7 @@ function canExport(report: Report, currentUserLogin: string, policy?: Policy) { return false; } - const hasExportError = report.hasExportError ?? false; + const hasExportError = hasExportErrorUtil(undefined, report); if (syncEnabled && !hasExportError) { return false; } diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 2043736d9990..1f7d5db9944a 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -12568,7 +12568,6 @@ function getIntegrationNameFromExportMessage(reportActions: OnyxEntry | ReportAction[], report?: OnyxEntry): boolean { - // If report object is provided and has the property, use it directly if (report?.isExportedToIntegration !== undefined) { return report.isExportedToIntegration; } @@ -12616,9 +12615,13 @@ function isExported(reportActions: OnyxEntry | ReportAction[], re } function hasExportError(reportActions: OnyxEntry | ReportAction[], report?: OnyxEntry) { - // If report object is provided and has the property, use it directly - if (report?.hasExportError !== undefined) { - return report.hasExportError; + if (report?.hasExportError) { + return true; + } + + const exportErrors = report?.errorFields?.export; + if (exportErrors && Object.values(exportErrors).some((error) => error != null)) { + return true; } // Fallback to checking actions for backward compatibility @@ -12926,7 +12929,6 @@ function canRejectReportAction(currentUserLogin: string, report: Report): boolea } function hasReportBeenReopened(report: OnyxEntry, reportActions?: OnyxEntry | ReportAction[]): boolean { - // If report object is provided and has the property, use it directly if (report?.hasReportBeenReopened !== undefined) { return report.hasReportBeenReopened; } @@ -12941,7 +12943,6 @@ function hasReportBeenReopened(report: OnyxEntry, reportActions?: OnyxEn } function hasReportBeenRetracted(report: OnyxEntry, reportActions?: OnyxEntry | ReportAction[]): boolean { - // If report object is provided and has the property, use it directly if (report?.hasReportBeenRetracted !== undefined) { return report.hasReportBeenRetracted; } diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 70f1c9f4133c..950cecc2acb9 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -118,6 +118,7 @@ import { getWorkspaceNameUpdatedMessage, hasActionWithErrorsForTransaction, hasEmptyReportsForPolicy, + hasExportError, hasReceiptError, hasSmartscanError, hasVisibleReportFieldViolations, @@ -17619,4 +17620,39 @@ describe('ReportUtils', () => { expect(createdActionForThread).toBeNull(); }); }); + + describe('hasExportError', () => { + it('returns true when report.hasExportError is true', () => { + const report = {hasExportError: true} as Report; + expect(hasExportError([], report)).toBe(true); + }); + + it('returns true when errorFields.export is populated but hasExportError is false', () => { + const report = { + hasExportError: false, + errorFields: {export: {'1708946640843000': 'export failed'}}, + } as unknown as Report; + expect(hasExportError([], report)).toBe(true); + }); + + it('returns false when errorFields.export is cleared', () => { + const report = { + hasExportError: false, + errorFields: {export: null}, + } as unknown as Report; + expect(hasExportError([], report)).toBe(false); + }); + + it('returns true when an integration message action exists in reportActions', () => { + const report = {hasExportError: false} as Report; + const reportActions = [ + { + actionName: CONST.REPORT.ACTIONS.TYPE.INTEGRATIONS_MESSAGE, + reportActionID: '1', + created: '2024-01-01', + }, + ] as ReportAction[]; + expect(hasExportError(reportActions, report)).toBe(true); + }); + }); });