From 4399528a1e3dac7bc63312aa3d7ff94710c93bba Mon Sep 17 00:00:00 2001
From: daledah <daleda261@outlook.com>
Date: Tue, 9 Jun 2026 17:46:57 +0700
Subject: [PATCH] refactor handleMoneyRequestStepDistanceNavigation function to
 use hasCompletedGuidedSetupFlow param

---
 .../IOU/types/CreateTrackExpenseParams.ts     |  2 +
 ...andleMoneyRequestStepDistanceNavigation.ts |  3 ++
 .../hooks/useDistanceNavigation.ts            |  7 ++-
 .../hooks/useOdometerNavigation.ts            |  7 ++-
 .../index.native.tsx                          |  7 ++-
 .../step/IOURequestStepDistanceManual.tsx     |  9 ++--
 tests/actions/IOU/MoneyRequestTest.ts         | 52 +++++++++++++++++++
 7 files changed, 77 insertions(+), 10 deletions(-)

diff --git a/src/libs/actions/IOU/types/CreateTrackExpenseParams.ts b/src/libs/actions/IOU/types/CreateTrackExpenseParams.ts
index 7bd2b21ad2c7..08afd22a33b7 100644
--- a/src/libs/actions/IOU/types/CreateTrackExpenseParams.ts
+++ b/src/libs/actions/IOU/types/CreateTrackExpenseParams.ts
@@ -34,6 +34,8 @@ type CreateTrackExpenseParams = {
     recentWaypoints: OnyxEntry<OnyxTypes.RecentWaypoint[]>;
     betas: OnyxEntry<OnyxTypes.Beta[]>;
     isSelfTourViewed: boolean;
+    // TODO: Make it required once we complete refactoring the trackExpense function to use hasCompletedGuidedSetupFlow. Refactor issue: https://github.com/Expensify/App/issues/66424
+    hasCompletedGuidedSetupFlow?: boolean;
     defaultWorkspaceName?: string;
     currentUserLocalCurrency: string | undefined;
     previousOdometerDraft?: OnyxEntry<OnyxTypes.OdometerDraft>;
diff --git a/src/pages/iou/request/step/IOURequestStepDistance/handleMoneyRequestStepDistanceNavigation.ts b/src/pages/iou/request/step/IOURequestStepDistance/handleMoneyRequestStepDistanceNavigation.ts
index e1705ee3aa57..f1e54b516cc3 100644
--- a/src/pages/iou/request/step/IOURequestStepDistance/handleMoneyRequestStepDistanceNavigation.ts
+++ b/src/pages/iou/request/step/IOURequestStepDistance/handleMoneyRequestStepDistanceNavigation.ts
@@ -90,6 +90,7 @@ type MoneyRequestStepDistanceNavigationParams = {
     unit?: Unit;
     personalOutputCurrency?: string;
     isSelfTourViewed: boolean;
+    hasCompletedGuidedSetupFlow: boolean;
     amountOwed: OnyxEntry<number>;
     userBillingGracePeriodEnds: OnyxCollection<BillingGraceEndPeriod>;
     ownerBillingGracePeriodEnd?: OnyxEntry<number>;
@@ -182,6 +183,7 @@ function handleMoneyRequestStepDistanceNavigation({
     unit,
     personalOutputCurrency,
     isSelfTourViewed,
+    hasCompletedGuidedSetupFlow,
     amountOwed,
     userBillingGracePeriodEnds,
     ownerBillingGracePeriodEnd,
@@ -312,6 +314,7 @@ function handleMoneyRequestStepDistanceNavigation({
                             recentWaypoints,
                             betas,
                             isSelfTourViewed,
+                            hasCompletedGuidedSetupFlow,
                             previousOdometerDraft,
                             optimisticTransactionID,
                             optimisticChatReportID,
diff --git a/src/pages/iou/request/step/IOURequestStepDistance/hooks/useDistanceNavigation.ts b/src/pages/iou/request/step/IOURequestStepDistance/hooks/useDistanceNavigation.ts
index 62721d7fe7ec..dd69aa7ab56f 100644
--- a/src/pages/iou/request/step/IOURequestStepDistance/hooks/useDistanceNavigation.ts
+++ b/src/pages/iou/request/step/IOURequestStepDistance/hooks/useDistanceNavigation.ts
@@ -1,4 +1,4 @@
-import {hasSeenTourSelector} from '@selectors/Onboarding';
+import {guidedSetupAndTourStatusSelector} from '@selectors/Onboarding';
 import {validTransactionDraftIDsSelector} from '@selectors/TransactionDraft';
 import type {OnyxEntry} from 'react-native-onyx';
 import type {LocaleContextProps} from '@components/LocaleContextProvider';
@@ -130,7 +130,9 @@ function useDistanceNavigation({
     const [quickAction] = useOnyx(ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE);
     const [policyRecentlyUsedCurrencies] = useOnyx(ONYXKEYS.RECENTLY_USED_CURRENCIES);
     const [draftTransactionIDs] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, {selector: validTransactionDraftIDsSelector});
-    const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector});
+    const [guidedSetupAndTourStatus] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: guidedSetupAndTourStatusSelector});
+    const isSelfTourViewed = !!guidedSetupAndTourStatus?.isSelfTourViewed;
+    const hasCompletedGuidedSetupFlow = !!guidedSetupAndTourStatus?.hasCompletedGuidedSetupFlow;
     const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID);
     const [amountOwed] = useOnyx(ONYXKEYS.NVP_PRIVATE_AMOUNT_OWED);
     const [userBillingGracePeriodEnds] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END);
@@ -176,6 +178,7 @@ function useDistanceNavigation({
             recentWaypoints,
             draftTransactionIDs,
             isSelfTourViewed: !!isSelfTourViewed,
+            hasCompletedGuidedSetupFlow,
             amountOwed,
             userBillingGracePeriodEnds,
             ownerBillingGracePeriodEnd,
diff --git a/src/pages/iou/request/step/IOURequestStepDistance/hooks/useOdometerNavigation.ts b/src/pages/iou/request/step/IOURequestStepDistance/hooks/useOdometerNavigation.ts
index 9effdaebd7e6..5263034d5fc1 100644
--- a/src/pages/iou/request/step/IOURequestStepDistance/hooks/useOdometerNavigation.ts
+++ b/src/pages/iou/request/step/IOURequestStepDistance/hooks/useOdometerNavigation.ts
@@ -1,4 +1,4 @@
-import {hasSeenTourSelector} from '@selectors/Onboarding';
+import {guidedSetupAndTourStatusSelector} from '@selectors/Onboarding';
 import {validTransactionDraftIDsSelector} from '@selectors/TransactionDraft';
 import type {OnyxEntry} from 'react-native-onyx';
 import type {LocaleContextProps} from '@components/LocaleContextProvider';
@@ -133,7 +133,9 @@ function useOdometerNavigation({
     const [quickAction] = useOnyx(ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE);
     const [policyRecentlyUsedCurrencies] = useOnyx(ONYXKEYS.RECENTLY_USED_CURRENCIES);
     const [draftTransactionIDs] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, {selector: validTransactionDraftIDsSelector});
-    const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector});
+    const [guidedSetupAndTourStatus] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: guidedSetupAndTourStatusSelector});
+    const isSelfTourViewed = !!guidedSetupAndTourStatus?.isSelfTourViewed;
+    const hasCompletedGuidedSetupFlow = !!guidedSetupAndTourStatus?.hasCompletedGuidedSetupFlow;
     const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID);
     const [amountOwed] = useOnyx(ONYXKEYS.NVP_PRIVATE_AMOUNT_OWED);
     const [userBillingGracePeriodEnds] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END);
