diff --git a/src/libs/actions/IOU/Split.ts b/src/libs/actions/IOU/Split.ts index 91911fa04a02..33e08e6b4d12 100644 --- a/src/libs/actions/IOU/Split.ts +++ b/src/libs/actions/IOU/Split.ts @@ -143,6 +143,9 @@ type CreateDistanceRequestInformation = { previousOdometerDraft?: OnyxEntry; delegateAccountID: number | undefined; isTrackIntentUser: boolean | 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 & { @@ -1958,6 +1961,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest previousOdometerDraft, delegateAccountID, isTrackIntentUser, + optimisticChatReportID, } = distanceRequestInformation; const {policy, policyCategories, policyTagList, policyRecentlyUsedCategories, policyRecentlyUsedTags} = policyParams; const parsedComment = getParsedComment(transactionParams.comment); @@ -2143,6 +2147,7 @@ function createDistanceRequest(distanceRequestInformation: CreateDistanceRequest optimisticReportPreviewActionID, delegateAccountID, isTrackIntentUser, + optimisticChatReportID, }); onyxData = moneyRequestOnyxData; diff --git a/src/pages/iou/request/step/confirmation/useExpenseSubmission.ts b/src/pages/iou/request/step/confirmation/useExpenseSubmission.ts index e3944a166934..99be02c1a73e 100644 --- a/src/pages/iou/request/step/confirmation/useExpenseSubmission.ts +++ b/src/pages/iou/request/step/confirmation/useExpenseSubmission.ts @@ -748,9 +748,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, diff --git a/tests/actions/IOUTest/SplitTest.ts b/tests/actions/IOUTest/SplitTest.ts index 4aabd56cfbef..0878ef47450c 100644 --- a/tests/actions/IOUTest/SplitTest.ts +++ b/tests/actions/IOUTest/SplitTest.ts @@ -7662,6 +7662,22 @@ 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)) ?? [];