Fix: preserve iouType for invoice/pay when reselecting a participant on confirm page#94536
Conversation
Co-authored-by: thelullabyy <thelullabyy@users.noreply.github.com>
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
|
@MelvinBot You are using the wrong PR description template. Please use this one https://raw.githubusercontent.com/Expensify/App/main/.github/PULL_REQUEST_TEMPLATE.md After that replace all Finally, open PR for review |
|
@thelullabyy Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
|
🤖 Done, @thelullabyy:
|
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppAndroid: mWeb ChromeiOS: HybridAppiOS: mWeb SafariMacOS: Chrome / SafariScreen.Recording.2026-06-26.at.00.23.03.movScreen.Recording.2026-06-26.at.00.18.38.mov |
thelullabyy
left a comment
There was a problem hiding this comment.
Agree with the solution
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 27173b3fd6
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| navigation.setParams({iouType: CONST.IOU.TYPE.TRACK}); | ||
| } else { | ||
| if (iouType !== CONST.IOU.TYPE.SPLIT && iouType !== CONST.IOU.TYPE.CREATE) { | ||
| if (iouType === CONST.IOU.TYPE.SUBMIT || iouType === CONST.IOU.TYPE.TRACK) { |
There was a problem hiding this comment.
Update the backing report when preserving pay/invoice
When a user in the PAY/INVOICE confirmation page opens the To picker and selects a different recipient, this branch now preserves the route type but the handler still only writes participants and never updates transaction.reportID/the route report. The rest of this screen derives report from the old report ID, and sendMoney/sendInvoice pass that stale chat or invoice room to the API, so the UI can show the newly selected participant while the payment/invoice is created in the previous chat/room. Please mirror the participant-step report update when keeping PAY/INVOICE here.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
@thelullabyy I checked this — it's a false positive for this PR. This PR only changes which iouType is preserved (which confirm page / submit branch is used); it doesn't touch transaction.reportID handling or report resolution at all. Both before and after, the recipient branch calls only setMoneyRequestParticipants, and the destination report is resolved at send time from the selected participant, not from a stale ID.
Two reasons the claim doesn't hold for the realistic flows:
- PAY: The "To" picker is only interactive when
transaction.isFromGlobalCreateis true (MoneyRequestConfirmationList.tsx:252), and PAY is never started from the global FAB (only from a 1:1 chat). So the picker can't be reopened in the pay flow — that half of the concern is unreachable. - INVOICE (from FAB): The route
reportIDis a freshly-generated optimistic ID with no report in Onyx, soresolveReportForMoneyRequestreturnsundefinedandsendInvoicederives the room from the selected participant via theexistingInvoiceReportpath (useExpenseSubmission.ts:909). Destination correctly follows the new recipient.
One narrow pre-existing edge case (not a blocker)
There is a genuine stale-room path: invoice-from-FAB → first pick a recipient who already has an existing invoice room → then reselect a different recipient on the confirm page. In that case transaction.reportID still points at the first recipient's room, and resolveReportForMoneyRequest returns it because the route report is undefined (IOUUtils.ts:504-507).
However, this is pre-existing and not introduced or exposed by this PR — pre-PR, handleParticipantsAdded also never updated transaction.reportID (it only flipped the iouType to create, which is the different bug this PR fixes). It lives entirely in resolveReportForMoneyRequest + the participants-step report write, none of which this diff touches. Worth a separate follow-up issue, not a reason to hold this PR.
So I'd resolve this comment — the bug it describes isn't caused by this change.
|
@MelvinBot Please check this comment #94536 (comment) |
|
🚧 puneetlath has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/puneetlath in version: 9.4.21-2 🚀
|
Explanation of Change
On the confirmation page, tapping the To field opens the inline
ParticipantPicker. When a participant is (re)selected,handleParticipantsAddedrannavigation.setParams({iouType: 'create'})for anyiouTypethat wasn'tsplitorcreate. For the invoice flow (iouType === 'invoice') — and equally the pay-someone flow (iouType === 'pay') — this rewrote the route param frominvoice/paytocreate, so the confirmation page re-rendered as a manual expense confirm page instead of the invoice/pay confirm page.The conversion to
createis only correct for the manual-expense flows (submit/track), which is exactly what the siblingparticipantPickerIOUTypealready encodes (IOURequestStepConfirmation.tsx:293). This change narrows the guard inhandleParticipantsAddedto mirror that intent — only convert tocreatewheniouTypeissubmitortrack— soinvoiceandpaykeep their route param and the correct confirm page is shown after reselecting a participant.The offending PR (#94134) was reverted, restoring the
NEW_MANUAL_EXPENSE_FLOWbeta gate, but this latent bug in the handler remained. This fixes the underlying bug so it doesn't resurface when the new manual expense flow is re-enabled.Fixed Issues
$ #94263
PROPOSAL: #94263 (comment)
Tests
Offline tests
Same as tests.
QA Steps
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)Avatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari