[Payment due @huult][NO QA] Show the debited and reimbursed amounts on the reconciliation dashboard - #97167
Conversation
…s until a settlement converts
|
Hey, I noticed you changed If you want to automatically generate translations for other locales, an Expensify employee will have to:
Alternatively, if you are an external contributor, you can run the translation script locally with your own OpenAI API key. To learn more, try running: npx ts-node ./scripts/generateTranslations.ts --helpTypically, you'd want to translate only what you changed by running |
|
@MelvinBot review |
|
@codex review |
SortableTableHeader only makes a header pressable when isColumnSortable is set, so without it the columns rendered as plain labels and the sort Auth supports could not be reached. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
getSortedData re-sorts the page by the mapped property, which for these two columns is a raw amount in whichever currency that settlement used. Ranking GBP 10250 against USD 12000 that way puts them in the wrong order. Unmapped columns fall through with the data untouched, which is the order Auth already computed from a common-currency sort key. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
typecheck and TranslateTest both fail on a key that only exists in en.ts. The generateTranslations bot skips pull requests from forks, so these are written by hand. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
🤖 Reviewed the diff. The visibility gating, types, styles, parser regen, and the two column-availability tests all look clean and match the existing patterns. One blocker on the sorting behavior, plus a design question and a minor nit. 🔴 The two new columns aren't actually sortableThe PR description says "Both columns are sortable" and Test step 8 asks to click the
In 🟡 Once sortable, the client sorts by the raw per-currency amountThe description argues raw amounts can't be ranked across currencies and that the server ranks via a hidden converted key. But grouped results are re-sorted client-side — 🟢 Minor: falsy guard hides a zero amount
Everything else looks good — nice touch adding the |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3d7bcaccf9
ℹ️ 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".
Codecov Report❌ Looks like you've decreased code coverage for some files. Please write tests to increase, or at least maintain, the existing level of code coverage. See our documentation here for how to interpret this table.
|
The list is built at module scope, so the name resolves the moment the file loads and grouping by category throws instead of rendering.
The helper answered "does this column have data" for every column, which read as a double negative for the ones it knows nothing about. Bail out on a transaction array first, then ask the question only of the two conversion columns, matching the expense report branch above.
The server communicates its order through orderedKeys, which the client never reads, so a column with no sorting property leaves the rows in the order the response object happened to be keyed in and clicking the header does nothing. Point both columns at their amount, the way the total column already works.
|
@MelvinBot final review this |
Final reviewLGTM — the change is well-scoped and complete. The two currency-aware columns are wired through the whole stack consistently, and the edge cases you'd worry about are covered. A couple of non-blocking observations below. What I verified
Observations (non-blocking)
Neither blocks merge — nice, clean PR. |
Screen.Recording.2026-08-04.at.13.09.38.movScreen.Recording.2026-08-04.at.13.14.44.movScreen.Recording.2026-08-04.at.13.15.37.movScreen.Recording.2026-08-04.at.13.17.16.movScreen.Recording.2026-08-04.at.13.17.59.movI can't enable Global Reimbursements with my test account. I mocked the data to verify the UI, but I couldn't test the sorting because I don't have the required permissions. @ishpaul777, could you please record the behavior on all platforms and share the videos with @shawnborton? Thanks! |
we dont have any setup on prod to test this yet, mock data in onyx works for now! i'll add videos for other platforms as well 👍 |
|
@ishpaul777 could you run this translation? thanks |
@shawnborton We have the screenshot. Could you review it? |
|
Sweet, looks fine to me 👍 |
|
🎯 @huult, thanks for reviewing and testing this PR! 🎉 A payment issue will be created for your review once this PR is deployed to production. If payment is not needed (e.g., regression PR review fix etc), react with 👎 to this comment to prevent the payment issue from being created. |
|
@ishpaul777 If the QA team has any questions about the test steps, please help them. |
|
This will be No QA, we will internal QA when we have setup for it on prod |
|
🚧 madmax330 has triggered a test Expensify/App build. You can view the workflow run here. |
|
✋ 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! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/madmax330 in version: 9.4.51-0 🚀
|
Help site review — docs update needed ✅This PR adds two columns — Amount debited and Amount reimbursed — to the reimbursement reconciliation view (Search grouped by Withdrawal ID), showing each side of a cross-border settlement in its own currency. That view is documented on the help site in Draft PR: #97920 What it changes:
The exact column labels (Amount debited, Amount reimbursed) and their placement between Expenses and Total were verified against the current App UI and the @ishpaul777, please review the linked help site PR and confirm it reflects the current behavior. Then mark the linked help site PR |
|
🤖 Payment issue created: #98186 |
|
🚀 Deployed to production by https://github.com/roryabraham in version: 9.4.51-1 🚀
Bundle Size Analysis (Sentry): |
Explanation of Change
Grouped by Withdrawal ID, the dashboard only showed the report total. A cross-border settlement debits the company and credits the employee in different currencies, so one number cannot describe it.
Adds
Amount debitedandAmount reimbursedbetweenExpensesandTotal, each in its own currency, from Auth #23263.achAccount, while Auth derives global reimbursement from the policy's reimbursement countries. Gating on the data lands in the same place.Fixed Issues
$ https://github.com/Expensify/Expensify/issues/655931
PROPOSAL: N/A - internal issue
Tests
Amount debitedandAmount reimbursedbetweenExpensesandTotal.Amount debited, and verify the column and its header disappear and the rest of the table stays aligned.Amount debitedheader and verify the rows reorder by that amount, and that clicking it again flips the order. Repeat forAmount reimbursed.Withdrawn,ExpensesandTotalstill works.Offline tests
QA Steps
Same as tests, using a staging account that is an admin of a workspace with global reimbursements enabled and a settled cross-border reimbursement.
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectionAvatar, 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
Screen.Recording.2026-08-04.at.6.09.34.PM.mov
Screen.Recording.2026-08-04.at.6.11.02.PM.mov
Screen.Recording.2026-08-04.at.6.08.36.PM.mov
Screen.Recording.2026-08-04.at.6.13.06.PM.mov