diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index 803d0a036c92..493ae6ac36be 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -2004,6 +2004,7 @@ export { getValidWaypoints, getValidDuplicateTransactionIDs, isDistanceRequest, + isMapDistanceRequest, isManualDistanceRequest, isFetchingWaypointsFromServer, isExpensifyCardTransaction, diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index bdb0f05de563..d8750e3e1cdb 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -215,6 +215,7 @@ import { isDuplicate, isFetchingWaypointsFromServer, isManualDistanceRequest as isManualDistanceRequestTransactionUtils, + isMapDistanceRequest, isOnHold, isPendingCardOrScanningTransaction, isPerDiemRequest as isPerDiemRequestTransactionUtils, @@ -6096,6 +6097,14 @@ function trackExpense(params: CreateTrackExpenseParams) { value: recentServerValidatedWaypoints, }); + if (isMapDistanceRequest(transaction) || isManualDistanceRequestTransactionUtils(transaction)) { + onyxData?.optimisticData?.push({ + onyxMethod: Onyx.METHOD.SET, + key: ONYXKEYS.NVP_LAST_DISTANCE_EXPENSE_TYPE, + value: transaction?.iouRequestType, + }); + } + const mileageRate = isCustomUnitRateIDForP2P(transaction) ? undefined : customUnitRateID; if (shouldPlaySound) { playSound(SOUNDS.DONE); diff --git a/src/libs/actions/QuickActionNavigation.ts b/src/libs/actions/QuickActionNavigation.ts index 1e7927486d00..de8adae1eda6 100644 --- a/src/libs/actions/QuickActionNavigation.ts +++ b/src/libs/actions/QuickActionNavigation.ts @@ -1,12 +1,25 @@ import {generateReportID} from '@libs/ReportUtils'; import CONST from '@src/CONST'; +import type {DistanceExpenseType} from '@src/types/onyx/IOU'; import type {QuickActionName} from '@src/types/onyx/QuickAction'; import type QuickAction from '@src/types/onyx/QuickAction'; import type {IOURequestType} from './IOU'; import {startDistanceRequest, startMoneyRequest} from './IOU'; import {startOutCreateTaskQuickAction} from './Task'; -function getQuickActionRequestType(action: QuickActionName | undefined): IOURequestType | undefined { +type NavigateToQuickActionParams = { + isValidReport: boolean; + quickAction: QuickAction; + selectOption: (onSelected: () => void, shouldRestrictAction: boolean) => void; + isManualDistanceTrackingEnabled?: boolean; + lastDistanceExpenseType?: DistanceExpenseType; +}; + +function getQuickActionRequestType( + action: QuickActionName | undefined, + lastDistanceExpenseType?: DistanceExpenseType, + isManualDistanceTrackingEnabled?: boolean, +): IOURequestType | undefined { if (!action) { return; } @@ -17,7 +30,11 @@ function getQuickActionRequestType(action: QuickActionName | undefined): IOURequ } else if ([CONST.QUICK_ACTIONS.REQUEST_SCAN, CONST.QUICK_ACTIONS.SPLIT_SCAN, CONST.QUICK_ACTIONS.TRACK_SCAN].some((a) => a === action)) { requestType = CONST.IOU.REQUEST_TYPE.SCAN; } else if ([CONST.QUICK_ACTIONS.REQUEST_DISTANCE, CONST.QUICK_ACTIONS.SPLIT_DISTANCE, CONST.QUICK_ACTIONS.TRACK_DISTANCE].some((a) => a === action)) { - requestType = CONST.IOU.REQUEST_TYPE.DISTANCE; + if (isManualDistanceTrackingEnabled) { + requestType = lastDistanceExpenseType ?? CONST.IOU.REQUEST_TYPE.DISTANCE_MAP; + } else { + requestType = CONST.IOU.REQUEST_TYPE.DISTANCE; + } } else if (action === CONST.QUICK_ACTIONS.PER_DIEM) { requestType = CONST.IOU.REQUEST_TYPE.PER_DIEM; } @@ -25,14 +42,10 @@ function getQuickActionRequestType(action: QuickActionName | undefined): IOURequ return requestType; } -function navigateToQuickAction( - isValidReport: boolean, - quickAction: QuickAction, - selectOption: (onSelected: () => void, shouldRestrictAction: boolean) => void, - isManualDistanceTrackingEnabled?: boolean, -) { +function navigateToQuickAction(params: NavigateToQuickActionParams) { + const {isValidReport, quickAction, selectOption, isManualDistanceTrackingEnabled, lastDistanceExpenseType} = params; const reportID = isValidReport && quickAction?.chatReportID ? quickAction?.chatReportID : generateReportID(); - const requestType = getQuickActionRequestType(quickAction?.action); + const requestType = getQuickActionRequestType(quickAction?.action, lastDistanceExpenseType, isManualDistanceTrackingEnabled); switch (quickAction?.action) { case CONST.QUICK_ACTIONS.REQUEST_MANUAL: diff --git a/src/pages/home/sidebar/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/FloatingActionButtonAndPopover.tsx index 4de18884e170..a6934c2b00ab 100644 --- a/src/pages/home/sidebar/FloatingActionButtonAndPopover.tsx +++ b/src/pages/home/sidebar/FloatingActionButtonAndPopover.tsx @@ -348,7 +348,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, isT showDelegateNoAccessModal(); return; } - navigateToQuickAction(isValidReport, quickAction, selectOption, isManualDistanceTrackingEnabled); + navigateToQuickAction({isValidReport, quickAction, selectOption, isManualDistanceTrackingEnabled, lastDistanceExpenseType}); }); }; return [ @@ -409,6 +409,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, isT showDelegateNoAccessModal, isReportArchived, isManualDistanceTrackingEnabled, + lastDistanceExpenseType, allTransactionDrafts, ]); diff --git a/tests/unit/QuickActionNavigationTest.ts b/tests/unit/QuickActionNavigationTest.ts index 687b8263f50c..bab2c1c5d89d 100644 --- a/tests/unit/QuickActionNavigationTest.ts +++ b/tests/unit/QuickActionNavigationTest.ts @@ -1,4 +1,4 @@ -import {startMoneyRequest} from '@libs/actions/IOU'; +import {startDistanceRequest, startMoneyRequest} from '@libs/actions/IOU'; import {navigateToQuickAction} from '@libs/actions/QuickActionNavigation'; import {startOutCreateTaskQuickAction} from '@libs/actions/Task'; import {generateReportID} from '@libs/ReportUtils'; @@ -6,6 +6,7 @@ import CONST from '@src/CONST'; jest.mock('@libs/actions/IOU', () => ({ startMoneyRequest: jest.fn(), + startDistanceRequest: jest.fn(), })); jest.mock('@libs/actions/Report', () => ({ createNewReport: jest.fn(), @@ -21,8 +22,12 @@ describe('IOU Utils', () => { it('should be navigated to Manual Submit Expense', () => { // When the quick action is REQUEST_MANUAL - navigateToQuickAction(true, {action: CONST.QUICK_ACTIONS.REQUEST_MANUAL, chatReportID: reportID}, (onSelected: () => void) => { - onSelected(); + navigateToQuickAction({ + isValidReport: true, + quickAction: {action: CONST.QUICK_ACTIONS.REQUEST_MANUAL, chatReportID: reportID}, + selectOption: (onSelected: () => void) => { + onSelected(); + }, }); // Then we should start manual submit request flow expect(startMoneyRequest).toHaveBeenCalledWith(CONST.IOU.TYPE.SUBMIT, reportID, CONST.IOU.REQUEST_TYPE.MANUAL, true); @@ -30,8 +35,12 @@ describe('IOU Utils', () => { it('should be navigated to Scan receipt Split Expense', () => { // When the quick action is SPLIT_SCAN - navigateToQuickAction(true, {action: CONST.QUICK_ACTIONS.SPLIT_SCAN, chatReportID: reportID}, (onSelected: () => void) => { - onSelected(); + navigateToQuickAction({ + isValidReport: true, + quickAction: {action: CONST.QUICK_ACTIONS.SPLIT_SCAN, chatReportID: reportID}, + selectOption: (onSelected: () => void) => { + onSelected(); + }, }); // Then we should start scan split request flow expect(startMoneyRequest).toHaveBeenCalledWith(CONST.IOU.TYPE.SPLIT, reportID, CONST.IOU.REQUEST_TYPE.SCAN, true); @@ -39,17 +48,54 @@ describe('IOU Utils', () => { it('should be navigated to Track distance Expense', () => { // When the quick action is TRACK_DISTANCE - navigateToQuickAction(true, {action: CONST.QUICK_ACTIONS.TRACK_DISTANCE, chatReportID: reportID}, (onSelected: () => void) => { - onSelected(); + navigateToQuickAction({ + isValidReport: true, + quickAction: {action: CONST.QUICK_ACTIONS.TRACK_DISTANCE, chatReportID: reportID}, + selectOption: (onSelected: () => void) => { + onSelected(); + }, }); // Then we should start distance track request flow expect(startMoneyRequest).toHaveBeenCalledWith(CONST.IOU.TYPE.TRACK, reportID, CONST.IOU.REQUEST_TYPE.DISTANCE, true); }); + it('should be navigated to Map distance Expense if isManualDistanceTrackingEnabled beta', () => { + // When the quick action is REQUEST_DISTANCE and isManualDistanceTrackingEnabled + navigateToQuickAction({ + isValidReport: true, + quickAction: {action: CONST.QUICK_ACTIONS.REQUEST_DISTANCE, chatReportID: reportID}, + selectOption: (onSelected: () => void) => { + onSelected(); + }, + isManualDistanceTrackingEnabled: true, + }); + // Then we should start map distance request flow + expect(startDistanceRequest).toHaveBeenCalledWith(CONST.IOU.TYPE.SUBMIT, reportID, CONST.IOU.REQUEST_TYPE.DISTANCE_MAP, true); + }); + + it('should be navigated to request distance Expense if isManualDistanceTrackingEnabled beta depending on lastDistanceExpenseType', () => { + // When the quick action is REQUEST_DISTANCE and isManualDistanceTrackingEnabled + navigateToQuickAction({ + isValidReport: true, + quickAction: {action: CONST.QUICK_ACTIONS.REQUEST_DISTANCE, chatReportID: reportID}, + selectOption: (onSelected: () => void) => { + onSelected(); + }, + isManualDistanceTrackingEnabled: true, + lastDistanceExpenseType: CONST.IOU.REQUEST_TYPE.DISTANCE_MANUAL, + }); + // Then we should start manual distance request flow + expect(startDistanceRequest).toHaveBeenCalledWith(CONST.IOU.TYPE.SUBMIT, reportID, CONST.IOU.REQUEST_TYPE.DISTANCE_MANUAL, true); + }); + it('should be navigated to Per Diem Expense', () => { // When the quick action is PER_DIEM - navigateToQuickAction(true, {action: CONST.QUICK_ACTIONS.PER_DIEM, chatReportID: reportID}, (onSelected: () => void) => { - onSelected(); + navigateToQuickAction({ + isValidReport: true, + quickAction: {action: CONST.QUICK_ACTIONS.PER_DIEM, chatReportID: reportID}, + selectOption: (onSelected: () => void) => { + onSelected(); + }, }); // Then we should start per diem request flow expect(startMoneyRequest).toHaveBeenCalledWith(CONST.IOU.TYPE.SUBMIT, reportID, CONST.IOU.REQUEST_TYPE.PER_DIEM, true); @@ -60,8 +106,12 @@ describe('IOU Utils', () => { describe('Non IOU quickActions test:', () => { describe('navigateToQuickAction', () => { it('starts create task flow for "assignTask" quick action', () => { - navigateToQuickAction(true, {action: CONST.QUICK_ACTIONS.ASSIGN_TASK, targetAccountID: 123}, (onSelected: () => void) => { - onSelected(); + navigateToQuickAction({ + isValidReport: true, + quickAction: {action: CONST.QUICK_ACTIONS.ASSIGN_TASK, targetAccountID: 123}, + selectOption: (onSelected: () => void) => { + onSelected(); + }, }); expect(startOutCreateTaskQuickAction).toHaveBeenCalled(); });