[$250] Confirm details - Unit doesn't change from Km to Mile when switching workspaces after selecting non-default rate
If you haven’t already, check out our contributing guidelines for onboarding and email [email protected] to request to join our Slack channel!
Version Number: v9.2.85-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: Exploratory around https://test-management.browserstack.com/projects/2219752/test-runs/TR-2467/folder/13176744/41237142/1086558789 and https://test-management.browserstack.com/projects/2219752/test-runs/TR-2467/folder/13176744/41237140/1086558788 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: Windows 11/Chrome, iPhone 16/iOS 18.3.1, Pixel 8a/Android 16 App Component: Money Requests
Action Performed:
Preconditions: On User A's side
- Workspace created with Distance rates enabled
- Few additional distance rates added
- Changed the unit to kilometer in settings
- Invited User B as member to workspace
On User's B side
- User B has created his default workspace with distance rates enabled
Steps:
- [User B] - Navigate to staging.new.expensify.com
- [User B] - Click FAB >> Track Distance >> Map option >> Enter waypoints >> Next
- Observe To field has User's B default workspace with default distance rate/mile ($0.7/mile) & take note of distance & amount
- Switch to User's A workspace in To field
- Observe rate field has default rate with kilometer unit ($0.7/kilometer)
- Change rate to non-default one
- Switch to User's B default workspace in To field 8.Observe incorrect unit displayed in Rate field which changes the distance & amount values
Expected Result:
When User B switches from User's A workspace to User's B default workspace, the Rate field unit should change from kilometer to mile & reflect correct distance & amount
Actual Result:
When User B switches from User's A workspace to User's B default workspace , the Rate field unit still display kilometer & does not change to mile unit which is User's B workspace default unit.
Workaround:
Unknown
Platforms:
- [x] Android: App
- [ ] Android: mWeb Chrome
- [x] iOS: App
- [ ] iOS: mWeb Safari
- [ ] iOS: mWeb Chrome
- [x] Windows: Chrome
- [ ] MacOS: Chrome / Safari
Screenshots/Videos
Upwork Automation - Do Not Edit
- Upwork Job URL: https://www.upwork.com/jobs/~022003058270992773869
- Upwork Job ID: 2003058270992773869
- Last Price Increase: 2025-12-22
Issue Owner
Current Issue Owner: @mananjadhav
Triggered auto assignment to @laurenreidexpensify (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.
Job added to Upwork: https://www.upwork.com/jobs/~022003058270992773869
Triggered auto assignment to Contributor-plus team member for initial proposal review - @mananjadhav (External)
Proposal
Please re-state the problem that we are trying to solve in this issue.
Confirm details - Unit doesn't change from Km to Mile when switching workspaces after selecting non-default rate
What is the root cause of that problem?
This is because when we use a custom rate, we perform this function:
https://github.com/Expensify/App/blob/6072cfb8aa701c282c0078bd512949b0465a9964/src/pages/iou/request/step/IOURequestStepDistanceRate.tsx#L116
Which adds distanceUnit:
https://github.com/Expensify/App/blob/6072cfb8aa701c282c0078bd512949b0465a9964/src/libs/actions/IOU.ts#L1469-L1490
https://github.com/Expensify/App/blob/6072cfb8aa701c282c0078bd512949b0465a9964/src/libs/actions/IOU.ts#L1485
This means that the transaction now has this value, and when the unit is received here: https://github.com/Expensify/App/blob/6072cfb8aa701c282c0078bd512949b0465a9964/src/components/MoneyRequestConfirmationList.tsx#L326-L329
In the getRate function:
https://github.com/Expensify/App/blob/6072cfb8aa701c282c0078bd512949b0465a9964/src/libs/DistanceRequestUtils.ts#L378
We always try to get the unit from transaction?.comment?.customUnit?.distanceUnit first, and since we inserted it when selecting a non-default unit, we get it:
https://github.com/Expensify/App/blob/6072cfb8aa701c282c0078bd512949b0465a9964/src/libs/DistanceRequestUtils.ts#L347-L349
And we don't have any logic that would clear this field when the participant changes, we only have the logic for changing the rate: https://github.com/Expensify/App/blob/6072cfb8aa701c282c0078bd512949b0465a9964/src/pages/iou/request/step/IOURequestStepParticipants.tsx#L258-L271
What changes do you think we should make in order to solve the problem?
When changing a participant, we can determine and set the same logic that we use here: https://github.com/Expensify/App/blob/6072cfb8aa701c282c0078bd512949b0465a9964/src/libs/actions/IOU.ts#L1469-L1490
Or reset this field, which I think is more correct, since it will correspond to the logic we have now (transaction?.comment?.customUnit does not have the distanceUnit field in the normal flow). To do this, we can create a separate function:
function clearCustomDistanceUnit(transactionID: string) {
Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {
comment: {
customUnit: {
distanceUnit: null,
},
},
});
}
And use it here: https://github.com/Expensify/App/blob/6072cfb8aa701c282c0078bd512949b0465a9964/src/pages/iou/request/step/IOURequestStepParticipants.tsx#L265
And we can use it here, if necessary: https://github.com/Expensify/App/blob/6072cfb8aa701c282c0078bd512949b0465a9964/src/pages/iou/request/step/IOURequestStepParticipants.tsx#L269
What alternative solutions did you explore? (Optional)
Reminder: Please use plain English, be brief and avoid jargon. Feel free to use images, charts or pseudo-code if necessary. Do not post large multi-line diffs or write walls of text. Do not create PRs unless you have been hired for this job.
Proposal
Please re-state the problem that we are trying to solve in this issue.
Confirm details - Unit doesn't change from Km to Mile when switching workspaces after selecting non-default rate
What is the root cause of that problem?
The issue originates from how the distance unit is persisted and later resolved during the distance request flow:
-
When a user selects a non-default distance rate in a workspace,
setMoneyRequestDistanceRateupdates the draft transaction by storing:transaction.comment.customUnit.distanceUnithere:
https://github.com/Expensify/App/blob/c00b37a1589ed02d6d8ac974e02c6d296ffdf1ef/src/libs/actions/IOU.ts#L1482-L1491
This is expected behavior and ensures correct recalculation within the same workspace .
-
The transaction is still in draft state when the user switches the To workspace. At this point, the draft transaction continues to carry the previously stored
distanceUnit. -
In the confirmation step,
MoneyRequestConfirmationListresolves the mileage rate viagetRate, which internally callsgetDistanceUnit: https://github.com/Expensify/App/blob/54c7eb47b7e774379769129367bc930dbdfb976f/src/libs/DistanceRequestUtils.ts#L378 -
getDistanceUnitcurrently prioritizes the transaction’s stored unit:https://github.com/Expensify/App/blob/54c7eb47b7e774379769129367bc930dbdfb976f/src/libs/DistanceRequestUtils.ts#L347-L349
This means the draft transaction’s unit always overrides the mileage rate’s unit, even when the mileage rate now belongs to a different workspace with a different default unit.
-
As a result, a kilometer unit from Workspace A incorrectly overrides a mile-based rate from Workspace B.
In short, the draft transaction’s stored unit leaks across workspace boundaries and incorrectly takes precedence over the newly selected workspace’s mileage rate unit.
What changes do you think we should make in order to solve the problem?
The distance unit used for display and calculation should always be consistent with the currently selected mileage rate . While the transaction’s stored distance unit is valid within the same workspace, it should not override the unit of a mileage rate that belongs to a different workspace.
To achieve this, we should refine the distance unit resolution logic so that:
- The transaction’s stored distance unit is treated as contextual , not authoritative
- It is only used when it matches the unit of the active mileage rate
- When a mismatch occurs (e.g. after switching workspaces), the mileage rate’s unit becomes the source of truth
This ensures that:
- Units persist correctly when editing or reselecting rates within the same workspace
- Units automatically realign when switching to a workspace with a different default unit
- Draft transactions do not leak unit state across workspace boundaries
- No draft mutation or reset logic is required
We update getDistanceUnit to explicitly validate whether the transaction’s stored unit is compatible with the mileage rate’s unit before using it.
function getDistanceUnit(
transaction: OnyxEntry<Transaction>,
mileageRate: OnyxEntry<MileageRate>
): Unit {
const transactionUnit = transaction?.comment?.customUnit?.distanceUnit;
const rateUnit = mileageRate?.unit;
// Use the transaction unit only when it matches the active mileage rate
if (transactionUnit && rateUnit && transactionUnit === rateUnit) {
return transactionUnit;
}
// Otherwise, fall back to the mileage rate unit
return rateUnit ?? CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES;
}
What alternative solutions did you explore? (Optional)
Reminder: Please use plain English, be brief and avoid jargon. Feel free to use images, charts or pseudo-code if necessary. Do not post large multi-line diffs or write walls of text. Do not create PRs unless you have been hired for this job.
Proposal
Please re-state the problem that we are trying to solve in this issue.
Confirm details - Unit doesn't change from Km to Mile when switching workspaces after selecting non-default rate
What is the root cause of that problem?
When we change distance rate we call setMoneyRequestDistanceRate, and we set the draftTransaction's comment?.customUnit?.distanceUnit to km
https://github.com/Expensify/App/blob/54c7eb47b7e774379769129367bc930dbdfb976f/src/libs/actions/IOU.ts#L1471-L1488
And when try to get the rate on MoneyRequestConfirmationList, we call getRate, and inside getRate useTransactionDistanceUnit transaction is true by default in getRate function call.
https://github.com/Expensify/App/blob/54c7eb47b7e774379769129367bc930dbdfb976f/src/libs/DistanceRequestUtils.ts#L357-L361
And we always calculate unit from transaction (transaction?.comment?.customUnit?.distanceUnit). And we fallback to using mileageRate when transaction?.comment?.customUnit?.distanceUnit is undefined.
https://github.com/Expensify/App/blob/54c7eb47b7e774379769129367bc930dbdfb976f/src/libs/DistanceRequestUtils.ts#L378
The logic to get the distance rate unit from transaction was introduced in this PR. The logic was introduced to avoid changing distance rate unit on MoneyRequestView when user changes unit in workspace settings by using the transaction as source of truth rather than using workspace distance rates (policy?.customUnits).
What changes do you think we should make in order to solve the problem?
We should pass false to useTransactionDistanceUnit when we call getRate in MoneyRequestConfirmationList.tsx
const mileageRate = DistanceRequestUtils.getRate({transaction, policy, policyDraft, useTransactionDistanceUnit: false});
https://github.com/Expensify/App/blob/54c7eb47b7e774379769129367bc930dbdfb976f/src/components/MoneyRequestConfirmationList.tsx#L326
That should work fine since we get distance rate unit from the policy when creating distance request to a policy and from personal policy when we create distance request in DM.
What alternative solutions did you explore? (Optional)
Reminder: Please use plain English, be brief and avoid jargon. Feel free to use images, charts or pseudo-code if necessary. Do not post large multi-line diffs or write walls of text. Do not create PRs unless you have been hired for this job.
Proposal
Please re-state the problem that we are trying to solve in this issue.
Unit doesn't change from Km to Mile when switching workspaces after selecting non-default rate
What is the root cause of that problem?
-
Because the
distanceUnitof the transaction is not set when the workspace changes, the old unit is still displayed. -
When we change the distance rate, the function
setMoneyRequestDistanceRateis used.
https://github.com/Expensify/App/blob/589574c1ca5caaed0c0c947de22e8e2c97981432/src/libs/actions/IOU.ts#L1471-L1492 -
However, when changing the workspace, the function
setCustomUnitRateIDis used.
https://github.com/Expensify/App/blob/589574c1ca5caaed0c0c947de22e8e2c97981432/src/libs/actions/IOU.ts#L1322-L1332 We can see that thesetCustomUnitRateIDfunction does not update thedistanceUnitaccording to thecustomUnitRateID.
What changes do you think we should make in order to solve the problem?
In setCustomUnitRateID, we should also use DistanceRequestUtils.getRateByCustomUnitRateID to retrieve the distanceUnit and update it, just like in setMoneyRequestDistanceRate.
https://github.com/Expensify/App/blob/589574c1ca5caaed0c0c947de22e8e2c97981432/src/libs/actions/IOU.ts#L1476
What alternative solutions did you explore? (Optional)
N/A
@mananjadhav Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!
📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸
Reviewing proposals.
@mananjadhav @laurenreidexpensify this issue was created 2 weeks ago. Are we close to approving a proposal? If not, what's blocking us from getting this issue assigned? Don't hesitate to create a thread in #expensify-open-source to align faster in real time. Thanks!