diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 102679c532a90..c37f0a204db7d 100755 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -1292,6 +1292,7 @@ const CONST = { REIMBURSEMENT_SETUP_REQUESTED: 'REIMBURSEMENTSETUPREQUESTED', // Deprecated OldDot Action REIMBURSEMENT_DIRECTOR_INFORMATION_REQUIRED: 'DIRECTORINFORMATIONREQUIRED', REJECTED: 'REJECTED', + REJECTED_TO_SUBMITTER: 'REJECTEDTOSUBMITTER', REMOVED_FROM_APPROVAL_CHAIN: 'REMOVEDFROMAPPROVALCHAIN', DEMOTED_FROM_WORKSPACE: 'DEMOTEDFROMWORKSPACE', RENAMED: 'RENAMED', @@ -1305,6 +1306,7 @@ const CONST = { STRIPE_PAID: 'STRIPEPAID', // OldDot Action SUBMITTED: 'SUBMITTED', SUBMITTED_AND_CLOSED: 'SUBMITTEDCLOSED', + ACTION_DELEGATE_SUBMIT: 'DELEGATESUBMIT', TAKE_CONTROL: 'TAKECONTROL', // OldDot Action TASK_CANCELLED: 'TASKCANCELLED', TASK_COMPLETED: 'TASKCOMPLETED', diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index ec2ea11770d23..2921f2cc6f05b 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -12440,31 +12440,39 @@ function isExported(reportActions: OnyxEntry | ReportAction[], re return false; } - let exportIntegrationActionsCount = 0; - let integrationMessageActionsCount = 0; - const reportActionList = Array.isArray(reportActions) ? reportActions : Object.values(reportActions); + + // Actions that reset the approval state and invalidate previous exports + const resetApprovalActionTypes = new Set([ + CONST.REPORT.ACTIONS.TYPE.REJECTED_TO_SUBMITTER, + CONST.REPORT.ACTIONS.TYPE.RETRACTED, + CONST.REPORT.ACTIONS.TYPE.SUBMITTED, + CONST.REPORT.ACTIONS.TYPE.ACTION_DELEGATE_SUBMIT, + CONST.REPORT.ACTIONS.TYPE.REOPENED, + CONST.REPORT.ACTIONS.TYPE.UNAPPROVED, + ]); + const validExportLabels = new Set(Object.values(CONST.EXPORT_LABELS)); + + let lastResetCreated = ''; + let lastSuccessfulExportCreated = ''; + for (const action of reportActionList) { + if (resetApprovalActionTypes.has(action.actionName)) { + if (action.created > lastResetCreated) { + lastResetCreated = action.created; + } + } if (isExportIntegrationAction(action)) { const originalMessage = getOriginalMessage(action); - // We consider any reports marked manually as exported to be exported, so we shortcut here. - if (originalMessage?.markedManually) { - return true; + const label = originalMessage?.label; + const isValidExport = originalMessage?.markedManually ?? (label && validExportLabels.has(label) && originalMessage?.type !== CONST.EXPORT_TEMPLATE); + if (isValidExport && action.created > lastSuccessfulExportCreated) { + lastSuccessfulExportCreated = action.created; } - // exportTemplate type is a CSV export, so we don't count it as an export integration action - if (originalMessage?.type !== CONST.EXPORT_TEMPLATE) { - exportIntegrationActionsCount++; - } - } - if (isIntegrationMessageAction(action)) { - integrationMessageActionsCount++; } } - // We need to make sure that there was at least one successful export to consider the report exported. - // We add one EXPORT_INTEGRATION action to the report when we start exporting it (with pendingAction: 'add') and then another EXPORT_INTEGRATION when the export finishes successfully. - // If the export fails, we add an INTEGRATIONS_MESSAGE action to the report, but the initial EXPORT_INTEGRATION action is still present, so we compare the counts of these two actions to determine if the report was exported successfully. - return exportIntegrationActionsCount > integrationMessageActionsCount; + return lastSuccessfulExportCreated > lastResetCreated; } function hasExportError(reportActions: OnyxEntry | ReportAction[], report?: OnyxEntry) {