@@ -183,6 +185,7 @@ function useOdometerNavigation({
             personalOutputCurrency,
             draftTransactionIDs,
             isSelfTourViewed: !!isSelfTourViewed,
+            hasCompletedGuidedSetupFlow,
             amountOwed,
             userBillingGracePeriodEnds,
             ownerBillingGracePeriodEnd,
diff --git a/src/pages/iou/request/step/IOURequestStepDistanceGPS/index.native.tsx b/src/pages/iou/request/step/IOURequestStepDistanceGPS/index.native.tsx
index e63f90116b9c..280aa381eae8 100644
--- a/src/pages/iou/request/step/IOURequestStepDistanceGPS/index.native.tsx
+++ b/src/pages/iou/request/step/IOURequestStepDistanceGPS/index.native.tsx
@@ -31,7 +31,7 @@ import withFullTransactionOrNotFound from '@pages/iou/request/step/withFullTrans
 import withWritableReportOrNotFound from '@pages/iou/request/step/withWritableReportOrNotFound';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
-import {hasSeenTourSelector} from '@src/selectors/Onboarding';
+import {guidedSetupAndTourStatusSelector} from '@src/selectors/Onboarding';
 import {validTransactionDraftIDsSelector} from '@src/selectors/TransactionDraft';
 import type {Errors} from '@src/types/onyx/OnyxCommon';
 import GPSButtons from './GPSButtons';
@@ -68,7 +68,9 @@ function IOURequestStepDistanceGPS({
     const selfDMReport = useSelfDMReport();
     const {policyForMovingExpenses} = usePolicyForMovingExpenses();
     const [betas] = useOnyx(ONYXKEYS.BETAS);
-    const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: hasSeenTourSelector});
+    const [guidedSetupAndTourStatus] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: guidedSetupAndTourStatusSelector});
+    const isSelfTourViewed = !!guidedSetupAndTourStatus?.isSelfTourViewed;
+    const hasCompletedGuidedSetupFlow = !!guidedSetupAndTourStatus?.hasCompletedGuidedSetupFlow;
     const [mapboxAccessToken] = useOnyx(ONYXKEYS.MAPBOX_ACCESS_TOKEN);
     const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID);
     const reportIDToCheck = isMoneyRequestReport(report) ? report?.chatReportID : report?.reportID;
