From a03fdc061f6fb2047aa104eab50815828ef3ca09 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Thu, 1 May 2025 19:52:43 +0200
Subject: [PATCH 01/10] fix export condition

---
 src/libs/ReportActionsUtils.ts       | 16 ++++++++++++++--
 src/libs/ReportPrimaryActionUtils.ts |  3 ++-
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts
index dad854859288..e1c28553140c 100644
--- a/src/libs/ReportActionsUtils.ts
+++ b/src/libs/ReportActionsUtils.ts
@@ -1271,8 +1271,20 @@ function doesReportHaveVisibleActions(reportID: string, canUserPerformWriteActio
     return visibleReportActionsWithoutTaskSystemMessage.length > 0;
 }
 
-function getAllReportActions(reportID: string | undefined): ReportActions {
-    return allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {};
+function getAllReportActions(reportID: string | undefined, selector?: (action: ReportAction) => boolean): ReportActions {
+    const actions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {};
+    if (!selector) {
+        return actions;
+    }
+
+    const filteredActions: ReportActions = {};
+    for (const [reportActionID, action] of Object.entries(actions)) {
+        if (selector(action)) {
+            filteredActions[reportActionID] = action;
+        }
+    }
+
+    return filteredActions;
 }
 
 /**
diff --git a/src/libs/ReportPrimaryActionUtils.ts b/src/libs/ReportPrimaryActionUtils.ts
index f50449547bac..c5aee93c6869 100644
--- a/src/libs/ReportPrimaryActionUtils.ts
+++ b/src/libs/ReportPrimaryActionUtils.ts
@@ -165,7 +165,8 @@ function isExportAction(report: Report, policy?: Policy) {
 
     const connectedIntegration = getConnectedIntegration(policy);
     const syncEnabled = hasIntegrationAutoSync(policy, connectedIntegration);
-    if (syncEnabled) {
+    const hasFailedToExport = Object.values(getAllReportActions(report.reportID, (action) => action.actionName === CONST.REPORT.ACTIONS.TYPE.INTEGRATIONS_MESSAGE)).length > 0;
+    if (syncEnabled && !hasFailedToExport) {
         return false;
     }
 

From 9857b6e68c627fb55ce84ef5c96be4ad27a9817a Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Thu, 1 May 2025 20:05:35 +0200
Subject: [PATCH 02/10] handle null action

---
 src/libs/ReportPrimaryActionUtils.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libs/ReportPrimaryActionUtils.ts b/src/libs/ReportPrimaryActionUtils.ts
index c5aee93c6869..c0a15d1b779c 100644
--- a/src/libs/ReportPrimaryActionUtils.ts
+++ b/src/libs/ReportPrimaryActionUtils.ts
@@ -165,7 +165,7 @@ function isExportAction(report: Report, policy?: Policy) {
 
     const connectedIntegration = getConnectedIntegration(policy);
     const syncEnabled = hasIntegrationAutoSync(policy, connectedIntegration);
-    const hasFailedToExport = Object.values(getAllReportActions(report.reportID, (action) => action.actionName === CONST.REPORT.ACTIONS.TYPE.INTEGRATIONS_MESSAGE)).length > 0;
+    const hasFailedToExport = Object.values(getAllReportActions(report.reportID, (action) => action?.actionName === CONST.REPORT.ACTIONS.TYPE.INTEGRATIONS_MESSAGE)).length > 0;
     if (syncEnabled && !hasFailedToExport) {
         return false;
     }

From 3732d251f0008dccb43024e04172bcebb32d9e45 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Thu, 1 May 2025 22:49:50 +0200
Subject: [PATCH 03/10] update conditions

---
 src/libs/ReportActionsUtils.ts       | 16 ++--------------
 src/libs/ReportPrimaryActionUtils.ts | 10 ++++++++--
 2 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts
index e1c28553140c..dad854859288 100644
--- a/src/libs/ReportActionsUtils.ts
+++ b/src/libs/ReportActionsUtils.ts
@@ -1271,20 +1271,8 @@ function doesReportHaveVisibleActions(reportID: string, canUserPerformWriteActio
     return visibleReportActionsWithoutTaskSystemMessage.length > 0;
 }
 
-function getAllReportActions(reportID: string | undefined, selector?: (action: ReportAction) => boolean): ReportActions {
-    const actions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {};
-    if (!selector) {
-        return actions;
-    }
-
-    const filteredActions: ReportActions = {};
-    for (const [reportActionID, action] of Object.entries(actions)) {
-        if (selector(action)) {
-            filteredActions[reportActionID] = action;
-        }
-    }
-
-    return filteredActions;
+function getAllReportActions(reportID: string | undefined): ReportActions {
+    return allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {};
 }
 
 /**
diff --git a/src/libs/ReportPrimaryActionUtils.ts b/src/libs/ReportPrimaryActionUtils.ts
index c0a15d1b779c..98ab2e0ba2ab 100644
--- a/src/libs/ReportPrimaryActionUtils.ts
+++ b/src/libs/ReportPrimaryActionUtils.ts
@@ -163,10 +163,16 @@ function isExportAction(report: Report, policy?: Policy) {
         return false;
     }
 
+    const reportActions = getAllReportActions(report.reportID);
+    const hasExportedIntegrationAction = Object.values(reportActions).some((action) => action?.actionName === CONST.REPORT.ACTIONS.TYPE.EXPORTED_TO_INTEGRATION);
+    if (hasExportedIntegrationAction) {
+        return false;
+    }
+
     const connectedIntegration = getConnectedIntegration(policy);
     const syncEnabled = hasIntegrationAutoSync(policy, connectedIntegration);
-    const hasFailedToExport = Object.values(getAllReportActions(report.reportID, (action) => action?.actionName === CONST.REPORT.ACTIONS.TYPE.INTEGRATIONS_MESSAGE)).length > 0;
-    if (syncEnabled && !hasFailedToExport) {
+    const hasFailedExportedAction = Object.values(reportActions).some((action) => action?.actionName === CONST.REPORT.ACTIONS.TYPE.INTEGRATIONS_MESSAGE);
+    if (syncEnabled && !hasFailedExportedAction) {
         return false;
     }
 

From 138a2ef581cfc5441e300b70b8aa6b7d59b39dad Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Fri, 2 May 2025 00:12:42 +0200
Subject: [PATCH 04/10] update conditions

---
 src/libs/ReportActionsUtils.ts       |  5 ++++-
 src/libs/ReportPrimaryActionUtils.ts | 12 ++++++------
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts
index dad854859288..b6ed713ec3cb 100644
--- a/src/libs/ReportActionsUtils.ts
+++ b/src/libs/ReportActionsUtils.ts
@@ -273,7 +273,10 @@ function getOriginalMessage<T extends ReportActionName>(reportAction: OnyxInputO
 }
 
 function isExportIntegrationAction(reportAction: OnyxInputOrEntry<ReportAction>): boolean {
-    return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.INTEGRATIONS_MESSAGE && !!getOriginalMessage(reportAction as ReportAction<'INTEGRATIONSMESSAGE'>)?.result?.success;
+    return (
+        (reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.INTEGRATIONS_MESSAGE && !!getOriginalMessage(reportAction as ReportAction<'INTEGRATIONSMESSAGE'>)?.result?.success) ||
+        (reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.EXPORTED_TO_INTEGRATION && !!getOriginalMessage(reportAction as ReportAction<'EXPORTINTEGRATION'>)?.markedManually)
+    );
 }
 
 /**
diff --git a/src/libs/ReportPrimaryActionUtils.ts b/src/libs/ReportPrimaryActionUtils.ts
index 98ab2e0ba2ab..c4d7bcfffb9b 100644
--- a/src/libs/ReportPrimaryActionUtils.ts
+++ b/src/libs/ReportPrimaryActionUtils.ts
@@ -22,6 +22,7 @@ import {
     isClosedReport as isClosedReportUtils,
     isCurrentUserSubmitter,
     isExpenseReport as isExpenseReportUtils,
+    isExported as isExportedUtil,
     isHoldCreator,
     isInvoiceReport as isInvoiceReportUtils,
     isIOUReport as isIOUReportUtils,
@@ -163,16 +164,15 @@ function isExportAction(report: Report, policy?: Policy) {
         return false;
     }
 
+    const connectedIntegration = getConnectedIntegration(policy);
+    const syncEnabled = hasIntegrationAutoSync(policy, connectedIntegration);
     const reportActions = getAllReportActions(report.reportID);
-    const hasExportedIntegrationAction = Object.values(reportActions).some((action) => action?.actionName === CONST.REPORT.ACTIONS.TYPE.EXPORTED_TO_INTEGRATION);
-    if (hasExportedIntegrationAction) {
+    const isExported = isExportedUtil(reportActions);
+    if (isExported) {
         return false;
     }
 
-    const connectedIntegration = getConnectedIntegration(policy);
-    const syncEnabled = hasIntegrationAutoSync(policy, connectedIntegration);
-    const hasFailedExportedAction = Object.values(reportActions).some((action) => action?.actionName === CONST.REPORT.ACTIONS.TYPE.INTEGRATIONS_MESSAGE);
-    if (syncEnabled && !hasFailedExportedAction) {
+    if (syncEnabled) {
         return false;
     }
 

From 77bb6815cd4d6c7b9a067c3870333642999cdb3b Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Mon, 5 May 2025 20:52:56 +0200
Subject: [PATCH 05/10] add export error condition

---
 src/libs/ReportActionsUtils.ts       |  5 +++++
 src/libs/ReportPrimaryActionUtils.ts |  4 +++-
 src/libs/ReportUtils.ts              | 14 ++++++++++++++
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts
index 4e33475cef36..228de307c408 100644
--- a/src/libs/ReportActionsUtils.ts
+++ b/src/libs/ReportActionsUtils.ts
@@ -280,6 +280,10 @@ function isExportIntegrationAction(reportAction: OnyxInputOrEntry<ReportAction>)
     return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.EXPORTED_TO_INTEGRATION;
 }
 
+function isIntegrationMessageAction(reportAction: OnyxInputOrEntry<ReportAction>): boolean {
+    return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.INTEGRATIONS_MESSAGE;
+}
+
 /**
  * We are in the process of deprecating reportAction.originalMessage and will be setting the db version of "message" to reportAction.message in the future see: https://github.com/Expensify/App/issues/39797
  * In the interim, we must check to see if we have an object or array for the reportAction.message, if we have an array we will use the originalMessage as this means we have not yet migrated.
@@ -2438,6 +2442,7 @@ export {
     isLinkedTransactionHeld,
     isMemberChangeAction,
     isExportIntegrationAction,
+    isIntegrationMessageAction,
     isMessageDeleted,
     useNewTableReportViewActionRenderConditionals,
     isModifiedExpenseAction,
diff --git a/src/libs/ReportPrimaryActionUtils.ts b/src/libs/ReportPrimaryActionUtils.ts
index d3bc89c8bb90..ce6949172454 100644
--- a/src/libs/ReportPrimaryActionUtils.ts
+++ b/src/libs/ReportPrimaryActionUtils.ts
@@ -18,6 +18,7 @@ import {
     canAddTransaction as canAddTransactionUtil,
     getMoneyRequestSpendBreakdown,
     getParentReport,
+    hasExportError as hasExportErrorUtil,
     isArchivedReport,
     isClosedReport as isClosedReportUtils,
     isCurrentUserSubmitter,
@@ -178,7 +179,8 @@ function isExportAction(report: Report, policy?: Policy) {
         return false;
     }
 
-    if (syncEnabled) {
+    const hasExportError = hasExportErrorUtil(reportActions);
+    if (syncEnabled && !hasExportError) {
         return false;
     }
 
diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts
index b79a71438601..d245dabbba53 100644
--- a/src/libs/ReportUtils.ts
+++ b/src/libs/ReportUtils.ts
@@ -173,6 +173,7 @@ import {
     isDeletedParentAction,
     isExportIntegrationAction,
     isForwardedAction,
+    isIntegrationMessageAction,
     isMarkAsClosedAction,
     isModifiedExpenseAction,
     isMoneyRequestAction,
@@ -10329,6 +10330,18 @@ function isExported(reportActions: OnyxEntry<ReportActions> | ReportAction[]) {
     return Object.values(reportActions).some((action) => isExportIntegrationAction(action));
 }
 
+function hasExportError(reportActions: OnyxEntry<ReportActions> | ReportAction[]) {
+    if (!reportActions) {
+        return false;
+    }
+
+    if (Array.isArray(reportActions)) {
+        return reportActions.some((action) => isIntegrationMessageAction(action));
+    }
+
+    return Object.values(reportActions).some((action) => isIntegrationMessageAction(action));
+}
+
 function getApprovalChain(policy: OnyxEntry<Policy>, expenseReport: OnyxEntry<Report>): string[] {
     const approvalChain: string[] = [];
     const fullApprovalChain: string[] = [];
@@ -10817,6 +10830,7 @@ export {
     getIntegrationIcon,
     canBeExported,
     isExported,
+    hasExportError,
     getHelpPaneReportType,
     hasOnlyNonReimbursableTransactions,
     getReportLastMessage,

From 29591fb3db66c9770117e4776eae30b9cb9e0d49 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Wed, 7 May 2025 00:57:32 +0200
Subject: [PATCH 06/10] update isExported logic, get reportActions from Onyx in
 the view

---
 src/components/MoneyReportHeader.tsx          |  8 +++---
 .../MoneyRequestReportPreviewContent.tsx      |  5 ++--
 src/libs/ReportPreviewActionUtils.ts          | 19 ++++++++++----
 src/libs/ReportPrimaryActionUtils.ts          |  8 +++---
 src/libs/ReportSecondaryActionUtils.ts        |  7 ++---
 src/libs/ReportUtils.ts                       | 26 +++++++++++++++++--
 6 files changed, 53 insertions(+), 20 deletions(-)

diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx
index 6a6b27eacdca..7aebb10d87ac 100644
--- a/src/components/MoneyReportHeader.tsx
+++ b/src/components/MoneyReportHeader.tsx
@@ -369,8 +369,8 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea
         if (!moneyRequestReport) {
             return '';
         }
-        return getReportPrimaryAction(moneyRequestReport, transactions, violations, policy, reportNameValuePairs);
-    }, [isPaidAnimationRunning, moneyRequestReport, reportNameValuePairs, policy, transactions, violations]);
+        return getReportPrimaryAction(moneyRequestReport, transactions, violations, policy, reportNameValuePairs, reportActions);
+    }, [isPaidAnimationRunning, moneyRequestReport, reportNameValuePairs, policy, transactions, violations, reportActions]);
 
     const confirmExport = useCallback(() => {
         setExportModalStatus(null);
@@ -497,8 +497,8 @@ function MoneyReportHeader({policy, report: moneyRequestReport, transactionThrea
         if (!moneyRequestReport) {
             return [];
         }
-        return getSecondaryReportActions(moneyRequestReport, transactions, violations, policy);
-    }, [moneyRequestReport, policy, transactions, violations]);
+        return getSecondaryReportActions(moneyRequestReport, transactions, violations, policy, reportActions);
+    }, [moneyRequestReport, policy, transactions, violations, reportActions]);
 
     const secondaryActionsImplemenation: Record<ValueOf<typeof CONST.REPORT.SECONDARY_ACTIONS>, DropdownOption<ValueOf<typeof CONST.REPORT.SECONDARY_ACTIONS>>> = {
         [CONST.REPORT.SECONDARY_ACTIONS.VIEW_DETAILS]: {
diff --git a/src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx
index 8b11a3615275..78b60255d506 100644
--- a/src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx
+++ b/src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx
@@ -193,6 +193,7 @@ function MoneyRequestReportPreviewContent({
     const [isNoDelegateAccessMenuVisible, setIsNoDelegateAccessMenuVisible] = useState(false);
 
     const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${iouReportID}`, {canBeMissing: true});
+    const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, {canBeMissing: true});
 
     const confirmPayment = useCallback(
         (type: PaymentMethodType | undefined, payAsBusiness?: boolean) => {
@@ -455,8 +456,8 @@ function MoneyRequestReportPreviewContent({
         if (isPaidAnimationRunning) {
             return CONST.REPORT.REPORT_PREVIEW_ACTIONS.PAY;
         }
-        return getReportPreviewAction(violations, iouReport, policy, transactions, reportNameValuePairs);
-    }, [isPaidAnimationRunning, violations, iouReport, policy, transactions, reportNameValuePairs]);
+        return getReportPreviewAction(violations, iouReport, policy, transactions, reportNameValuePairs, reportActions);
+    }, [isPaidAnimationRunning, violations, iouReport, policy, transactions, reportNameValuePairs, reportActions]);
 
     const reportPreviewActions = {
         [CONST.REPORT.REPORT_PREVIEW_ACTIONS.SUBMIT]: (
diff --git a/src/libs/ReportPreviewActionUtils.ts b/src/libs/ReportPreviewActionUtils.ts
index bbbaca59dc20..bf03b0ee4d7d 100644
--- a/src/libs/ReportPreviewActionUtils.ts
+++ b/src/libs/ReportPreviewActionUtils.ts
@@ -1,7 +1,7 @@
-import type {OnyxCollection} from 'react-native-onyx';
+import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
 import type {ValueOf} from 'type-fest';
 import CONST from '@src/CONST';
-import type {Policy, Report, ReportNameValuePairs, Transaction, TransactionViolation} from '@src/types/onyx';
+import type {Policy, Report, ReportAction, ReportActions, ReportNameValuePairs, Transaction, TransactionViolation} from '@src/types/onyx';
 import {isApprover as isApproverMember} from './actions/Policy/Member';
 import {getCurrentUserAccountID} from './actions/Report';
 import {
@@ -34,6 +34,8 @@ import {
     isReportApproved,
     isReportManuallyReimbursed,
     isSettled,
+    isExported as isExportedUtil,
+    hasExportError as hasExportErrorUtil,
 } from './ReportUtils';
 import {getSession} from './SessionUtils';
 import {allHavePendingRTERViolation, isReceiptBeingScanned, shouldShowBrokenConnectionViolationForMultipleTransactions} from './TransactionUtils';
@@ -134,7 +136,7 @@ function canPay(report: Report, violations: OnyxCollection<TransactionViolation[
     return policy?.role === CONST.POLICY.ROLE.ADMIN;
 }
 
-function canExport(report: Report, violations: OnyxCollection<TransactionViolation[]>, policy?: Policy) {
+function canExport(report: Report, violations: OnyxCollection<TransactionViolation[]>, policy?: Policy, reportActions?: OnyxEntry<ReportActions> | ReportAction[]) {
     const isExpense = isExpenseReport(report);
     const isExporter = policy ? isPrefferedExporter(policy) : false;
     const isReimbursed = isSettled(report);
@@ -150,7 +152,13 @@ function canExport(report: Report, violations: OnyxCollection<TransactionViolati
         return false;
     }
 
-    if (syncEnabled) {
+    const isExported = isExportedUtil(reportActions);
+    if (isExported) {
+        return false;
+    }
+
+    const hasExportError = hasExportErrorUtil(reportActions);
+    if (syncEnabled && !hasExportError) {
         return false;
     }
 
@@ -194,6 +202,7 @@ function getReportPreviewAction(
     policy?: Policy,
     transactions?: Transaction[],
     reportNameValuePairs?: ReportNameValuePairs,
+    reportActions?: OnyxEntry<ReportActions> | ReportAction[],
 ): ValueOf<typeof CONST.REPORT.REPORT_PREVIEW_ACTIONS> {
     if (!report) {
         return CONST.REPORT.REPORT_PREVIEW_ACTIONS.VIEW;
@@ -207,7 +216,7 @@ function getReportPreviewAction(
     if (canPay(report, violations, policy, reportNameValuePairs)) {
         return CONST.REPORT.REPORT_PREVIEW_ACTIONS.PAY;
     }
-    if (canExport(report, violations, policy)) {
+    if (canExport(report, violations, policy, reportActions)) {
         return CONST.REPORT.REPORT_PREVIEW_ACTIONS.EXPORT_TO_ACCOUNTING;
     }
     if (canReview(report, violations, policy, transactions)) {
diff --git a/src/libs/ReportPrimaryActionUtils.ts b/src/libs/ReportPrimaryActionUtils.ts
index ae8b92723a9d..412c18fbeacc 100644
--- a/src/libs/ReportPrimaryActionUtils.ts
+++ b/src/libs/ReportPrimaryActionUtils.ts
@@ -1,7 +1,7 @@
 import type {OnyxCollection} from 'react-native-onyx';
 import type {ValueOf} from 'type-fest';
 import CONST from '@src/CONST';
-import type {Policy, Report, ReportNameValuePairs, Transaction, TransactionViolation} from '@src/types/onyx';
+import type {Policy, Report, ReportAction, ReportNameValuePairs, Transaction, TransactionViolation} from '@src/types/onyx';
 import {isApprover as isApproverUtils} from './actions/Policy/Member';
 import {getCurrentUserAccountID} from './actions/Report';
 import {
@@ -156,7 +156,7 @@ function isPayAction(report: Report, policy?: Policy, reportNameValuePairs?: Rep
     return policy?.role === CONST.POLICY.ROLE.ADMIN;
 }
 
-function isExportAction(report: Report, policy?: Policy) {
+function isExportAction(report: Report, policy?: Policy, reportActions?: ReportAction[]) {
     if (!policy) {
         return false;
     }
@@ -173,7 +173,6 @@ function isExportAction(report: Report, policy?: Policy) {
 
     const connectedIntegration = getConnectedIntegration(policy);
     const syncEnabled = hasIntegrationAutoSync(policy, connectedIntegration);
-    const reportActions = getAllReportActions(report.reportID);
     const isExported = isExportedUtil(reportActions);
     if (isExported) {
         return false;
@@ -270,6 +269,7 @@ function getReportPrimaryAction(
     violations: OnyxCollection<TransactionViolation[]>,
     policy?: Policy,
     reportNameValuePairs?: ReportNameValuePairs,
+    reportActions?: ReportAction[],
 ): ValueOf<typeof CONST.REPORT.PRIMARY_ACTIONS> | '' {
     if (isAddExpenseAction(report, reportTransactions)) {
         return CONST.REPORT.PRIMARY_ACTIONS.ADD_EXPENSE;
@@ -299,7 +299,7 @@ function getReportPrimaryAction(
         return CONST.REPORT.PRIMARY_ACTIONS.PAY;
     }
 
-    if (isExportAction(report, policy)) {
+    if (isExportAction(report, policy, reportActions)) {
         return CONST.REPORT.PRIMARY_ACTIONS.EXPORT_TO_ACCOUNTING;
     }
 
diff --git a/src/libs/ReportSecondaryActionUtils.ts b/src/libs/ReportSecondaryActionUtils.ts
index 7e614608a083..fea79ad92122 100644
--- a/src/libs/ReportSecondaryActionUtils.ts
+++ b/src/libs/ReportSecondaryActionUtils.ts
@@ -180,7 +180,7 @@ function isCancelPaymentAction(report: Report, reportTransactions: Transaction[]
     return isPaymentProcessing && !hasDailyNachaCutoffPassed;
 }
 
-function isExportAction(report: Report, policy?: Policy): boolean {
+function isExportAction(report: Report, policy?: Policy, reportActions?: ReportAction[]): boolean {
     if (!policy) {
         return false;
     }
@@ -216,7 +216,7 @@ function isExportAction(report: Report, policy?: Policy): boolean {
     const isReportReimbursed = report.statusNum === CONST.REPORT.STATUS_NUM.REIMBURSED;
     const connectedIntegration = getConnectedIntegration(policy);
     const syncEnabled = hasIntegrationAutoSync(policy, connectedIntegration);
-    const isReportExported = isExportedUtils(getReportActions(report));
+    const isReportExported = isExportedUtils(reportActions);
     const isReportFinished = isReportApproved || isReportReimbursed || isReportClosed;
 
     return isAdmin && isReportFinished && syncEnabled && !isReportExported;
@@ -408,6 +408,7 @@ function getSecondaryReportActions(
     reportTransactions: Transaction[],
     violations: OnyxCollection<TransactionViolation[]>,
     policy?: Policy,
+    reportActions?: ReportAction[],
 ): Array<ValueOf<typeof CONST.REPORT.SECONDARY_ACTIONS>> {
     const options: Array<ValueOf<typeof CONST.REPORT.SECONDARY_ACTIONS>> = [];
 
@@ -431,7 +432,7 @@ function getSecondaryReportActions(
         options.push(CONST.REPORT.SECONDARY_ACTIONS.CANCEL_PAYMENT);
     }
 
-    if (isExportAction(report, policy)) {
+    if (isExportAction(report, policy, reportActions)) {
         options.push(CONST.REPORT.SECONDARY_ACTIONS.EXPORT_TO_ACCOUNTING);
     }
 
diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts
index 45419ffb60d9..cba30a136c21 100644
--- a/src/libs/ReportUtils.ts
+++ b/src/libs/ReportUtils.ts
@@ -10324,11 +10324,33 @@ function isExported(reportActions: OnyxEntry<ReportActions> | ReportAction[]) {
         return false;
     }
 
+    let exportIntegrationActionsCount = 0;
+    let integrationMessageActionsCount = 0;
+
     if (Array.isArray(reportActions)) {
-        return reportActions.some((action) => isExportIntegrationAction(action));
+        for (const action of reportActions) {
+            if (isExportIntegrationAction(action)) {
+                exportIntegrationActionsCount++;
+            }
+            if (isIntegrationMessageAction(action)) {
+                integrationMessageActionsCount++;
+            }
+        }
+    } else {
+        for (const action of Object.values(reportActions)) {
+            if (isExportIntegrationAction(action)) {
+                exportIntegrationActionsCount++;
+            }
+            if (isIntegrationMessageAction(action)) {
+                integrationMessageActionsCount++;
+            }
+        }
     }
 
-    return Object.values(reportActions).some((action) => isExportIntegrationAction(action));
+    // We need to make sure that there was at least one successful export to consider the report exported.
+    // We add one EXPORTINTEGRATION action to the report when we start exporting it (with pendingAction: 'add') and then another EXPORTINTEGRATION when the export finishes successfully.
+    // If the export fails, we add an INTEGRATIONS_MESSAGE action to the report, but the initial EXPORTINTEGRATION action is still present, so we compare the counts of these two actions to determine if the report was exported successfully.
+    return exportIntegrationActionsCount > integrationMessageActionsCount;
 }
 
 function hasExportError(reportActions: OnyxEntry<ReportActions> | ReportAction[]) {

From f68589fd76414bb674f3f6fd7da223383ce790f7 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Wed, 7 May 2025 01:07:45 +0200
Subject: [PATCH 07/10] fix lint

---
 src/libs/ReportPreviewActionUtils.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libs/ReportPreviewActionUtils.ts b/src/libs/ReportPreviewActionUtils.ts
index bf03b0ee4d7d..9189cdda5aa0 100644
--- a/src/libs/ReportPreviewActionUtils.ts
+++ b/src/libs/ReportPreviewActionUtils.ts
@@ -18,6 +18,7 @@ import {
     getMoneyRequestSpendBreakdown,
     getParentReport,
     getReportTransactions,
+    hasExportError as hasExportErrorUtil,
     hasMissingSmartscanFields,
     hasNoticeTypeViolations,
     hasViolations,
@@ -26,6 +27,7 @@ import {
     isClosedReport,
     isCurrentUserSubmitter,
     isExpenseReport,
+    isExported as isExportedUtil,
     isInvoiceReport,
     isIOUReport,
     isOpenReport,
@@ -34,8 +36,6 @@ import {
     isReportApproved,
     isReportManuallyReimbursed,
     isSettled,
-    isExported as isExportedUtil,
-    hasExportError as hasExportErrorUtil,
 } from './ReportUtils';
 import {getSession} from './SessionUtils';
 import {allHavePendingRTERViolation, isReceiptBeingScanned, shouldShowBrokenConnectionViolationForMultipleTransactions} from './TransactionUtils';

From 2ba5f23d95f5584acc77d52659657ceae242c123 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Wed, 7 May 2025 10:46:09 +0200
Subject: [PATCH 08/10] always display button in success style

---
 src/components/ReportActionItem/ExportWithDropdownMenu.tsx | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/components/ReportActionItem/ExportWithDropdownMenu.tsx b/src/components/ReportActionItem/ExportWithDropdownMenu.tsx
index 7858d58a6901..6b6a0ec066ff 100644
--- a/src/components/ReportActionItem/ExportWithDropdownMenu.tsx
+++ b/src/components/ReportActionItem/ExportWithDropdownMenu.tsx
@@ -11,7 +11,6 @@ import useResponsiveLayout from '@hooks/useResponsiveLayout';
 import useThemeStyles from '@hooks/useThemeStyles';
 import {savePreferredExportMethod as savePreferredExportMethodUtils} from '@libs/actions/Policy/Policy';
 import {exportToIntegration, markAsManuallyExported} from '@libs/actions/Report';
-import {hasIntegrationAutoSync as hasIntegrationAutoSyncUtils} from '@libs/PolicyUtils';
 import {canBeExported as canBeExportedUtils, getIntegrationIcon, isExported as isExportedUtils} from '@libs/ReportUtils';
 import type {ExportType} from '@pages/home/report/ReportDetailsExportPage';
 import variables from '@styles/variables';
@@ -54,7 +53,6 @@ function ExportWithDropdownMenu({
     const iconToDisplay = getIntegrationIcon(connectionName);
     const canBeExported = canBeExportedUtils(report);
     const isExported = isExportedUtils(reportActions);
-    const hasIntegrationAutoSync = hasIntegrationAutoSyncUtils(policy, connectionName);
     const flattenedWrapperStyle = StyleSheet.flatten([styles.flex1, wrapperStyle]);
 
     const dropdownOptions: Array<DropdownOption<ReportExportType>> = useMemo(() => {
@@ -109,7 +107,7 @@ function ExportWithDropdownMenu({
     return (
         <>
             <ButtonWithDropdownMenu<ReportExportType>
-                success={!hasIntegrationAutoSync}
+                success
                 pressOnEnter
                 shouldAlwaysShowDropdownMenu
                 anchorAlignment={dropdownAnchorAlignment}

From 3f39dd6cd3595534e67b352aa749b3879ea83a78 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Wed, 7 May 2025 10:58:37 +0200
Subject: [PATCH 09/10] rm policy prop

---
 src/components/MoneyReportHeaderOld.tsx                      | 2 --
 src/components/ReportActionItem/ExportWithDropdownMenu.tsx   | 5 +----
 .../MoneyRequestReportPreviewContent.tsx                     | 1 -
 src/components/ReportActionItem/ReportPreview.tsx            | 1 -
 src/components/ReportActionItem/ReportPreviewOld.tsx         | 1 -
 5 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/src/components/MoneyReportHeaderOld.tsx b/src/components/MoneyReportHeaderOld.tsx
index 6bca05419a81..3891a81ee2ae 100644
--- a/src/components/MoneyReportHeaderOld.tsx
+++ b/src/components/MoneyReportHeaderOld.tsx
@@ -517,7 +517,6 @@ function MoneyReportHeaderOld({policy, report: moneyRequestReport, transactionTh
                 {!shouldShowSelectedTransactionsButton && !!shouldShowExportIntegrationButton && !shouldUseNarrowLayout && (
                     <View style={[styles.pv2]}>
                         <ExportWithDropdownMenu
-                            policy={policy}
                             report={moneyRequestReport}
                             connectionName={connectedIntegration}
                         />
@@ -595,7 +594,6 @@ function MoneyReportHeaderOld({policy, report: moneyRequestReport, transactionTh
                         )}
                         {!shouldShowSelectedTransactionsButton && !!shouldShowExportIntegrationButton && shouldUseNarrowLayout && (
                             <ExportWithDropdownMenu
-                                policy={policy}
                                 report={moneyRequestReport}
                                 connectionName={connectedIntegration}
                             />
diff --git a/src/components/ReportActionItem/ExportWithDropdownMenu.tsx b/src/components/ReportActionItem/ExportWithDropdownMenu.tsx
index 6b6a0ec066ff..8a2fa012fce8 100644
--- a/src/components/ReportActionItem/ExportWithDropdownMenu.tsx
+++ b/src/components/ReportActionItem/ExportWithDropdownMenu.tsx
@@ -16,13 +16,11 @@ import type {ExportType} from '@pages/home/report/ReportDetailsExportPage';
 import variables from '@styles/variables';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
-import type {Policy, Report} from '@src/types/onyx';
+import type {Report} from '@src/types/onyx';
 import type {ConnectionName} from '@src/types/onyx/Policy';
 import type AnchorAlignment from '@src/types/utils/AnchorAlignment';
 
 type ExportWithDropdownMenuProps = {
-    policy: OnyxEntry<Policy>;
-
     report: OnyxEntry<Report>;
 
     connectionName: ConnectionName;
@@ -33,7 +31,6 @@ type ExportWithDropdownMenuProps = {
 };
 
 function ExportWithDropdownMenu({
-    policy,
     report,
     connectionName,
     dropdownAnchorAlignment = {
diff --git a/src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx
index 78b60255d506..e4252176940f 100644
--- a/src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx
+++ b/src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx
@@ -507,7 +507,6 @@ function MoneyRequestReportPreviewContent({
         ),
         [CONST.REPORT.REPORT_PREVIEW_ACTIONS.EXPORT_TO_ACCOUNTING]: connectedIntegration ? (
             <ExportWithDropdownMenu
-                policy={policy}
                 report={iouReport}
                 connectionName={connectedIntegration}
                 wrapperStyle={styles.flexReset}
diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx
index 5d244fc69521..49c4637ceebc 100644
--- a/src/components/ReportActionItem/ReportPreview.tsx
+++ b/src/components/ReportActionItem/ReportPreview.tsx
@@ -564,7 +564,6 @@ function ReportPreview({
         ),
         [CONST.REPORT.REPORT_PREVIEW_ACTIONS.EXPORT_TO_ACCOUNTING]: connectedIntegration ? (
             <ExportWithDropdownMenu
-                policy={policy}
                 report={iouReport}
                 connectionName={connectedIntegration}
                 wrapperStyle={styles.flexReset}
diff --git a/src/components/ReportActionItem/ReportPreviewOld.tsx b/src/components/ReportActionItem/ReportPreviewOld.tsx
index ac9fdccaf513..699f227eadfa 100644
--- a/src/components/ReportActionItem/ReportPreviewOld.tsx
+++ b/src/components/ReportActionItem/ReportPreviewOld.tsx
@@ -651,7 +651,6 @@ function ReportPreviewOld({
                                 )}
                                 {!!shouldShowExportIntegrationButton && !shouldShowSettlementButton && (
                                     <ExportWithDropdownMenu
-                                        policy={policy}
                                         report={iouReport}
                                         connectionName={connectedIntegration}
                                         wrapperStyle={styles.flexReset}

From acaba3b1954032d7619f037b5326ba63f304fcf6 Mon Sep 17 00:00:00 2001
From: Carlos Martins <cmartins@expensify.com>
Date: Wed, 7 May 2025 11:02:04 +0200
Subject: [PATCH 10/10] fix eslint

---
 src/components/ReportActionItem/ExportWithDropdownMenu.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/components/ReportActionItem/ExportWithDropdownMenu.tsx b/src/components/ReportActionItem/ExportWithDropdownMenu.tsx
index 8a2fa012fce8..a33b002d2cea 100644
--- a/src/components/ReportActionItem/ExportWithDropdownMenu.tsx
+++ b/src/components/ReportActionItem/ExportWithDropdownMenu.tsx
@@ -44,8 +44,8 @@ function ExportWithDropdownMenu({
     const {translate} = useLocalize();
     const {shouldUseNarrowLayout} = useResponsiveLayout();
     const [modalStatus, setModalStatus] = useState<ExportType | null>(null);
-    const [exportMethods] = useOnyx(ONYXKEYS.LAST_EXPORT_METHOD);
-    const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`);
+    const [exportMethods] = useOnyx(ONYXKEYS.LAST_EXPORT_METHOD, {canBeMissing: true});
+    const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, {canBeMissing: true});
 
     const iconToDisplay = getIntegrationIcon(connectionName);
     const canBeExported = canBeExportedUtils(report);
