Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/CONST/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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',
Expand Down
42 changes: 25 additions & 17 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12440,31 +12440,39 @@ function isExported(reportActions: OnyxEntry<ReportActions> | 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<string>([
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<string>(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<ReportActions> | ReportAction[], report?: OnyxEntry<Report>) {
Expand Down
Loading