Skip to content
1 change: 1 addition & 0 deletions src/libs/TransactionUtils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@

let allTransactions: OnyxCollection<Transaction> = {};

Onyx.connect({

Check warning on line 117 in src/libs/TransactionUtils/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.TRANSACTION,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -126,7 +126,7 @@
});

let allReports: OnyxCollection<Report> = {};
Onyx.connect({

Check warning on line 129 in src/libs/TransactionUtils/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.REPORT,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -135,7 +135,7 @@
});

let allTransactionViolations: OnyxCollection<TransactionViolations> = {};
Onyx.connect({

Check warning on line 138 in src/libs/TransactionUtils/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS,
waitForCollectionCallback: true,
callback: (value) => (allTransactionViolations = value),
Expand All @@ -143,7 +143,7 @@

let currentUserEmail = '';
let currentUserAccountID = -1;
Onyx.connect({

Check warning on line 146 in src/libs/TransactionUtils/index.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.SESSION,
callback: (val) => {
currentUserEmail = val?.email ?? '';
Expand Down Expand Up @@ -2004,6 +2004,7 @@
getValidWaypoints,
getValidDuplicateTransactionIDs,
isDistanceRequest,
isMapDistanceRequest,
isManualDistanceRequest,
isFetchingWaypointsFromServer,
isExpensifyCardTransaction,
Expand Down
9 changes: 9 additions & 0 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@
isDuplicate,
isFetchingWaypointsFromServer,
isManualDistanceRequest as isManualDistanceRequestTransactionUtils,
isMapDistanceRequest,
isOnHold,
isPendingCardOrScanningTransaction,
isPerDiemRequest as isPerDiemRequestTransactionUtils,
Expand Down Expand Up @@ -670,7 +671,7 @@
};

let allPersonalDetails: OnyxTypes.PersonalDetailsList = {};
Onyx.connect({

Check warning on line 674 in src/libs/actions/IOU.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.PERSONAL_DETAILS_LIST,
callback: (value) => {
allPersonalDetails = value ?? {};
Expand Down Expand Up @@ -711,13 +712,13 @@
};

let allBetas: OnyxEntry<OnyxTypes.Beta[]>;
Onyx.connect({

Check warning on line 715 in src/libs/actions/IOU.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.BETAS,
callback: (value) => (allBetas = value),
});

let allTransactions: NonNullable<OnyxCollection<OnyxTypes.Transaction>> = {};
Onyx.connect({

Check warning on line 721 in src/libs/actions/IOU.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.TRANSACTION,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -731,7 +732,7 @@
});

let allTransactionDrafts: NonNullable<OnyxCollection<OnyxTypes.Transaction>> = {};
Onyx.connect({

Check warning on line 735 in src/libs/actions/IOU.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.TRANSACTION_DRAFT,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -740,7 +741,7 @@
});

let allTransactionViolations: NonNullable<OnyxCollection<OnyxTypes.TransactionViolations>> = {};
Onyx.connect({

Check warning on line 744 in src/libs/actions/IOU.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS,
waitForCollectionCallback: true,
callback: (value) => {
Expand All @@ -754,7 +755,7 @@
});

let allDraftSplitTransactions: NonNullable<OnyxCollection<OnyxTypes.Transaction>> = {};
Onyx.connect({

Check warning on line 758 in src/libs/actions/IOU.ts

View workflow job for this annotation

GitHub Actions / Changed files ESLint check

Onyx.connect() is deprecated. Use useOnyx() hook instead and pass the data as parameters to a pure function
key: ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT,
waitForCollectionCallback: true,
callback: (value) => {
Expand Down Expand Up @@ -6096,6 +6097,14 @@
value: recentServerValidatedWaypoints,
});

if (isMapDistanceRequest(transaction) || isManualDistanceRequestTransactionUtils(transaction)) {
onyxData?.optimisticData?.push({
onyxMethod: Onyx.METHOD.SET,
key: ONYXKEYS.NVP_LAST_DISTANCE_EXPENSE_TYPE,
value: transaction?.iouRequestType,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NAB: We only need to set this value when IOU request type is manual since map is the default.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really important though, and maybe this is more clear

});
}

const mileageRate = isCustomUnitRateIDForP2P(transaction) ? undefined : customUnitRateID;
if (shouldPlaySound) {
playSound(SOUNDS.DONE);
Expand Down
31 changes: 22 additions & 9 deletions src/libs/actions/QuickActionNavigation.ts
Original file line number Diff line number Diff line change
@@ -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,
Comment on lines +19 to +21

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm... I think it would be better to add these as a object.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's already an object parameter:

function navigateToQuickAction(params: NavigateToQuickActionParams) {

): IOURequestType | undefined {
if (!action) {
return;
}
Expand All @@ -17,22 +30,22 @@ 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;
}

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:
Expand Down
3 changes: 2 additions & 1 deletion src/pages/home/sidebar/FloatingActionButtonAndPopover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, isT
showDelegateNoAccessModal();
return;
}
navigateToQuickAction(isValidReport, quickAction, selectOption, isManualDistanceTrackingEnabled);
navigateToQuickAction({isValidReport, quickAction, selectOption, isManualDistanceTrackingEnabled, lastDistanceExpenseType});
});
};
return [
Expand Down Expand Up @@ -409,6 +409,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu, isT
showDelegateNoAccessModal,
isReportArchived,
isManualDistanceTrackingEnabled,
lastDistanceExpenseType,
allTransactionDrafts,
]);

Expand Down
72 changes: 61 additions & 11 deletions tests/unit/QuickActionNavigationTest.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
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';
import CONST from '@src/CONST';

jest.mock('@libs/actions/IOU', () => ({
startMoneyRequest: jest.fn(),
startDistanceRequest: jest.fn(),
}));
jest.mock('@libs/actions/Report', () => ({
createNewReport: jest.fn(),
Expand All @@ -21,35 +22,80 @@ 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);
});

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);
});

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);
Expand All @@ -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();
});
Expand Down
Loading