Show expense type and commercial card feed name on the expense view - #99132
Conversation
Add the transaction type next to Amount and show reimbursable state
on both sides. Move Purchase/Converted underneath as a hint. Show
{feed name} - {last4} for commercial card feed cards instead of the
masked PAN.
|
@ZhenjaHorbach 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] |
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 14a3be4141
ℹ️ 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".
getCustomFeedNameFromFeeds scanned every domain the user belongs to and returned the first nickname matching the feed key, so a user in multiple domains with the same commercial feed could see another domain's nickname. Read the nickname directly from the card's own SHARED_NVP_PRIVATE_DOMAIN_MEMBER entry instead, keyed by card.fundID, matching the existing search card-grouping lookup.
…or Personal card A plain "Card" doesn't say who issued it. Branch the Amount type label the same way the search table's Type column tooltip already does, so an Expensify Card, a feed-managed company card, and an unmanaged personal card each show their own label instead of all collapsing to "Card". Verified live: seeded a fake commercial-feed transaction (managedCard, bank vcf) via Onyx.merge on a real tracked expense and confirmed the Amount row reads "Amount · Company card" and the Card field reads "Acme Visa Cards - 2554" using the custom feed nickname.
…table TypeCell's tooltip already split Card into Expensify Card, Company card, and Personal card. Extract that into getDetailedExpenseTypeTranslationKey in TransactionUtils so MoneyRequestView reuses it instead of duplicating the branch, and drop the now-unnecessary CompanyCardFeed cast in getCommercialFeedCardDescription (companyCardNicknames is already keyed by CardFeedWithNumber).
TypeCell's tooltip special-cased isPendingCardTransaction and isTravelBillingCard before falling back to the shared type label helper. Move both checks into getDetailedExpenseTypeTranslationKey itself so MoneyRequestView's Amount row picks them up too, and TypeCell's tooltip collapses to a single delegating call.
…main MoneyRequestView subscribed to the entire SHARED_NVP_PRIVATE_DOMAIN_MEMBER collection to read one entry. Read only the transaction's own domain key instead, matching the TRANSACTION_BACKUP/POLICY_TAGS pattern already used in this file. Also drops a stray duplicated JSDoc opener left over from an earlier edit.
|
@joekaufmanexpensify Flavia is out this week, would you be up for swapping in on the product review? |
|
yep! |
|
Videos are looking neat to me. When adhoc is ready I'll test on my account to see how it looks with currency conversion etc. |
|
🚧 joekaufmanexpensify has triggered a test Expensify/App build. You can view the workflow run here. |
This comment has been minimized.
This comment has been minimized.
|
@ZhenjaHorbach kindly bump |
Reviewer Checklist
Screenshots/VideosAndroid: HybridApp2026-08-26.15.24.59.movAndroid: mWeb Chrome2026-08-26.15.22.30.moviOS: HybridApp2026-08-26.15.20.23.moviOS: mWeb Safari2026-08-26.15.17.27.movMacOS: Chrome / Safari2026-08-26.15.09.17.mov |
|
LGTM! |
|
Commercial card stuff looks good to me |
|
I'm not sure that it's related to this PR since we didn't touch this code |
|
checking 👀 |
|
@joekaufmanexpensify @ZhenjaHorbach I think this is pre-existing bug. I can reproduce on stagin as well REC-20260826214022.mp4RCAOffending PR: #9607 "Refactor GetLocalCurrency" (luacmartins, merged 2022-07-16), commit That PR deleted // IOUCurrencySelection.js and WorkspaceSettingsPage.js — both removed
- componentDidMount() { this.fetchData(); }
- componentDidUpdate(prevProps) {
- if (!prevProps.network.isOffline || this.props.network.isOffline) { return; }
- this.fetchData(); // ← re-fetch when coming back online
- }
- fetchData() { PersonalDetails.getCurrencyList(); }That was the self-heal path. After it, The chain:
So i think this is out of scope and we can fix as a follow up? what do you think guys? |
|
It's not our issue😁 |
|
@ZhenjaHorbach I mean I am interested in a follow up issue, haha |
|
Okay, sounds good. Yeah, I agree we do not need to handle here then. |
joekaufmanexpensify
left a comment
There was a problem hiding this comment.
Good for product.
|
🚧 arosiclair has triggered a test Expensify/App build. You can view the workflow run here. |
@joekaufmanexpensify @arosiclair do we want to fix this as a follow up? |
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
Do we have a stable way to reproduce this without clearing the cache in offline mode? |
|
🚀 Deployed to staging by https://github.com/arosiclair in version: 9.4.64-0 🚀
|
|
Yes — help site changes are required. Draft PR: #99802 Two behaviors this PR changed are user-visible and were not documented anywhere under
What I changed and whyNo article documented the single-expense detail view at all, so nothing on the help site stated the old behavior — these are gaps to fill, not corrections.
Also added the missing
Verified against the live web UI, not inferred from the diff:
Expense type strings came from One item I could not complete: GitHub rejected assigning the docs PR to @mukhrr, please review the linked help site PR and confirm it reflects the current behavior. Then mark the linked help site PR |
@ZhenjaHorbach I think no |



Explanation of Change
Adds expense type (Cash/Card/Distance/etc) next to Amount, shows reimbursable state on both sides, moves Purchase/Converted underneath as a hint, and shows
{feed name} - {last4}instead of the masked PAN for commercial card feed (VCF/CDF/GL1025) cards.Fixed Issues
$ #98913
PROPOSAL: #98913 (comment)
Tests
Amount · Cash · Reimbursable(or· Non-reimbursableif the toggle is off).Purchase [amount]now shows as its own line under the Amount row, not inline in theAmount · ...subtitle.Converted [amount]shows under the Amount row the same way.Distance,Per diem,Time), notCash.{feed name} - {last four}(e.g.Visa cards - 1234), not the masked card number.Offline tests
Same as tests, no network calls involved.
QA Steps
Same as tests.
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
ios_app.mp4
Android: mWeb Chrome
android_web.mp4
iOS: Native
ios_app.mp4
iOS: mWeb Safari
ios_web.mp4
MacOS: Chrome / Safari
web.mp4