From 1775cc28169e5663829019d6413ee4a1f6e5d890 Mon Sep 17 00:00:00 2001 From: "thelullabyy (via MelvinBot)" Date: Thu, 9 Jul 2026 23:51:25 +0000 Subject: [PATCH 1/3] Fix: keep optimistic reportID coherent for brand-new P2P distance recipient Co-authored-by: thelullabyy --- src/libs/actions/IOU/Split.ts | 4 ++++ .../iou/request/step/confirmation/useExpenseSubmission.ts | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/libs/actions/IOU/Split.ts b/src/libs/actions/IOU/Split.ts index 09941faf3f25..1ea8b3048874 100644 --- a/src/libs/actions/IOU/Split.ts +++ b/src/libs/actions/IOU/Split.ts @@ -142,6 +142,8 @@ type CreateDistanceRequestInformation = { shouldDeferAutoSubmit?: boolean; previousOdometerDraft?: OnyxEntry; delegateAccountID: number | undefined; + /** Optimistic chat reportID to build the new chat report at, so it matches the ID the confirmation screen already subscribed to (brand-new P2P recipient). */ + optimisticChatReportID?: string; }; type CreateSplitsTransactionParams = Omit & { @@ -1933,6 +1935,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest shouldDeferAutoSubmit, previousOdometerDraft, delegateAccountID, + optimisticChatReportID, } = distanceRequestInformation; const {policy, policyCategories, policyTagList, policyRecentlyUsedCategories, policyRecentlyUsedTags} = policyParams; const parsedComment = getParsedComment(transactionParams.comment); @@ -2116,6 +2119,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest betas, optimisticReportPreviewActionID, delegateAccountID, + optimisticChatReportID, }); onyxData = moneyRequestOnyxData; diff --git a/src/pages/iou/request/step/confirmation/useExpenseSubmission.ts b/src/pages/iou/request/step/confirmation/useExpenseSubmission.ts index 3a7a2107de51..6e86724a22e8 100644 --- a/src/pages/iou/request/step/confirmation/useExpenseSubmission.ts +++ b/src/pages/iou/request/step/confirmation/useExpenseSubmission.ts @@ -732,9 +732,17 @@ function useExpenseSubmission(params: UseExpenseSubmissionParams) { return; } + // For a brand-new P2P recipient (no existing chat), the confirmation screen has already committed the draft + // transaction to a freshly generated optimistic reportID via setTransactionReport. Build the optimistic chat + // report at that same ID so the report the screen subscribes to is the one that actually gets created. + // Otherwise the builder mints a different ID and the screen hangs waiting on a report that never materializes. + const isBrandNewP2PRecipient = !report && !participant.isPolicyExpenseChat && !participant.reportID; + const optimisticChatReportID = isBrandNewP2PRecipient && !!transaction.reportID && transaction.reportID !== CONST.REPORT.UNREPORTED_REPORT_ID ? transaction.reportID : undefined; + const {chatReportID: distanceChatReportID, transactionID: distanceTransactionID} = createDistanceRequestIOUActions({ report, participants: selectedParticipantsForRequest, + optimisticChatReportID, currentUserLogin: currentUserPersonalDetails.login ?? '', currentUserAccountID: currentUserPersonalDetails.accountID, iouType, From 1cea8fcd631131046de9c91e8e7ef982d3c63c5b Mon Sep 17 00:00:00 2001 From: "thelullabyy (via MelvinBot)" Date: Thu, 9 Jul 2026 23:56:44 +0000 Subject: [PATCH 2/3] Add regression test: distance createDistanceRequest honors optimisticChatReportID Co-authored-by: thelullabyy --- tests/actions/IOUTest/SplitTest.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/actions/IOUTest/SplitTest.ts b/tests/actions/IOUTest/SplitTest.ts index 98471a7be180..0be3e0dee30b 100644 --- a/tests/actions/IOUTest/SplitTest.ts +++ b/tests/actions/IOUTest/SplitTest.ts @@ -7546,6 +7546,21 @@ describe('createDistanceRequest', () => { expect(result.transactionID).toBeTruthy(); }); + it('builds the optimistic chat report at the provided optimisticChatReportID for a brand-new P2P recipient — so it matches the id the confirmation screen already subscribed to', async () => { + const recentWaypoints = (await getOnyxValue(ONYXKEYS.NVP_RECENT_WAYPOINTS)) ?? []; + // The confirmation screen commits the draft transaction to this generated id before submit. The action must + // create the optimistic chat at the same id, otherwise the screen hangs waiting on a report that never exists. + const optimisticChatReportID = '987654321'; + + const result = createDistanceRequest({ + ...getDefaultDistanceRequestParams(undefined, {amount: 1000}, recentWaypoints), + participants: [{accountID: CARLOS_ACCOUNT_ID, login: CARLOS_EMAIL}], + optimisticChatReportID, + }); + + expect(result.chatReportID).toBe(optimisticChatReportID); + }); + it('returns chatReportID with a null iouReport for a split distance request — the UI can only navigate via chatReportID', async () => { const recentWaypoints = (await getOnyxValue(ONYXKEYS.NVP_RECENT_WAYPOINTS)) ?? []; From ba79b7d9de38510a696b642a609a8db64f9de028 Mon Sep 17 00:00:00 2001 From: "thelullabyy (via MelvinBot)" Date: Mon, 13 Jul 2026 17:03:43 +0000 Subject: [PATCH 3/3] Apply review suggestions: add blank line before doc comment per style guide Co-authored-by: thelullabyy --- src/libs/actions/IOU/Split.ts | 1 + tests/actions/IOUTest/SplitTest.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/libs/actions/IOU/Split.ts b/src/libs/actions/IOU/Split.ts index 1ea8b3048874..9eb2d0243672 100644 --- a/src/libs/actions/IOU/Split.ts +++ b/src/libs/actions/IOU/Split.ts @@ -142,6 +142,7 @@ type CreateDistanceRequestInformation = { shouldDeferAutoSubmit?: boolean; previousOdometerDraft?: OnyxEntry; delegateAccountID: number | undefined; + /** Optimistic chat reportID to build the new chat report at, so it matches the ID the confirmation screen already subscribed to (brand-new P2P recipient). */ optimisticChatReportID?: string; }; diff --git a/tests/actions/IOUTest/SplitTest.ts b/tests/actions/IOUTest/SplitTest.ts index 0a950f7c73f9..4e6e24192554 100644 --- a/tests/actions/IOUTest/SplitTest.ts +++ b/tests/actions/IOUTest/SplitTest.ts @@ -7548,6 +7548,7 @@ describe('createDistanceRequest', () => { it('builds the optimistic chat report at the provided optimisticChatReportID for a brand-new P2P recipient — so it matches the id the confirmation screen already subscribed to', async () => { const recentWaypoints = (await getOnyxValue(ONYXKEYS.NVP_RECENT_WAYPOINTS)) ?? []; + // The confirmation screen commits the draft transaction to this generated id before submit. The action must // create the optimistic chat at the same id, otherwise the screen hangs waiting on a report that never exists. const optimisticChatReportID = '987654321';