Skip to content

Commit 687a6b4

Browse files
committed
fix: started scan logic in useReceiptScan hook with routeName
1 parent 9d97de3 commit 687a6b4

10 files changed

Lines changed: 105 additions & 75 deletions

File tree

src/pages/iou/request/IOURequestStartPage.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ function IOURequestStartPage({
9898
});
9999

100100
const [lastSelectedDistanceRates] = useOnyx(ONYXKEYS.NVP_LAST_SELECTED_DISTANCE_RATES);
101-
const [isMultiScanEnabled, setIsMultiScanEnabled] = useState(false);
102101
const [currentDate] = useOnyx(ONYXKEYS.CURRENT_DATE);
103102
const {isOffline} = useNetwork();
104103
const [hasUserSubmittedExpenseOrScannedReceipt] = useOnyx(ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING, {selector: isTestReceiptTooltipDismissedSelector});
@@ -188,7 +187,6 @@ function IOURequestStartPage({
188187
if (transaction?.iouRequestType === newIOUType) {
189188
return;
190189
}
191-
setIsMultiScanEnabled(false);
192190
initMoneyRequest({
193191
reportID,
194192
policy,
@@ -347,14 +345,12 @@ function IOURequestStartPage({
347345
{() => (
348346
<TabScreenWithFocusTrapWrapper>
349347
<IOURequestStepScan
348+
key={transactionRequestType}
350349
route={route}
351350
navigation={navigation}
352351
onLayout={(setTestReceiptAndNavigate) => {
353352
setTestReceiptAndNavigateRef.current = setTestReceiptAndNavigate;
354353
}}
355-
isMultiScanEnabled={isMultiScanEnabled}
356-
setIsMultiScanEnabled={setIsMultiScanEnabled}
357-
isStartingScan
358354
/>
359355
</TabScreenWithFocusTrapWrapper>
360356
)}

src/pages/iou/request/step/IOURequestStepScan/components/MobileWebCameraView.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ type MobileWebCameraViewProps = {
4141
iouType: IOUType;
4242
currentUserPersonalDetails: CurrentUserPersonalDetails;
4343
reportID: string;
44-
isMultiScanEnabled?: boolean;
45-
isStartingScan?: boolean;
44+
isMultiScanEnabled: boolean;
45+
isStartingScan: boolean;
4646
updateScanAndNavigate: (file: FileObject, source: string) => void;
47-
setIsMultiScanEnabled?: (value: boolean) => void;
47+
setIsMultiScanEnabled: (value: boolean) => void;
4848
PDFValidationComponent: React.ReactNode;
4949
shouldAcceptMultipleFiles: boolean;
5050
receiptFiles: ReceiptFile[];
@@ -54,8 +54,8 @@ type MobileWebCameraViewProps = {
5454
navigateToConfirmationStep: (files: ReceiptFile[], locationPermissionGranted?: boolean, isTestTransaction?: boolean) => void;
5555
shouldSkipConfirmation: boolean;
5656
setStartLocationPermissionFlow: (value: boolean) => void;
57-
onLayout?: () => void;
5857
onBackButtonPress: () => void;
58+
onLayout?: () => void;
5959
shouldShowWrapper: boolean;
6060
};
6161

@@ -65,7 +65,7 @@ function MobileWebCameraView({
6565
iouType,
6666
currentUserPersonalDetails,
6767
reportID,
68-
isMultiScanEnabled = false,
68+
isMultiScanEnabled,
6969
isStartingScan,
7070
updateScanAndNavigate,
7171
setIsMultiScanEnabled,
@@ -78,8 +78,8 @@ function MobileWebCameraView({
7878
navigateToConfirmationStep,
7979
shouldSkipConfirmation,
8080
setStartLocationPermissionFlow,
81-
onLayout,
8281
onBackButtonPress,
82+
onLayout,
8383
shouldShowWrapper,
8484
}: MobileWebCameraViewProps) {
8585
const {blinkStyle, canUseMultiScan, shouldShowMultiScanEducationalPopup, showBlink, toggleMultiScan, dismissMultiScanEducationalPopup, submitReceipts, submitMultiScanReceipts} =
@@ -93,6 +93,7 @@ function MobileWebCameraView({
9393
shouldSkipConfirmation,
9494
setStartLocationPermissionFlow,
9595
setIsMultiScanEnabled,
96+
setReceiptFiles,
9697
});
9798
const theme = useTheme();
9899
const styles = useThemeStyles();

src/pages/iou/request/step/IOURequestStepScan/hooks/useMobileReceiptScan.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ import {validTransactionDraftIDsSelector} from '@src/selectors/TransactionDraft'
1818
function useMobileReceiptScan({
1919
initialTransaction,
2020
iouType,
21-
isMultiScanEnabled = false,
22-
isStartingScan = false,
21+
isMultiScanEnabled,
22+
isStartingScan,
2323
receiptFiles,
2424
navigateToConfirmationStep,
2525
shouldSkipConfirmation,
2626
setStartLocationPermissionFlow,
2727
setIsMultiScanEnabled,
28+
setReceiptFiles,
2829
}: UseMobileReceiptScanParams) {
2930
const [shouldStartLocationPermissionFlow] = useOnyx(ONYXKEYS.NVP_LAST_LOCATION_PERMISSION_PROMPT, {
3031
selector: shouldStartLocationPermissionFlowSelector,
@@ -78,7 +79,10 @@ function useMobileReceiptScan({
7879
}
7980
removeTransactionReceipt(CONST.IOU.OPTIMISTIC_TRANSACTION_ID);
8081
removeDraftTransactionsByIDs(draftTransactionIDs, true);
81-
setIsMultiScanEnabled?.(!isMultiScanEnabled);
82+
if (isMultiScanEnabled) {
83+
setReceiptFiles([]);
84+
}
85+
setIsMultiScanEnabled(!isMultiScanEnabled);
8286
}
8387

8488
function dismissMultiScanEducationalPopup() {

src/pages/iou/request/step/IOURequestStepScan/hooks/useReceiptScan.ts

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import shouldStartLocationPermissionFlowSelector from '@selectors/LocationPermission';
22
import {hasSeenTourSelector} from '@selectors/Onboarding';
3-
import {useEffect, useMemo, useState} from 'react';
3+
import {useMemo, useState} from 'react';
44
import TestReceipt from '@assets/images/fake-receipt.png';
55
import useDefaultExpensePolicy from '@hooks/useDefaultExpensePolicy';
66
import useFilesValidation from '@hooks/useFilesValidation';
@@ -24,6 +24,7 @@ import {setMoneyRequestReceipt} from '@userActions/IOU';
2424
import {buildOptimisticTransactionAndCreateDraft, removeDraftTransactionsByIDs} from '@userActions/TransactionEdit';
2525
import CONST from '@src/CONST';
2626
import ONYXKEYS from '@src/ONYXKEYS';
27+
import SCREENS from '@src/SCREENS';
2728
import {validTransactionDraftsSelector} from '@src/selectors/TransactionDraft';
2829
import type Transaction from '@src/types/onyx/Transaction';
2930
import type {FileObject} from '@src/types/utils/Attachment';
@@ -38,8 +39,7 @@ function useReceiptScan({
3839
currentUserPersonalDetails,
3940
backTo,
4041
backToReport,
41-
isMultiScanEnabled = false,
42-
isStartingScan = false,
42+
routeName,
4343
updateScanAndNavigate,
4444
getSource,
4545
}: UseReceiptScanParams) {
@@ -70,9 +70,11 @@ function useReceiptScan({
7070
const [userBillingGracePeriodEnds] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END);
7171
const [ownerBillingGracePeriodEnd] = useOnyx(ONYXKEYS.NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END);
7272
const draftTransactionIDs = Object.keys(allTransactionDrafts ?? {});
73+
const [isMultiScanEnabled, setIsMultiScanEnabled] = useState(false);
7374

7475
const isEditing = action === CONST.IOU.ACTION.EDIT;
7576
const isReplacingReceipt = (isEditing && hasReceipt(initialTransaction)) || (!!initialTransaction?.receipt && !!backTo);
77+
const isStartingScan = routeName === SCREENS.MONEY_REQUEST.CREATE;
7678
const shouldAcceptMultipleFiles = !isEditing && !backTo;
7779
const shouldGenerateTransactionThreadReport = !isBetaEnabled(CONST.BETAS.NO_OPTIMISTIC_TRANSACTION_THREADS);
7880
const isASAPSubmitBetaEnabled = isBetaEnabled(CONST.BETAS.ASAP_SUBMIT);
@@ -90,15 +92,6 @@ function useReceiptScan({
9092
const [startLocationPermissionFlow, setStartLocationPermissionFlow] = useState(false);
9193
const [receiptFiles, setReceiptFiles] = useState<ReceiptFile[]>([]);
9294

93-
// Clear receipt files when multi-scan is disabled
94-
useEffect(() => {
95-
if (isMultiScanEnabled) {
96-
return;
97-
}
98-
// eslint-disable-next-line react-hooks/set-state-in-effect
99-
setReceiptFiles([]);
100-
}, [isMultiScanEnabled]);
101-
10295
const [recentWaypoints] = useOnyx(ONYXKEYS.NVP_RECENT_WAYPOINTS);
10396

10497
const participants = useMemo(
@@ -232,6 +225,9 @@ function useReceiptScan({
232225
});
233226
return {
234227
transactions,
228+
isMultiScanEnabled,
229+
setIsMultiScanEnabled,
230+
isStartingScan,
235231
isEditing,
236232
isReplacingReceipt,
237233
shouldAcceptMultipleFiles,

src/pages/iou/request/step/IOURequestStepScan/index.native.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,12 @@ import type IOURequestStepScanProps from './types';
5555
function IOURequestStepScan({
5656
report,
5757
route: {
58+
name: routeName,
5859
params: {action, iouType, reportID, transactionID: initialTransactionID, backTo, backToReport},
5960
},
6061
transaction: initialTransaction,
6162
currentUserPersonalDetails,
6263
onLayout,
63-
isMultiScanEnabled = false,
64-
isStartingScan = false,
65-
setIsMultiScanEnabled,
6664
}: IOURequestStepScanProps) {
6765
const theme = useTheme();
6866
const styles = useThemeStyles();
@@ -218,6 +216,9 @@ function IOURequestStepScan({
218216

219217
const {
220218
isEditing,
219+
isMultiScanEnabled,
220+
setIsMultiScanEnabled,
221+
isStartingScan,
221222
shouldAcceptMultipleFiles,
222223
shouldSkipConfirmation,
223224
startLocationPermissionFlow,
@@ -239,8 +240,7 @@ function IOURequestStepScan({
239240
currentUserPersonalDetails,
240241
backTo,
241242
backToReport,
242-
isMultiScanEnabled,
243-
isStartingScan,
243+
routeName,
244244
updateScanAndNavigate,
245245
getSource,
246246
});
@@ -256,6 +256,7 @@ function IOURequestStepScan({
256256
shouldSkipConfirmation,
257257
setStartLocationPermissionFlow,
258258
setIsMultiScanEnabled,
259+
setReceiptFiles,
259260
});
260261

261262
const maybeCancelShutterSpan = useCallback(() => {

src/pages/iou/request/step/IOURequestStepScan/index.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,12 @@ import type IOURequestStepScanProps from './types';
2727
function IOURequestStepScan({
2828
report,
2929
route: {
30+
name: routeName,
3031
params: {action, iouType, reportID, transactionID: initialTransactionID, backTo, backToReport},
3132
},
3233
transaction: initialTransaction,
3334
currentUserPersonalDetails,
3435
onLayout,
35-
isMultiScanEnabled = false,
36-
isStartingScan = false,
37-
setIsMultiScanEnabled,
3836
}: Omit<IOURequestStepScanProps, 'user'>) {
3937
const isMobileWeb = isMobile();
4038
const policy = usePolicy(report?.policyID);
@@ -62,6 +60,9 @@ function IOURequestStepScan({
6260

6361
const {
6462
transactions,
63+
isMultiScanEnabled,
64+
setIsMultiScanEnabled,
65+
isStartingScan,
6566
isEditing,
6667
isReplacingReceipt,
6768
shouldAcceptMultipleFiles,
@@ -85,8 +86,7 @@ function IOURequestStepScan({
8586
currentUserPersonalDetails,
8687
backTo,
8788
backToReport,
88-
isMultiScanEnabled,
89-
isStartingScan,
89+
routeName,
9090
updateScanAndNavigate,
9191
getSource,
9292
});
@@ -127,7 +127,7 @@ function IOURequestStepScan({
127127
if (isAllScanFilesCanBeRead) {
128128
return;
129129
}
130-
setIsMultiScanEnabled?.(false);
130+
setIsMultiScanEnabled(false);
131131
removeTransactionReceipt(CONST.IOU.OPTIMISTIC_TRANSACTION_ID);
132132
removeDraftTransactionsByIDs(draftTransactionIDs, true);
133133
});

src/pages/iou/request/step/IOURequestStepScan/types.ts

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,8 @@ type UseReceiptScanParams = {
3838
/** Report ID to navigate back to */
3939
backToReport: string | undefined;
4040

41-
/** Whether multi-scan is enabled */
42-
isMultiScanEnabled: boolean | undefined;
43-
44-
/** Whether the user is starting a scan request */
45-
isStartingScan: boolean | undefined;
41+
/** The route name to determine if scan is starting */
42+
routeName: string;
4643

4744
/** Callback to replace receipt and navigate back when editing */
4845
updateScanAndNavigate: (file: FileObject, source: string) => void;
@@ -62,7 +59,7 @@ type UseMobileReceiptScanParams = {
6259
isMultiScanEnabled?: boolean;
6360

6461
/** Whether the user is starting a scan request */
65-
isStartingScan?: boolean;
62+
isStartingScan: boolean;
6663

6764
/** The current receipt files being scanned */
6865
receiptFiles: ReceiptFile[];
@@ -76,8 +73,11 @@ type UseMobileReceiptScanParams = {
7673
/** Callback to start the location permission flow */
7774
setStartLocationPermissionFlow: (value: boolean) => void;
7875

79-
/** Callback to update multi-scan enabled state in parent */
80-
setIsMultiScanEnabled: ((value: boolean) => void) | undefined;
76+
/** Callback to update multi-scan enabled state */
77+
setIsMultiScanEnabled: (value: boolean) => void;
78+
79+
/** Callback to update scanned receipt files */
80+
setReceiptFiles: (value: ReceiptFile[]) => void;
8181
};
8282

8383
type IOURequestStepScanProps = WithCurrentUserPersonalDetailsProps &
@@ -90,15 +90,6 @@ type IOURequestStepScanProps = WithCurrentUserPersonalDetailsProps &
9090
* Receives a function (`setTestReceiptAndNavigate`) as an argument,
9191
*/
9292
onLayout?: (setTestReceiptAndNavigate: () => void) => void;
93-
94-
/** If the receipts preview should be shown */
95-
isMultiScanEnabled?: boolean;
96-
97-
/** Updates isMultiScanEnabled flag */
98-
setIsMultiScanEnabled?: (value: boolean) => void;
99-
100-
/** Indicates whether users start to create scan request */
101-
isStartingScan?: boolean;
10293
};
10394

10495
type ReceiptFile = {

tests/ui/IOURequestStepScanTest.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {NavigationContainer} from '@react-navigation/native';
2-
import {act, render} from '@testing-library/react-native';
2+
import {act, fireEvent, render, screen} from '@testing-library/react-native';
33
import React from 'react';
44
import Onyx from 'react-native-onyx';
55
import type {OnyxEntry} from 'react-native-onyx';
@@ -172,14 +172,8 @@ describe('IOURequestStepScan', () => {
172172
const POLICY_ID = 'policy-1';
173173
const TRANSACTION_ID_1 = '101';
174174

175-
const transaction1 = createRandomTransaction(1);
176-
transaction1.reportID = REPORT_ID;
177-
transaction1.transactionID = TRANSACTION_ID_1;
178-
transaction1.receipt = {source: 'file://first-receipt.png', state: CONST.IOU.RECEIPT_STATE.OPEN};
179-
180175
await act(async () => {
181176
await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, createMinimalReport(REPORT_ID, POLICY_ID));
182-
await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID_1}`, transaction1);
183177
});
184178
await waitForBatchedUpdates();
185179

@@ -191,7 +185,7 @@ describe('IOURequestStepScan', () => {
191185
route={
192186
{
193187
key: 'StepScan2',
194-
name: SCREENS.MONEY_REQUEST.STEP_SCAN,
188+
name: SCREENS.MONEY_REQUEST.CREATE,
195189
params: {
196190
action: CONST.IOU.ACTION.CREATE,
197191
iouType: CONST.IOU.TYPE.SUBMIT,
@@ -202,16 +196,24 @@ describe('IOURequestStepScan', () => {
202196
} as unknown as PlatformStackScreenProps<MoneyRequestNavigatorParamList, typeof SCREENS.MONEY_REQUEST.STEP_SCAN>['route']
203197
}
204198
navigation={{} as never}
205-
isMultiScanEnabled
206-
isStartingScan
207-
setIsMultiScanEnabled={jest.fn()}
208199
/>
209200
</NavigationContainer>
210201
</LocaleContextProvider>
211202
</OnyxListItemProvider>,
212203
);
213204

214205
await waitForBatchedUpdatesWithAct();
206+
fireEvent.press(screen.getByLabelText('multi-scan'));
207+
await waitForBatchedUpdatesWithAct();
208+
const transaction1 = createRandomTransaction(1);
209+
transaction1.reportID = REPORT_ID;
210+
transaction1.transactionID = TRANSACTION_ID_1;
211+
transaction1.receipt = {source: 'file://first-receipt.png', state: CONST.IOU.RECEIPT_STATE.OPEN};
212+
213+
await act(async () => {
214+
await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID_1}`, transaction1);
215+
});
216+
await waitForBatchedUpdates();
215217

216218
expect(triggerFileSelection).not.toBeNull();
217219

0 commit comments

Comments
 (0)