You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[$250] Expense-Creating distance map expense from QAB shows amount as zero #82801
Please re-state the problem that we are trying to solve in this issue.
Creating distance map expense from QAB shows amount as zero.
What is the root cause of that problem?
When creating a manual distance expense via QAB, shouldSkipConfirmation is true, so the flow bypasses the confirmation page and directly creates the expense in handleMoneyRequestStepDistanceNavigation. In this skip-confirmation path, the expense is created with amount: 0 hardcoded:
For map distance expenses, the backend recalculates the amount from validWaypoints/route data. However, for manual distance, validWaypoints is undefined (since there is no route):
Additionally, setDistanceRequestData (which calculates the amount for the map flow) is only passed from IOURequestStepDistanceMap, not from IOURequestStepDistanceManual, so it's undefined and the optional call on line 564 does nothing for manual distance:
When offline, the backend never processes the request, so the expense remains at $0.00.
What changes do you think we should make in order to solve the problem?
In handleMoneyRequestStepDistanceNavigation (src/libs/actions/IOU/MoneyRequest.ts), calculate the amount from the manual distance and mileage rate before passing it to trackExpense/createDistanceRequest when shouldSkipConfirmation is true:
Please re-state the problem that we are trying to solve in this issue.
When creating a manual distance expense via QAB (Quick Action Button) — especially while offline — the expense amount displays as $0.00 instead of the calculated distance-based amount.
What is the root cause of that problem?
When the QAB is used, shouldSkipConfirmation is true, so the flow bypasses the confirmation page and directly creates the expense inside handleMoneyRequestStepDistanceNavigation in src/libs/actions/IOU/MoneyRequest.ts.
In this skip-confirmation path, both trackExpense (line 622) and createDistanceRequest (line 662) are called with amount: 0 hardcoded in transactionParams.
For map-based distance expenses, IOURequestStepDistanceMap passes a setDistanceRequestData callback (defined at IOURequestStepDistanceMap.tsx:173-205) that computes the amount via DistanceRequestUtils.getDistanceRequestAmount(distance, unit, rate) and writes it to the transaction draft via setMoneyRequestAmount. However, the hardcoded amount: 0 in the dispatch calls overrides this for the skip-confirmation path — it works for map expenses because the backend recalculates from validWaypoints and route data.
For manual distance expenses, IOURequestStepDistanceManual does not pass setDistanceRequestData at all (see IOURequestStepDistanceManual.tsx:205-238), and validWaypoints is explicitly set to undefined (line 607: const validWaypoints = !isManualDistance && !isOdometerDistance ? ... : undefined). This means:
No client-side amount calculation occurs
No waypoints are sent for the backend to recalculate from
The expense is created with amount: 0
When offline, the backend never processes the request, so the $0.00 persists
In the normal (non-QAB) flow, the confirmation page (MoneyRequestConfirmationList at MoneyRequestConfirmationList.tsx:389-401) independently recalculates the amount from distance * rate and calls setMoneyRequestAmount, which is why the non-QAB flow works correctly.
What changes do you think we should make in order to solve the problem?
In handleMoneyRequestStepDistanceNavigation (src/libs/actions/IOU/MoneyRequest.ts), when shouldSkipConfirmation is true and the request is a manual distance expense, compute the amount from the distance and mileage rate before passing it to trackExpense/createDistanceRequest.
The function already has access to distance (derived from manualDistance at line 576), unit (line 561), and policy. The amount can be computed using DistanceRequestUtils.convertToDistanceInMeters(distance, unit) and DistanceRequestUtils.getDistanceRequestAmount(distanceInMeters, unit, rate) — the same pattern used by MoneyRequestConfirmationList and IOURequestStepDistanceMap.setDistanceRequestData.
The computed amount should replace the hardcoded 0 at lines 622 and 662 for the manual distance case.
Existing Proposal Assessment
The proposal from daledah correctly identifies the root cause and proposes the right fix approach. The key code locations and the mechanism (hardcoded amount: 0 + missing setDistanceRequestData + no validWaypoints for backend recalculation) are accurately described.
Detailed Investigation
Evidence Chain
Entry point: User creates manual distance via QAB → IOURequestStepDistanceManual.navigateToNextPage (line 163) → calls handleMoneyRequestStepDistanceNavigation with manualDistance: distanceAsFloat and shouldSkipConfirmation: true
Missing callback: IOURequestStepDistanceManual does NOT pass setDistanceRequestData (compare with IOURequestStepDistanceMap.tsx:324 which does)
No-op: At MoneyRequest.ts:587, setDistanceRequestData?.(participants) is a no-op because the callback is undefined
Hardcoded zero: trackExpense at line 622 and createDistanceRequest at line 662 both pass amount: 0
No backend fallback: validWaypoints is undefined for manual distance (line 607), so the backend has no route data to recalculate from
Result: Optimistic transaction shows $0.00, and when offline, the server never corrects it
Relevant Code
App/src/libs/actions/IOU/MoneyRequest.ts:564-687 - handleMoneyRequestStepDistanceNavigation, the function containing the bug
App/src/libs/actions/IOU/MoneyRequest.ts:622,662 - The hardcoded amount: 0 in both trackExpense and createDistanceRequest
App/src/pages/iou/request/step/IOURequestStepDistanceManual.tsx:205-238 - Missing setDistanceRequestData in the call
App/src/pages/iou/request/step/IOURequestStepDistanceMap.tsx:173-205 - Working reference: setDistanceRequestData callback that correctly computes amount
App/src/libs/DistanceRequestUtils.ts:316-318 - getDistanceRequestAmount(distance, unit, rate) — the canonical amount calculation function
App/src/components/MoneyRequestConfirmationList.tsx:389-401,543-546 - Normal flow amount calculation (confirmation page)
Confidence: High
Root cause identified with specific code locations and mechanism
Evidence chain is complete from user action through to the $0.00 display
Normal (non-QAB) flow works correctly because the confirmation page independently calculates the amount
The fix approach is consistent with existing patterns in the codebase
Next Steps for Contributor+ team: Reply with @MelvinBot implement this to create a draft PR, or @MelvinBot <your feedback> to refine this analysis.
Activity
daledah commentedon Feb 18, 2026
Proposal
Please re-state the problem that we are trying to solve in this issue.
Creating distance map expense from QAB shows amount as zero.
What is the root cause of that problem?
When creating a manual distance expense via QAB,
shouldSkipConfirmationistrue, so the flow bypasses the confirmation page and directly creates the expense inhandleMoneyRequestStepDistanceNavigation. In this skip-confirmation path, the expense is created withamount: 0hardcoded:App/src/libs/actions/IOU/MoneyRequest.ts
Line 594 in c835e8d
App/src/libs/actions/IOU/MoneyRequest.ts
Line 629 in c835e8d
For map distance expenses, the backend recalculates the amount from
validWaypoints/route data. However, for manual distance,validWaypointsisundefined(since there is no route):App/src/libs/actions/IOU/MoneyRequest.ts
Line 579 in c835e8d
Additionally,
setDistanceRequestData(which calculates the amount for the map flow) is only passed fromIOURequestStepDistanceMap, not fromIOURequestStepDistanceManual, so it'sundefinedand the optional call on line 564 does nothing for manual distance:App/src/libs/actions/IOU/MoneyRequest.ts
Line 564 in c835e8d
When offline, the backend never processes the request, so the expense remains at
$0.00.What changes do you think we should make in order to solve the problem?
In
handleMoneyRequestStepDistanceNavigation(src/libs/actions/IOU/MoneyRequest.ts), calculate the amount from the manual distance and mileage rate before passing it totrackExpense/createDistanceRequestwhenshouldSkipConfirmationis true:What alternative solutions did you explore? (Optional)
N/A
melvin-bot commentedon Mar 3, 2026
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.MelvinBot commentedon Mar 3, 2026
🔍 Issue Analysis
Please re-state the problem that we are trying to solve in this issue.
When creating a manual distance expense via QAB (Quick Action Button) — especially while offline — the expense amount displays as $0.00 instead of the calculated distance-based amount.
What is the root cause of that problem?
When the QAB is used,
shouldSkipConfirmationistrue, so the flow bypasses the confirmation page and directly creates the expense insidehandleMoneyRequestStepDistanceNavigationinsrc/libs/actions/IOU/MoneyRequest.ts.In this skip-confirmation path, both
trackExpense(line 622) andcreateDistanceRequest(line 662) are called withamount: 0hardcoded intransactionParams.For map-based distance expenses,
IOURequestStepDistanceMappasses asetDistanceRequestDatacallback (defined atIOURequestStepDistanceMap.tsx:173-205) that computes the amount viaDistanceRequestUtils.getDistanceRequestAmount(distance, unit, rate)and writes it to the transaction draft viasetMoneyRequestAmount. However, the hardcodedamount: 0in the dispatch calls overrides this for the skip-confirmation path — it works for map expenses because the backend recalculates fromvalidWaypointsand route data.For manual distance expenses,
IOURequestStepDistanceManualdoes not passsetDistanceRequestDataat all (seeIOURequestStepDistanceManual.tsx:205-238), andvalidWaypointsis explicitly set toundefined(line 607:const validWaypoints = !isManualDistance && !isOdometerDistance ? ... : undefined). This means:amount: 0In the normal (non-QAB) flow, the confirmation page (
MoneyRequestConfirmationListatMoneyRequestConfirmationList.tsx:389-401) independently recalculates the amount fromdistance * rateand callssetMoneyRequestAmount, which is why the non-QAB flow works correctly.What changes do you think we should make in order to solve the problem?
In
handleMoneyRequestStepDistanceNavigation(src/libs/actions/IOU/MoneyRequest.ts), whenshouldSkipConfirmationistrueand the request is a manual distance expense, compute the amount from the distance and mileage rate before passing it totrackExpense/createDistanceRequest.The function already has access to
distance(derived frommanualDistanceat line 576),unit(line 561), andpolicy. The amount can be computed usingDistanceRequestUtils.convertToDistanceInMeters(distance, unit)andDistanceRequestUtils.getDistanceRequestAmount(distanceInMeters, unit, rate)— the same pattern used byMoneyRequestConfirmationListandIOURequestStepDistanceMap.setDistanceRequestData.The computed amount should replace the hardcoded
0at lines 622 and 662 for the manual distance case.Existing Proposal Assessment
The proposal from
daledahcorrectly identifies the root cause and proposes the right fix approach. The key code locations and the mechanism (hardcodedamount: 0+ missingsetDistanceRequestData+ novalidWaypointsfor backend recalculation) are accurately described.Detailed Investigation
Evidence Chain
IOURequestStepDistanceManual.navigateToNextPage(line 163) → callshandleMoneyRequestStepDistanceNavigationwithmanualDistance: distanceAsFloatandshouldSkipConfirmation: trueIOURequestStepDistanceManualdoes NOT passsetDistanceRequestData(compare withIOURequestStepDistanceMap.tsx:324which does)MoneyRequest.ts:587,setDistanceRequestData?.(participants)is a no-op because the callback isundefinedtrackExpenseat line 622 andcreateDistanceRequestat line 662 both passamount: 0validWaypointsisundefinedfor manual distance (line 607), so the backend has no route data to recalculate fromRelevant Code
App/src/libs/actions/IOU/MoneyRequest.ts:564-687-handleMoneyRequestStepDistanceNavigation, the function containing the bugApp/src/libs/actions/IOU/MoneyRequest.ts:622,662- The hardcodedamount: 0in bothtrackExpenseandcreateDistanceRequestApp/src/pages/iou/request/step/IOURequestStepDistanceManual.tsx:205-238- MissingsetDistanceRequestDatain the callApp/src/pages/iou/request/step/IOURequestStepDistanceMap.tsx:173-205- Working reference:setDistanceRequestDatacallback that correctly computes amountApp/src/libs/DistanceRequestUtils.ts:316-318-getDistanceRequestAmount(distance, unit, rate)— the canonical amount calculation functionApp/src/components/MoneyRequestConfirmationList.tsx:389-401,543-546- Normal flow amount calculation (confirmation page)Confidence: High
Next Steps for Contributor+ team: Reply with
@MelvinBot implement thisto create a draft PR, or@MelvinBot <your feedback>to refine this analysis.melvin-bot commentedon Mar 3, 2026
Triggered auto assignment to Contributor-plus team member for initial proposal review - @ahmedGaber93 (
External)8 remaining items
melvin-bot commentedon Mar 12, 2026
Triggered auto assignment to @francoisl, see https://stackoverflow.com/c/expensify/questions/7972 for more details.
ahmedGaber93 commentedon Mar 12, 2026
@francoisl I think you close this issue by mistake, could you please reopen it again for payment.
francoisl commentedon Mar 12, 2026
Ah I see, it got closed automatically when I merged because this commit message contains the keyword
Fixes <issue number>.laurenreidexpensify commentedon Mar 23, 2026
Deployed to Prod last week - #84658 (comment) eligible for payment now as 7 days have passed
laurenreidexpensify commentedon Mar 23, 2026
Payment Summary
C+ Review @ahmedGaber93 can request $250 in New Expensify
flaviadefaria commentedon Apr 29, 2026
$250 approved for @ahmedGaber93