Fix merge transaction receipt preview showing incorrect eReceipt - #73274
Conversation
- Add !isImageSource check to prevent eReceipt rendering when source transaction receipt is selected - During merge flow, target transaction data hasn't been merged yet, causing incorrect eReceipt display - Add explanatory comment for the logic and reference GitHub issue Expensify#70415 - Fixes issue where receipt preview on merge confirm page shows wrong receipt
|
@dominictb 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] |
|
@dominictb any ETA on reviewing this? |
|
I'm a bit skeptical about the expected behavior here. From the design doc:
It's been working that way when merging card and cash expenses. So logically, we should keep the eReceipt and discard the image receipt because the eReceipt reflects the correct amount and currency of the kept card expense and is IRS-compliant. Alternatively, we can show the receipt select step to toggle between the eReceipt and custom receipt. @garrettmknight @youssef-lr What do you think should be the expected behavior here? I also see in your screenshot, it's showing Amount field here which should not be there. I cannot reproduce this but you can debug on your side:
|
According to the design document, I believe the intention is to treat the eReceipt as 'no receipt' and automatically select the uploaded receipt. |
|
Root cause is |
|
Screen.Recording.2025-10-29.at.18.02.20.movThe source transaction in the above recording has a PDF receipt. |
|
When merging a card transaction, amount and currency must be retained. Root cause is a personal card transaction is not a managed card transaction ( App/src/libs/MergeTransactionUtils.ts Line 199 in 809575d I think we should reuse this check instead (check by Can you check for other places in the merge flow where we're using |
| const isVideo = (typeof source === 'string' && Str.isVideo(source)) || (file?.name && Str.isVideo(file.name)); | ||
| const firstRenderRoute = useFirstRenderRoute(); | ||
| const isInFocusedModal = firstRenderRoute.isFocused && isFocused === undefined; | ||
| const isImageSource = typeof source !== 'function' && !!checkIsFileImage(source, file?.name); |
There was a problem hiding this comment.
This feels like a workaround to me. I suggested to compute the imageSource here instead:
Where you check if there's mergeTransactionID URL param, use the receipt from mergeTransaction_ Onyx instead.
There was a problem hiding this comment.
We already used a receipt from mergeTransaction here
App/src/pages/TransactionReceiptPage.tsx
Lines 44 to 49 in 9c9932b
The root cause is that we fetch transaction from Onyx again here, it hasn't contain the receipt from mergeTransaction yet.
There was a problem hiding this comment.
I think about another solution that we will pass transaction object here down to AttachmentView component. Wdyt?
…ipt" This reverts commit 4d9a2c0.
…r merge flow When displaying receipts in merge transaction flow, TransactionReceiptPage calculates a merged transaction with the correct receipt data, but this wasn't being passed down to AttachmentModal and AttachmentView. Both components were fetching fresh transactions from Onyx, which don't have the merged receipt data yet, causing incorrect receipt display. Changes: - Add optional transaction prop to AttachmentModal and AttachmentView - Use passed transaction if provided, otherwise fall back to Onyx fetch - Pass merged transaction from TransactionReceiptPage through component tree
|
@dominictb I fixed this bug. Please feel free to take a look at this PR again. Screen.Recording.2025-11-02.at.23.40.33.mov |
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
|
@dominictb can you re-review, please? |
|
I'm not sure why all the eReceipts didn't show for me.
Second weird thing is they show in receipt preview in search page but not in report RHP: Screen.Recording.2025-11-03.at.22.23.33.movAsking here |
|
cc @youssef-lr again on this bug #73274 (comment). Not a priority/blocker but can be in your backlog. |
|
Are we blocked on that, or can this PR be reviewed? |
|
The approach seems good but I need eReceipts visibility to test it and edge cases. So we're blocked. |
|
Cool, seems like @rayane-d is getting close! |
|
Conflicts here! |
When displaying receipts in merge transaction flow, TransactionReceiptPage calculates a merged transaction with the correct receipt data, but this wasn't being passed down to AttachmentModal and AttachmentView. Both components were fetching fresh transactions from Onyx, which don't have the merged receipt data yet, causing incorrect receipt display.
|
Resolved conflict. TypeScript check is also failing on the main branch https://expensify.slack.com/archives/C01GTK53T8Q/p1762834499865619 PR is ready to review @dominictb |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppScreen.Recording.2025-11-12.at.22.43.56-compressed.movAndroid: mWeb ChromeiOS: HybridAppScreen.Recording.2025-11-12.at.22.16.05-compressed.moviOS: mWeb SafariScreen.Recording.2025-11-12.at.22.22.27-compressed.movMacOS: Chrome / SafariScreen.Recording.2025-11-11.at.23.21.00-compressed.movMacOS: Desktop |
joekaufmanexpensify
left a comment
There was a problem hiding this comment.
Good from a product perspective 👍
|
Also bump @youssef-lr on this BE bug #73274 (comment) |
Will work on a quick fix today |
|
I have a PR in review that adds the hasEReceipt field |
…e with photo receipt (source) while offline, it still shows the eReceipt until back online
|
@dominictb I fixed this bug in this commit |
| return data.onyxData; | ||
| const onyxData = data.onyxData; | ||
|
|
||
| onyxData.optimisticData?.push({ |
There was a problem hiding this comment.
NAB: Can't we just do this?
| onyxData.optimisticData?.push({ | |
| data.onyxData.optimisticData?.push({ |
There was a problem hiding this comment.
I prefer keep current implementation because we gonna add more in "Merge distance" PR
|
🚀 Deployed to staging by https://github.com/youssef-lr in version: 9.2.58-0 🚀
|
|
🚀 Deployed to production by https://github.com/cristipaval in version: 9.2.58-3 🚀
|






Explanation of Change
When displaying receipts in merge transaction flow,
TransactionReceiptPagecalculates a merged transaction with the correct receipt data, but this wasn't being passed down toAttachmentModalandAttachmentView. Both components were fetching fresh transactions from Onyx, which don't have the merged receipt data yet, causing incorrect receipt display.Fixed Issues
$ #70415
PROPOSAL:
Tests
Same as QA
Offline tests
Same as QA
QA Steps
// TODO: These must be filled out, or the issue title must include "[No QA]."
Precondition:
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectioncanBeMissingparam foruseOnyxtoggleReportand 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
Screen.Recording.2025-10-23.at.17.55.52.android.mov
Android: mWeb Chrome
Screen.Recording.2025-10-23.at.17.52.44.android.chrome.mov
iOS: Native
Screen.Recording.2025-10-23.at.18.08.33.mov
iOS: mWeb Safari
Screen.Recording.2025-10-23.at.17.59.32.ios.safari.mov
MacOS: Chrome / Safari
Screen.Recording.2025-10-23.at.09.03.22.web.mov
MacOS: Desktop
Screen.Recording.2025-10-23.at.17.47.58.desktop.mov