@@ -153,6 +155,7 @@ function IOURequestStepDistanceGPS({
             personalOutputCurrency: personalPolicy?.outputCurrency,
             draftTransactionIDs,
             isSelfTourViewed: !!isSelfTourViewed,
+            hasCompletedGuidedSetupFlow,
             amountOwed,
             userBillingGracePeriodEnds,
             ownerBillingGracePeriodEnd,
diff --git a/src/pages/iou/request/step/IOURequestStepDistanceManual.tsx b/src/pages/iou/request/step/IOURequestStepDistanceManual.tsx
index 0ca84fa421eb..c1df0f933704 100644
--- a/src/pages/iou/request/step/IOURequestStepDistanceManual.tsx
+++ b/src/pages/iou/request/step/IOURequestStepDistanceManual.tsx
@@ -37,7 +37,7 @@ import variables from '@styles/variables';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
 import type SCREENS from '@src/SCREENS';
-import {hasSeenTourSelector} from '@src/selectors/Onboarding';
+import {guidedSetupAndTourStatusSelector} from '@src/selectors/Onboarding';
 import {validTransactionDraftIDsSelector} from '@src/selectors/TransactionDraft';
 import type Transaction from '@src/types/onyx/Transaction';
 import handleMoneyRequestStepDistanceNavigation from './IOURequestStepDistance/handleMoneyRequestStepDistanceNavigation';
@@ -98,9 +98,9 @@ function IOURequestStepDistanceManual({
     const [draftTransactionIDs] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_DRAFT, {
         selector: validTransactionDraftIDsSelector,
     });
-    const [isSelfTourViewed] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {
-        selector: hasSeenTourSelector,
-    });
+    const [guidedSetupAndTourStatus] = useOnyx(ONYXKEYS.NVP_ONBOARDING, {selector: guidedSetupAndTourStatusSelector});
+    const isSelfTourViewed = !!guidedSetupAndTourStatus?.isSelfTourViewed;
+    const hasCompletedGuidedSetupFlow = !!guidedSetupAndTourStatus?.hasCompletedGuidedSetupFlow;
     const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID);
     const [splitDraftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT}${transactionID}`);
     const [recentWaypoints] = useOnyx(ONYXKEYS.NVP_RECENT_WAYPOINTS);
@@ -258,6 +258,7 @@ function IOURequestStepDistanceManual({
             unit,
             personalOutputCurrency: personalPolicy?.outputCurrency,
             isSelfTourViewed: !!isSelfTourViewed,
+            hasCompletedGuidedSetupFlow,
             amountOwed,
             userBillingGracePeriodEnds,
             ownerBillingGracePeriodEnd,
diff --git a/tests/actions/IOU/MoneyRequestTest.ts b/tests/actions/IOU/MoneyRequestTest.ts
index bfd439d7b95a..d0c797f82db3 100644
--- a/tests/actions/IOU/MoneyRequestTest.ts
+++ b/tests/actions/IOU/MoneyRequestTest.ts
@@ -608,6 +608,7 @@ describe('MoneyRequest', () => {
             optimisticTransactionID: 'mock-txn-id',
             optimisticChatReportID: 'mock-chat-id',
             isSelfTourViewed: false,
+            hasCompletedGuidedSetupFlow: false,
             amountOwed: 0,
             draftTransactionIDs: undefined,
             userBillingGracePeriodEnds: undefined,
@@ -1148,6 +1149,57 @@ describe('MoneyRequest', () => {
             expect(capturedParticipants.length).toBeGreaterThan(0);
             expect(capturedParticipants.at(0)).toMatchObject({isDisabled: false});
         });
+
+        it('should forward hasCompletedGuidedSetupFlow: true to trackExpense', () => {
+            handleMoneyRequestStepDistanceNavigation({
+                ...baseParams,
+                manualDistance: 20,
+                shouldSkipConfirmation: true,
+                iouType: CONST.IOU.TYPE.TRACK,
+                draftTransactionIDs: [baseParams.transactionID],
+                hasCompletedGuidedSetupFlow: true,
+            });
+
+            expect(TrackExpense.trackExpense).toHaveBeenCalledWith(
+                expect.objectContaining({
+                    hasCompletedGuidedSetupFlow: true,
+                }),
+            );
+        });
+
+        it('should forward hasCompletedGuidedSetupFlow: false to trackExpense', () => {
+            handleMoneyRequestStepDistanceNavigation({
+                ...baseParams,
+                manualDistance: 20,
+                shouldSkipConfirmation: true,
+                iouType: CONST.IOU.TYPE.TRACK,
+                draftTransactionIDs: [baseParams.transactionID],
+                hasCompletedGuidedSetupFlow: false,
+            });
+
+            expect(TrackExpense.trackExpense).toHaveBeenCalledWith(
+                expect.objectContaining({
+                    hasCompletedGuidedSetupFlow: false,
+                }),
+            );
+        });
+
+        it('should forward hasCompletedGuidedSetupFlow to trackExpense for waypoints-based track expense', () => {
+            handleMoneyRequestStepDistanceNavigation({
+                ...baseParams,
+                manualDistance: undefined,
+                shouldSkipConfirmation: true,
+                iouType: CONST.IOU.TYPE.TRACK,
+                draftTransactionIDs: [baseParams.transactionID],
+                hasCompletedGuidedSetupFlow: true,
+            });
+
+            expect(TrackExpense.trackExpense).toHaveBeenCalledWith(
+                expect.objectContaining({
+                    hasCompletedGuidedSetupFlow: true,
+                }),
+            );
+        });
     });
 
     describe('getMoneyRequestParticipantOptions', () => {
