Skip to content

[$250] Expense-Creating distance map expense from QAB shows amount as zero #82801

Closed

Description

@nlemma

If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!


Version Number: V9.3.21-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/TR-5546/folder/13176896/41237396/1196513917
Email or phone of affected tester (no customers): dreamnitethedragon@gmail.com
Issue reported by: Applause Internal Team
Bug source: Exploratory - Significant User Experience Deterioration
Device used: Redminote 10S Android 13
App Component: User Settings

Action Performed:

  1. Launch app
  2. Login with new account
  3. Create a 1:1 distance manual expense
  4. Go to reports
  5. Go offline
  6. Tap fab - track distance from QAB & complete the flow using manual option
  7. Note expense amount is displayed as zero
  8. Tap fab - track distance & complete the flow using manual option
  9. Note expense amount is displayed

Expected Result:

Creating distance map expense from QAB must not show amount as zero.

Actual Result:

Creating distance map expense from QAB shows amount as zero.

Workaround:

Unknown

Platforms:

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

Screenshots/Videos

Bug7081341_1771419397417.Screenrecorder-2026-02-18-18-20-20-726.mp4

View all open jobs on GitHub

Issue OwnerCurrent Issue Owner: @ahmedGaber93
Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~022028952299804889254
  • Upwork Job ID: 2028952299804889254
  • Last Price Increase: 2026-03-03

Activity

  1. daledah commented on Feb 18, 2026

    @daledah
    Contributor

    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, 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):

    const validWaypoints = !isManualDistance && !isOdometerDistance ? getValidWaypoints(waypoints, true, isGPSDistance) : undefined;

    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:

    setDistanceRequestData?.(participants);

    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:

     const validWaypoints = !isManualDistance && !isOdometerDistance ? getValidWaypoints(waypoints, true, isGPSDistance) : undefined;
    
    +let amount = 0;
    +if (isManualDistance && distance !== undefined && unit) {
    +    const distanceInMeters = DistanceRequestUtils.convertToDistanceInMeters(distance, unit);
    +    const mileageRates = DistanceRequestUtils.getMileageRates(policy);
    +    const defaultMileageRate = DistanceRequestUtils.getDefaultMileageRate(policy);
    +    const mileageRate = (customUnitRateID && mileageRates?.[customUnitRateID]) || defaultMileageRate;
    +    amount = DistanceRequestUtils.getDistanceRequestAmount(distanceInMeters, unit, mileageRate?.rate ?? 0);
    +}
    +
     if (isCreatingTrackExpense && participant) {
         trackExpense({
             ...
             transactionParams: {
    -            amount: 0,
    +            amount,
                 distance,
                 ...
             },
             ...
         });
         return;
     }
    
     createDistanceRequest({
         ...
         transactionParams: {
    -        amount: 0,
    +        amount,
             distance,
             ...
         },
         ...
     });

    What alternative solutions did you explore? (Optional)

    N/A

  2. added
    BugSomething is broken. Auto assigns a BugZero manager.
    on Mar 3, 2026
  3. melvin-bot commented on Mar 3, 2026

    @melvin-bot

    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.

  4. MelvinBot commented on Mar 3, 2026

    @MelvinBot
    Contributor

    🔍 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, 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:

    1. No client-side amount calculation occurs
    2. No waypoints are sent for the backend to recalculate from
    3. The expense is created with amount: 0
    4. 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

    1. Entry point: User creates manual distance via QAB → IOURequestStepDistanceManual.navigateToNextPage (line 163) → calls handleMoneyRequestStepDistanceNavigation with manualDistance: distanceAsFloat and shouldSkipConfirmation: true
    2. Missing callback: IOURequestStepDistanceManual does NOT pass setDistanceRequestData (compare with IOURequestStepDistanceMap.tsx:324 which does)
    3. No-op: At MoneyRequest.ts:587, setDistanceRequestData?.(participants) is a no-op because the callback is undefined
    4. Hardcoded zero: trackExpense at line 622 and createDistanceRequest at line 662 both pass amount: 0
    5. No backend fallback: validWaypoints is undefined for manual distance (line 607), so the backend has no route data to recalculate from
    6. 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.

  5. added
    ExternalAdded to denote the issue can be worked on by a contributor
    on Mar 3, 2026
  6. added
    Help WantedApply this label when an issue is open to proposals by contributors
    on Mar 3, 2026
  7. melvin-bot commented on Mar 3, 2026

    @melvin-bot

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

  8. 8 remaining items

  9. removed
    Help WantedApply this label when an issue is open to proposals by contributors
    on Mar 10, 2026
  10. melvin-bot commented on Mar 12, 2026

    @melvin-bot

    Triggered auto assignment to @francoisl, see https://stackoverflow.com/c/expensify/questions/7972 for more details.

  11. ahmedGaber93 commented on Mar 12, 2026

    @ahmedGaber93
    Contributor

    @francoisl I think you close this issue by mistake, could you please reopen it again for payment.

  12. francoisl commented on Mar 12, 2026

    @francoisl
    Contributor

    Ah I see, it got closed automatically when I merged because this commit message contains the keyword Fixes <issue number>.

  13. laurenreidexpensify commented on Mar 23, 2026

    @laurenreidexpensify
    Contributor

    Deployed to Prod last week - #84658 (comment) eligible for payment now as 7 days have passed

  14. laurenreidexpensify commented on Mar 23, 2026

    @laurenreidexpensify
    Contributor

    Payment Summary

    C+ Review @ahmedGaber93 can request $250 in New Expensify

  15. flaviadefaria commented on Apr 29, 2026

    @flaviadefaria
    Contributor

    $250 approved for @ahmedGaber93

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.ExternalAdded to denote the issue can be worked on by a contributorReviewingHas a PR in reviewWeeklyKSv2

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions