From 12dd146fdac6457bb087ad63789f46004d90750d Mon Sep 17 00:00:00 2001 From: dmkt9 Date: Tue, 16 Dec 2025 17:37:01 +0700 Subject: [PATCH 1/2] Fix - Duplicate Expense Cards Appear in Report When Adding a Single Expense from Empty State --- src/libs/actions/Transaction.ts | 35 +++++++++++++++++---------------- src/pages/home/ReportScreen.tsx | 2 +- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/libs/actions/Transaction.ts b/src/libs/actions/Transaction.ts index 614c3902de6a1..2121f6446fe08 100644 --- a/src/libs/actions/Transaction.ts +++ b/src/libs/actions/Transaction.ts @@ -823,6 +823,23 @@ function changeTransactionsReport( const oldReportID = isUnreportedExpense ? CONST.REPORT.UNREPORTED_REPORT_ID : transaction.reportID; const oldReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${oldReportID}`]; + const isUnreported = reportID === CONST.REPORT.UNREPORTED_REPORT_ID; + const optimisticMoneyRequestReportActionID = rand64(); + + const originalMessage = getOriginalMessage(oldIOUAction) as OriginalMessageIOU; + const newIOUAction = { + ...oldIOUAction, + originalMessage: { + ...originalMessage, + IOUReportID: reportID, + type: isUnreported ? CONST.IOU.REPORT_ACTION_TYPE.TRACK : CONST.IOU.REPORT_ACTION_TYPE.CREATE, + }, + reportActionID: optimisticMoneyRequestReportActionID, + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + actionName: oldIOUAction?.actionName ?? CONST.REPORT.ACTIONS.TYPE.MOVED_TRANSACTION, + created: oldIOUAction?.created ?? DateUtils.getDBTime(), + }; + // 1. Optimistically change the reportID on the passed transactions optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, @@ -832,6 +849,7 @@ function changeTransactionsReport( comment: { hold: null, }, + ...(oldIOUAction ? {linkedTrackedExpenseReportAction: newIOUAction} : {}), }, }); @@ -940,7 +958,6 @@ function changeTransactionsReport( const allowNegative = shouldEnableNegative(newReport); // 3. Keep track of the new report totals - const isUnreported = reportID === CONST.REPORT.UNREPORTED_REPORT_ID; const targetReportID = isUnreported ? selfDMReportID : reportID; const {amount: transactionAmount = 0, currency: transactionCurrency} = getTransactionDetails(transaction, undefined, undefined, allowNegative) ?? {}; const oldReportTotal = oldReport?.total ?? 0; @@ -974,22 +991,6 @@ function changeTransactionsReport( } // 4. Optimistically update the IOU action reportID - const optimisticMoneyRequestReportActionID = rand64(); - - const originalMessage = getOriginalMessage(oldIOUAction) as OriginalMessageIOU; - const newIOUAction = { - ...oldIOUAction, - originalMessage: { - ...originalMessage, - IOUReportID: reportID, - type: isUnreported ? CONST.IOU.REPORT_ACTION_TYPE.TRACK : CONST.IOU.REPORT_ACTION_TYPE.CREATE, - }, - reportActionID: optimisticMoneyRequestReportActionID, - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - actionName: oldIOUAction?.actionName ?? CONST.REPORT.ACTIONS.TYPE.MOVED_TRANSACTION, - created: oldIOUAction?.created ?? DateUtils.getDBTime(), - }; - const trackExpenseActionableWhisper = isUnreportedExpense ? getTrackExpenseActionableWhisper(transaction.transactionID, selfDMReportID) : undefined; if (oldIOUAction) { diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 2cad7de046608..733d3befca4b9 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -880,7 +880,7 @@ function ReportScreen({route, navigation}: ReportScreenProps) { // - IOU action already exists (not a legacy transaction) // - Transaction is pending addition (new transaction, not legacy) const iouAction = getIOUActionForReportID(reportID, transaction.transactionID); - if (iouAction || transaction?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) { + if (iouAction || transaction?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD || !!transaction.linkedTrackedExpenseReportAction?.childReportID) { return; } From 69ad05b50478cf539eedc3c10768ed79d35b698b Mon Sep 17 00:00:00 2001 From: dmkt9 Date: Fri, 19 Dec 2025 21:29:41 +0700 Subject: [PATCH 2/2] Fix - Duplicate Expense Cards Appear in Report When Adding a Single Expense from Empty State --- src/pages/Search/SearchMoneyRequestReportPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Search/SearchMoneyRequestReportPage.tsx b/src/pages/Search/SearchMoneyRequestReportPage.tsx index 708d1829cbc1a..a7ce824920c85 100644 --- a/src/pages/Search/SearchMoneyRequestReportPage.tsx +++ b/src/pages/Search/SearchMoneyRequestReportPage.tsx @@ -157,7 +157,7 @@ function SearchMoneyRequestReportPage({route}: SearchMoneyRequestPageProps) { } const iouAction = getIOUActionForTransactionID(reportActions, transaction.transactionID); - if (iouAction || transaction?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD) { + if (iouAction || transaction?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD || !!transaction.linkedTrackedExpenseReportAction?.childReportID) { return; }