Fix negative Total after moving an IOU report to a workspace - #100535
Fix negative Total after moving an IOU report to a workspace#100535MelvinBot wants to merge 2 commits into
Conversation
…pense report Co-authored-by: Abdelrahman Khattab <abzokhattab@users.noreply.github.com>
|
I created this PR from an upstream branch since I don't have push access to your fork. To take ownership of this branch and be able to push updates, run: Then you can close this PR and open a new one from your fork. |
Co-authored-by: Abdelrahman Khattab <abzokhattab@users.noreply.github.com>
|
Fixed and pushed as What was failing:
Both are pure whitespace. No logic changed. Verification
|
|
🤖 Web test steps verification results: ❌ fail Session was lost to an off-app navigation (expensify.com marketing site) while still on step 1 (choosing the 1:1 recipient for the first expense), before any expense could be created; steps 2-4 were never reached. This is a test-harness failure, not evidence about the code in this PR — the flow this PR touches was never exercised on web, so the web pass still needs a re-run.
|






Explanation of Change
Moving an IOU report to a workspace showed the Total as a negative amount (
-$100.00).IOU reports store their totals positive; expense reports store them negative. When converting an IOU report to an expense report, the optimistic report object negated
totalbut left the sibling total columns —reimbursableTotal,nonReimbursableTotal,unheldTotal,unheldReimbursableTotal,unheldNonReimbursableTotal— riding along unchanged from the spread, still positive.Every Total on screen comes from
getMoneyRequestSpendBreakdown, which prefers the stalereimbursableTotalovertotalviagetReimbursableTotal, then negates it because the report is now an expense report. For a $100 IOU:totalbecomes-10000(correct),reimbursableTotalstays+10000, so the breakdown returns10000 * -1 = -10000→ -$100.00.The change: a new
getNegatedReportTotals()helper inReportUtilsflips the whole family of total columns together, and both conversion sites now use it instead of negatingtotalalone:convertIOUReportToExpenseReport— the "Change Workspace" flow from the issue.Policy.ts— the duplicated block used when creating a workspace from an IOU, which had the identical omission.The helper only writes columns the report actually carries, so absent ones keep being derived from
totalby the existing fallback. This matches what the sibling expense-report flows already do inbuildOptimisticChangePolicyDataand whatIOUUtilsdoes when an IOU flips owner.This also fixes the same stale-total read on the other surfaces: the Search table Total, the report transaction list Total row, the report preview total, the Pay/Approve button amount, and sorting by Total in Search.
Why native only flashed the negative value while web appeared to keep it
There is no
successDataentry for the report key, so only the server response repairs the totals — on native the bad value is visible for exactly one round trip. On web,convertIOUReportToExpenseReportpushes noSNAPSHOToptimistic update and the page callsrefreshSearch()instead, so if theMoveIOUReportToExistingPolicyresponse omitsreimbursableTotal, the OnyxMERGEkeeps the stale positive value for longer. The client-side fix is correct either way.AI tests run locally (all passed):
npm run typecheck,npm run lint-changed,npm run spell-changed, andnpm testovertests/actions/ReportTest.ts,tests/actions/PolicyTest.ts,tests/unit/ReportUtilsTest.ts(1815 tests). Noprettierscript exists in this repo — formatting is enforced through ESLint, which passed.A new unit test in
tests/actions/ReportTest.tsasserts that every total column flips sign and thatgetMoneyRequestSpendBreakdown(...).totalDisplaySpendcomes back positive after conversion.Fixed Issues
$ #97759
PROPOSAL: #97759 (comment)
Tests
// TODO: The human co-author must fill out the tests you ran before marking this PR as "ready for review".
// Please describe what tests you performed that validate your change worked.
//
// Suggested starting point (from the linked issue, not yet run live by Melvin):
// 1. Create 2 expenses in a 1:1 conversation with another user.
// 2. Open the IOU report details.
// 3. Click More > "Change Workspace" and select any workspace.
// 4. Verify the Total on the table shows a positive amount, with no negative flash on native.
Offline tests
QA Steps
// TODO: The human co-author must fill out the QA tests you ran before marking this PR as "ready for review".
// These must be filled out, or the issue title must include "[No QA]."
// Please describe what QA needs to do to validate your changes and what areas they need to test for regressions.
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
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari