Skip to content

Wrong distance at confirm page when create from FAB for ws set different unit with default ws #100973

Open

Description

@applause-bot

If you haven’t already, check out our contributing guidelines for onboarding. To join our Slack channel, fill out this form.


Version Number: v9.4.76-0
Reproducible in staging?: Yes
Reproducible in production?: Yes
If this was caught during regression testing, add the test name, ID and link from BrowserStack: https://test-management.browserstack.com/projects/2219752/test-runs/73341873/folder/53991803/96168978/1746386850?sort=-identifier
Email or phone of affected tester (no customers): [email protected]
Issue reported by: Applause Internal Team
Bug source: Exploratory - Significant User Experience Deterioration
Device used: Win 11/Chrome
App Component: Money Requests

Action Performed:

Precondition:

  • Create 2 workspace, enable Distance rate
  • At default workspace change the Distance rate unit to Km
  1. Open https://staging.new.expensify.com
  2. At FAB, click + button
  3. Select Track distance
  4. Click on Odometer tab
  5. Enter Start and End reading > Next
  6. At confirm details page, change recipient to the second workspace
  7. Observe Distance row at confirm page
  8. Click on Distance row to observe total distance

Expected Result:

The distance at confirm page should be same with total distance at step 8

Actual Result:

The distance at confirm page is different with total distance at step 8

Workaround:

Unknown

Platforms:

  • Android: App
  • Android: mWeb Chrome
  • iOS: App
  • iOS: mWeb Safari
  • iOS: mWeb Chrome
  • Windows: Chrome
  • MacOS: Chrome Safari

Screenshots/Videos

Bug7256915_1789121595743.Recording__2469.mp4

View all open jobs on GitHub

Applause Internal Information
Exported by: Svetlana Lazutkina
Bug ID: 7256915

Issue OwnerCurrent Issue Owner: @jayeshmangwani

Activity

  1. added
    BugSomething is broken. Auto assigns a BugZero manager.
    on Sep 11, 2026
  2. applause-bot commented on Sep 11, 2026

    @applause-bot
    Author

    While Applause doesn't embed attachments for this bug, here are the links for quick view:
    https://platform.applause.com/services/links/v1/external/42beaf7e733e10f52520f9febcd39e39d6622d36bed64176e225f0db1f93eb43

  3. MelvinBot commented on Sep 11, 2026

    @MelvinBot
    Contributor

    Proposal

    What is the root cause of that problem?

    Switching the recipient to another workspace converts the odometer expense's stored distance between units, but the odometer readings it was derived from are never converted — so the two screens disagree.

    When you pick a participant on a different workspace, the confirmation step swaps in that workspace's mileage rate via src/pages/iou/request/step/IOURequestStepConfirmation.tsx:479. setCustomUnitRateID then rewrites both comment.customUnit.distanceUnit and comment.customUnit.quantity, converting the quantity into the new unit at src/libs/actions/IOU/MoneyRequest.ts:783-790. That conversion is correct for map/manual distance, but wrong for odometer: there the quantity is just end reading − start reading, a plain number that belongs to whatever the vehicle's odometer counts, not a measurement to re-scale.

    The odometer screen still derives its total live from the untouched readings in comment.odometerStart / comment.odometerEnd (IOURequestStepDistanceOdometer.tsx:272-280), while the confirmation page reads the converted quantity (useDistanceRequestState.ts:97). With readings 1000 → 1100 saved on a km workspace and then moved to a mi workspace: confirmation shows ~62.14 mi, the Distance page shows 100 mi. The amount and merchant are seeded from the same converted quantity, so the expense total is wrong too — not just the label.

    The same code already knows odometer must be exempt: setMoneyRequestDistanceRate guards the identical conversion with !isOdometerDistanceRequest(transaction). setCustomUnitRateID is missing that guard.

    What changes do you think we should make in order to solve the problem?

    Add the same odometer exemption to setCustomUnitRateID: keep updating distanceUnit to the destination workspace's unit, but skip the quantity conversion when the transaction is an odometer expense, so quantity stays equal to end reading − start reading. That makes the confirmation row, the Distance page, the merchant and the amount all agree, and matches the behaviour already implemented for the rate picker.

    Unit test to add alongside tests/unit/useParticipantSubmissionTest.ts: calling setCustomUnitRateID with a km→mi rate change leaves quantity untouched for an odometer transaction, and still converts it for a map/manual distance transaction.

    What alternative solutions did you explore? (Optional)

    Converting the odometer readings themselves along with the quantity. Rejected — the readings are what the tester physically entered from the vehicle, and rewriting them would make the odometer screen contradict the receipt images. It also contradicts the existing rate-picker behaviour.

    Notes and confidence

    Next Steps for Contributor+ team:
    To accept: @MelvinBot implement [this](https://github.com/Expensify/App/issues/100973) to create a draft PR.
    To refine: @MelvinBot <your feedback>
    To reject: Explain why you are rejecting Melvin's proposal.

  4. added
    ExternalAdded to denote the issue can be worked on by a contributor
    on Sep 11, 2026
  5. melvin-bot commented on Sep 11, 2026

    @melvin-bot

    Triggered auto assignment to Contributor-plus team member for initial proposal review - @jayeshmangwani (External)

  6. melvin-bot commented on Sep 11, 2026

    @melvin-bot

    Unable to auto-create job on Upwork. The BZ team member should create it manually for this issue.

  7. jayeshmangwani commented on Sep 14, 2026

    @jayeshmangwani
    Contributor

    @MelvinBot implement this

  8. MelvinBot commented on Sep 14, 2026

    @MelvinBot
    Contributor

    🤖 Draft PR created: #101050

    Please mark it as "Ready for review" when it is ready for review.

    What changed: setCustomUnitRateID now skips the quantity conversion for odometer expenses, matching the guard setMoneyRequestDistanceRate already had.

    Switching the recipient to a workspace with a different distance unit was re-scaling comment.customUnit.quantity into the new unit, but for odometer expenses that quantity is just end reading − start reading — a count off the vehicle, not a measurement. The readings in comment.odometerStart / comment.odometerEnd were left alone, so the Distance page kept deriving 100 live from them while the confirmation page showed the converted ~62.14. The amount and merchant are seeded from the same quantity, so the total was wrong too, not just the label.

    distanceUnit still updates to the destination workspace's unit, so both screens now agree on the unit and the number.

    Code and testing details

    The fix — src/libs/actions/IOU/MoneyRequest.ts:778, adding && !isOdometerDistanceRequest(transaction) to shouldUpdateQuantity. The same exemption already existed one function over at MoneyRequest.ts:939.

    Why the two screens disagreed — the odometer screen computes its total live from the readings at IOURequestStepDistanceOdometer.tsx:270-280, while the confirmation page reads the stored quantity via useDistanceRequestState.ts:97.

    Unit tests added — a new setCustomUnitRateID block in tests/actions/IOU/MoneyRequestSettersTest.ts: a km→mi rate change still converts the quantity for a normal distance expense, and leaves it untouched for an odometer one.

    AI tests run locally — npm run typecheck, npm run lint-changed, and npm run spell-changed all passed. npm test across tests/actions/IOU plus the distance and odometer suites passed: 34 suites, 1040 tests.

    ⚠️ Not verified in a browser. The automated web session for this run rendered a blank page, so I could not drive the two-workspace repro end to end. The fix is covered by unit tests only — please run the repro steps from the issue before marking the PR ready for review.

  9. melvin-bot commented on Sep 17, 2026

    @melvin-bot

    @jayeshmangwani Whoops! This issue is 2 days overdue. Let's get this updated quick!

  10. melvin-bot commented on Sep 21, 2026

    @melvin-bot

    @jayeshmangwani 6 days overdue. This is scarier than being forced to listen to Vogon poetry!

  11. jayeshmangwani commented on Sep 23, 2026

    @jayeshmangwani
    Contributor

    Update: We’re discussing the expected behavior in the draft PR #101050 and trying to reach a consensus.

  12. 15 remaining items

  13. self-assigned this
    on Oct 16, 2026
  14. Julesssss commented on Oct 16, 2026

    @Julesssss
    Contributor

    Clearing up the blocking discussion here.

  15. melvin-bot commented on Oct 19, 2026

    @melvin-bot

    @jayeshmangwani Whoops! This issue is 2 days overdue. Let's get this updated quick!

  16. jayeshmangwani commented on Oct 20, 2026

    @jayeshmangwani
    Contributor

    Not overdue. There’s a slight inconsistency between FE and BE, and we’re checking #101050 whether a BE fix is also needed to fix the issue.

  17. Julesssss commented on Oct 21, 2026

    @Julesssss
    Contributor

    As @jayeshmangwani mentioned we need a backend fix to accompany the App fix. Looking for contributor.

  18. Julesssss commented on Oct 21, 2026

    @Julesssss
    Contributor

    Backend issue here (internal).

    @jayeshmangwani, could you update the App PR so that we send a new odometerUnit param with CreateDistanceRequest, TrackExpense, and UpdateMoneyRequestDistance.

    We could have the backend use the client's distance directly, but the backend treats the odometer readings as the source of truth, so that they always match the photos.

  19. Kabeer099 commented on Oct 29, 2026

    @Kabeer099

    Proposal

    Please re-state the problem that we are trying to solve in this issue.

    When creating an odometer distance expense from the global FAB (Create expense > Distance > Odometer) and selecting a workspace whose distance unit differs from the default workspace's unit (e.g. km vs mi), the confirmation page converts the stored distance quantity into the new unit while leaving odometerStart and odometerEnd untouched, causing the confirmation page distance to disagree with endReading - startReading.

    What is the root cause of that problem?

    1. In src/pages/iou/request/step/IOURequestStepConfirmation/index.tsx (line 479), switching the recipient to a workspace with a different mileage rate invokes setCustomUnitRateID.
    2. In src/libs/actions/IOU/MoneyRequest.ts (lines 783-790), setCustomUnitRateID converts comment.customUnit.quantity from the previous distanceUnit to the new workspace's distanceUnit (convertDistanceUnit). While converting physical distance is valid for Map/Manual distance requests, for Odometer distance requests (isOdometerDistanceRequest(transaction)), quantity is strictly the numeric delta odometerEnd - odometerStart entered by the user (src/pages/iou/request/step/IOURequestStepDistanceOdometer.tsx:272-280), so scaling quantity by 1.609 or 0.621 makes quantity no longer equal odometerEnd - odometerStart.

    What changes do you think we should make in order to solve the problem?

    1. In src/libs/actions/IOU/MoneyRequest.ts (setCustomUnitRateID, lines 783-790), skip the convertDistanceUnit rescaling of comment.customUnit.quantity when isOdometerDistanceRequest(transaction) is true (preserving quantity = odometerEnd - odometerStart while updating distanceUnit and customUnitRateID to the selected workspace's rate).

    What alternative solutions did you explore? (Optional)

    None — odometer readings are raw numeric counter values entered by the user, so odometerEnd - odometerStart must remain invariant when switching workspaces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

BugSomething is broken. Auto assigns a BugZero manager.DailyKSv2ExternalAdded to denote the issue can be worked on by a contributorOverdue

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions