Fix bulk expense merge opening self DM instead of transaction thread#89360
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fdc20abd97
ℹ️ About Codex in GitHub
Your team has set up Codex to 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 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (routeName !== SCREENS.RIGHT_MODAL.SEARCH_REPORT) { | ||
| return false; |
There was a problem hiding this comment.
Treat search money request route as search origin
isSearchOriginForMerge returns false for every route except SCREENS.RIGHT_MODAL.SEARCH_REPORT, so merges initiated from SCREENS.RIGHT_MODAL.SEARCH_MONEY_REQUEST_REPORT are now classified as non-search. In that flow we lose the isOnSearch flag and fall back to the non-search post-merge navigation path, which can reopen/dismiss to the wrong destination instead of the search transaction context.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
@rojiphil, this makes sense, but I couldn't reproduce this. Are you able to reproduce this? thanks.
There was a problem hiding this comment.
This theoretically seems like a legit concern
There was a problem hiding this comment.
isSearchOriginForMerge is called in a component that only mounts under MoneyRequestHeader. However, MoneyRequestHeader shows with route.name of SearchMoneyRequestReport only for transaction thread report within SearchMoneyRequestReportPage. And SearchMoneyRequestReportPage always displays expense report and not transaction thread report. So, theoretically, the scenario looks unreachable with the current navigation.
|
@rojiphil, gentle bump. thanks. |
|
@rojiphil, could you please take a look at this pr? thanks. |
|
@marufsharifi Due to multiple PRs here, it's becoming a little messy here. |
@rojiphil, sorry, I've added the flow in the PR author checklist. Thanks. |
|
@rojiphil, merged the main and resolved the conflict; it is ready for your review. thanks. |
rojiphil
left a comment
There was a problem hiding this comment.
@marufsharifi The previous PR review comments are still pending. Anyway, I have copied it here so that we do not miss.
Also, regarding the concern mentioned here, can you please share the test steps that would fail if we do not include those changes? I would ilke to explore if we can completely avoid going through all the transactions again.
- delete getTargetTransactionThreadReportIDForSearchSelection from MergeTransactionUtils - update MergeTransactionUtilsTest to cover getTargetTransactionThreadReportIDForSelection directly - keep behavior unchanged while simplifying the helper surface
@rojiphil, I've updated the PR checklist regarding this. |
|
@rojiphil, I've addressed your comment. Could you please take another look when you get a chance? thanks. |
rojiphil
left a comment
There was a problem hiding this comment.
Thanks @marufsharifi for addressing the concern regarding getTargetTransactionThreadReportIDForSearchSelection.
Regarding the other concern, I am still not clear. I have left a comment below. Please have a look.
|
|
||
| mergedTransactions[key] = { | ||
| ...onyxTransaction, | ||
| transactionThreadReportID: snapshotTransaction.transactionThreadReportID, |
There was a problem hiding this comment.
regarding the concern mentioned #83825 (comment), can you please share the test steps that would fail if we do not include those changes.
@rojiphil, I've updated the PR checklist regarding this.
Sorry. I did not understand the statement. What I wanted is to explore is whether we can avoid going through all the transactions again. Are you saying that the test steps in PR checklist would fail if we do not include this change?
There was a problem hiding this comment.
@rojiphil, Yes, the second flow in the PR checklist will fail without this change.
There was a problem hiding this comment.
Sorry. I still seem to be missing something. I just tested flow-2 without these changes and it seemed to work. What exactly are we fixing here?
89360-test-001.mp4
There was a problem hiding this comment.
Thanks, this helped clarify the concern.
After rechecking this flow, I’m no longer able to reproduce the stale-overlap case that this fallback loop in useAllTransactions() was intended to protect. Since I couldn’t validate the issue with a reliable repro anymore, I removed the loop and the related test coverage that was specifically asserting that behavior.
At this point, I think it’s better to avoid carrying forward a defensive merge path that we can’t currently justify with a reproducible UI scenario. If we later find a concrete repro showing that search snapshot data is still observably fresher than the overlapping Onyx transaction in this flow, we can add back a targeted fix with clearer evidence.
|
@rojiphil, friendly bump. thanks. |
|
@rojiphil, gentle bump. thanks. |
|
@marufsharifi Will come back to this soon. Sorry for the delay. |
Treat SEARCH_MONEY_REQUEST_REPORT as a valid merge search origin.
@rojiphil, I made this change. Please feel free to check this out. I am still testing all flows again. thanks. |
|
There are conflicts now. |
rojiphil
left a comment
There was a problem hiding this comment.
@MonilBhavsar Recent changes also LGTM.
Over to you.
89360-web-chrome-003.mp4
|
@MonilBhavsar, could you please check this? thanks. |
MonilBhavsar
left a comment
There was a problem hiding this comment.
Looking good. Appreciate adding good test coverage!
|
🚧 @MonilBhavsar 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! 🧪🧪
|
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚀 Deployed to staging by https://github.com/MonilBhavsar in version: 9.4.0-0 🚀
Bundle Size Analysis (Sentry): |
Help site review — no docs changes requiredI reviewed the changes in this PR against the help site articles under Why:
In short: this restores intended behavior rather than changing a documented feature, so the help site is already correct. @marufsharifi, if you'd still like a docs note added (e.g., a line clarifying where you land after merging), let me know and I'll draft a help site PR. |
|
Deploy Blocker #92846 was identified to be related to this PR. |
…nse-open-transaction-thread [CP Staging] Revert "Merge pull request #89360 from marufsharifi/fix/bulk-merge-ex…
|
@MonilBhavsar @marufsharifi I revert this PR due to: #92846, in the revert PR: #92935 I posted a video of how the flow was working after revert. |
|
🚀 Deployed to production by https://github.com/Julesssss in version: 9.4.0-7 🚀
|
|
🚀 Deployed to staging by https://github.com/MonilBhavsar in version: 9.4.1-0 🚀
Bundle Size Analysis (Sentry): |
|
🤖 Help site review: no documentation changes required. I reviewed this PR against the help site articles under Why no docs change is needed:
Since the fix is a behind-the-scenes navigation correction and doesn't alter any documented behavior, no draft help site PR was created. If you believe the help site should explicitly call out where you land after a merge, let me know with |
|
🚀 Deployed to production by https://github.com/Julesssss in version: 9.4.1-6 🚀
|
Explanation of Change
Bulk expense merge now follows the same destination behavior as individual merge.
Before this update, bulk merge from
Reports > Expensescould open the wrong place (for example, self-DM) after merge because the app sometimes lost the intended transaction-thread destination during the multi-step merge flow.Now, the app determines the correct target transaction thread earlier in the merge process and carries that destination through to confirmation. That makes post-merge navigation consistent and predictable across flows, especially when merging workspace and
self-DMexpenses from search.follow-up of #79766
Fixed Issues
$ #83257
PROPOSAL:
Tests
Flow 1:
Flow 2:
Offline tests
Same as Tests.
QA Steps
Same as Tests.
// TODO: These must be filled out, or the issue title must include "[No QA]."
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, 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.ScrollViewcomponent to make it scrollable when more elements are added to the page.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.native.mp4
Android: mWeb Chrome
android.web.mp4
iOS: Native
Screen.Recording.2026-03-06.at.5.49.31.PM.mov
iOS: mWeb Safari
Screen.Recording.2026-03-06.at.5.52.45.PM.mov
MacOS: Chrome / Safari
Flow 1:
web.mp4
Flow 2:
Screen.Recording.2026-05-07.at.1.21.19.PM.mov