Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions src/pages/iou/request/IOURequestStartPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ function IOURequestStartPage({
});

const [lastSelectedDistanceRates] = useOnyx(ONYXKEYS.NVP_LAST_SELECTED_DISTANCE_RATES);
const [isMultiScanEnabled, setIsMultiScanEnabled] = useState(false);
const [currentDate] = useOnyx(ONYXKEYS.CURRENT_DATE);
const {isOffline} = useNetwork();
const [hasUserSubmittedExpenseOrScannedReceipt] = useOnyx(ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING, {selector: isTestReceiptTooltipDismissedSelector});
Expand Down Expand Up @@ -186,7 +185,6 @@ function IOURequestStartPage({
if (transaction?.iouRequestType === newIOUType) {
return;
}
setIsMultiScanEnabled(false);
initMoneyRequest({
reportID,
policy,
Expand Down Expand Up @@ -340,14 +338,12 @@ function IOURequestStartPage({
{() => (
<TabScreenWithFocusTrapWrapper>
<IOURequestStepScan
key={transactionRequestType}
route={route}
navigation={navigation}
onLayout={(setTestReceiptAndNavigate) => {
setTestReceiptAndNavigateRef.current = setTestReceiptAndNavigate;
}}
isMultiScanEnabled={isMultiScanEnabled}
setIsMultiScanEnabled={setIsMultiScanEnabled}
isStartingScan
/>
</TabScreenWithFocusTrapWrapper>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,9 @@ type MobileWebCameraViewProps = {
iouType: IOUType;
currentUserPersonalDetails: CurrentUserPersonalDetails;
reportID: string;
isMultiScanEnabled?: boolean;
isStartingScan?: boolean;
isStartingScan: boolean;
updateScanAndNavigate: (file: FileObject, source: string) => void;
setIsMultiScanEnabled?: (value: boolean) => void;
setIsMultiScanEnabled: (value: boolean) => void;
PDFValidationComponent: React.ReactNode;
shouldAcceptMultipleFiles: boolean;
receiptFiles: ReceiptFile[];
Expand All @@ -56,9 +55,10 @@ type MobileWebCameraViewProps = {
navigateToConfirmationStep: (files: ReceiptFile[], locationPermissionGranted?: boolean, isTestTransaction?: boolean) => void;
shouldSkipConfirmation: boolean;
setStartLocationPermissionFlow: (value: boolean) => void;
onLayout?: () => void;
onBackButtonPress: () => void;
shouldShowWrapper: boolean;
isMultiScanEnabled?: boolean;
onLayout?: () => void;
};

/**
Expand Down Expand Up @@ -103,7 +103,6 @@ function MobileWebCameraView({
iouType,
currentUserPersonalDetails,
reportID,
isMultiScanEnabled = false,
isStartingScan,
updateScanAndNavigate,
setIsMultiScanEnabled,
Expand All @@ -116,9 +115,10 @@ function MobileWebCameraView({
navigateToConfirmationStep,
shouldSkipConfirmation,
setStartLocationPermissionFlow,
onLayout,
onBackButtonPress,
shouldShowWrapper,
isMultiScanEnabled = false,
onLayout,
}: MobileWebCameraViewProps) {
const {blinkStyle, canUseMultiScan, shouldShowMultiScanEducationalPopup, showBlink, toggleMultiScan, dismissMultiScanEducationalPopup, submitReceipts, submitMultiScanReceipts} =
useMobileReceiptScan({
Expand All @@ -131,6 +131,7 @@ function MobileWebCameraView({
shouldSkipConfirmation,
setStartLocationPermissionFlow,
setIsMultiScanEnabled,
setReceiptFiles,
});
const theme = useTheme();
const styles = useThemeStyles();
Expand Down Expand Up @@ -444,7 +445,7 @@ function MobileWebCameraView({
) : null}
<Animated.View
pointerEvents="none"
style={[StyleSheet.absoluteFillObject, styles.backgroundWhite, blinkStyle, styles.zIndex10]}
style={[StyleSheet.absoluteFill, styles.backgroundWhite, blinkStyle, styles.zIndex10]}
/>
</View>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ function useMobileReceiptScan({
initialTransaction,
iouType,
isMultiScanEnabled = false,
isStartingScan = false,
isStartingScan,
receiptFiles,
navigateToConfirmationStep,
shouldSkipConfirmation,
setStartLocationPermissionFlow,
setIsMultiScanEnabled,
setReceiptFiles,
}: UseMobileReceiptScanParams) {
const [shouldStartLocationPermissionFlow] = useOnyx(ONYXKEYS.NVP_LAST_LOCATION_PERMISSION_PROMPT, {
selector: shouldStartLocationPermissionFlowSelector,
Expand Down Expand Up @@ -78,7 +79,10 @@ function useMobileReceiptScan({
}
removeTransactionReceipt(CONST.IOU.OPTIMISTIC_TRANSACTION_ID);
removeDraftTransactionsByIDs(draftTransactionIDs, true);
setIsMultiScanEnabled?.(!isMultiScanEnabled);
if (isMultiScanEnabled) {
setReceiptFiles([]);
}
setIsMultiScanEnabled(!isMultiScanEnabled);
}

function dismissMultiScanEducationalPopup() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import shouldStartLocationPermissionFlowSelector from '@selectors/LocationPermission';
import {hasSeenTourSelector} from '@selectors/Onboarding';
import {useEffect, useMemo, useState} from 'react';
import {useMemo, useState} from 'react';
import TestReceipt from '@assets/images/fake-receipt.png';
import useDefaultExpensePolicy from '@hooks/useDefaultExpensePolicy';
import useFilesValidation from '@hooks/useFilesValidation';
Expand Down Expand Up @@ -37,8 +37,6 @@ function useReceiptScan({
currentUserPersonalDetails,
backTo,
backToReport,
isMultiScanEnabled = false,
isStartingScan = false,
updateScanAndNavigate,
getSource,
}: UseReceiptScanParams) {
Expand Down Expand Up @@ -69,6 +67,8 @@ function useReceiptScan({
const [userBillingGracePeriodEnds] = useOnyx(ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_USER_BILLING_GRACE_PERIOD_END);
const [ownerBillingGracePeriodEnd] = useOnyx(ONYXKEYS.NVP_PRIVATE_OWNER_BILLING_GRACE_PERIOD_END);
const draftTransactionIDs = Object.keys(allTransactionDrafts ?? {});
const [isMultiScanEnabled, setIsMultiScanEnabled] = useState(false);
const isStartingScan = action === CONST.IOU.ACTION.CREATE;

const isEditing = action === CONST.IOU.ACTION.EDIT;
const isArchived = isArchivedReport(reportNameValuePairs);
Expand All @@ -90,15 +90,6 @@ function useReceiptScan({
const [startLocationPermissionFlow, setStartLocationPermissionFlow] = useState(false);
const [receiptFiles, setReceiptFiles] = useState<ReceiptFile[]>([]);

// Clear receipt files when multi-scan is disabled
useEffect(() => {
if (isMultiScanEnabled) {
return;
}
// eslint-disable-next-line react-hooks/set-state-in-effect
setReceiptFiles([]);
}, [isMultiScanEnabled]);

const [recentWaypoints] = useOnyx(ONYXKEYS.NVP_RECENT_WAYPOINTS);

const participants = useMemo(
Expand Down Expand Up @@ -232,6 +223,9 @@ function useReceiptScan({
});
return {
transactions,
isMultiScanEnabled,
setIsMultiScanEnabled,
isStartingScan,
isEditing,
isReplacingReceipt,
shouldAcceptMultipleFiles,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,6 @@ function IOURequestStepScan({
transaction: initialTransaction,
currentUserPersonalDetails,
onLayout,
isMultiScanEnabled = false,
isStartingScan = false,
setIsMultiScanEnabled,
}: IOURequestStepScanProps) {
const theme = useTheme();
const styles = useThemeStyles();
Expand Down Expand Up @@ -288,6 +285,9 @@ function IOURequestStepScan({
const getSource = useCallback((file: FileObject) => file.uri ?? '', []);

const {
isMultiScanEnabled,
setIsMultiScanEnabled,
isStartingScan,
isEditing,
shouldAcceptMultipleFiles,
shouldSkipConfirmation,
Expand All @@ -310,8 +310,6 @@ function IOURequestStepScan({
currentUserPersonalDetails,
backTo,
backToReport,
isMultiScanEnabled,
isStartingScan,
updateScanAndNavigate,
getSource,
});
Expand All @@ -327,6 +325,7 @@ function IOURequestStepScan({
shouldSkipConfirmation,
setStartLocationPermissionFlow,
setIsMultiScanEnabled,
setReceiptFiles,
});

const maybeCancelShutterSpan = useCallback(() => {
Expand Down
10 changes: 4 additions & 6 deletions src/pages/iou/request/step/IOURequestStepScan/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ function IOURequestStepScan({
transaction: initialTransaction,
currentUserPersonalDetails,
onLayout,
isMultiScanEnabled = false,
isStartingScan = false,
setIsMultiScanEnabled,
}: Omit<IOURequestStepScanProps, 'user'>) {
const isMobileWeb = isMobile();
const policy = usePolicy(report?.policyID);
Expand Down Expand Up @@ -62,6 +59,9 @@ function IOURequestStepScan({

const {
transactions,
isMultiScanEnabled,
setIsMultiScanEnabled,
isStartingScan,
isEditing,
isReplacingReceipt,
shouldAcceptMultipleFiles,
Expand All @@ -85,8 +85,6 @@ function IOURequestStepScan({
currentUserPersonalDetails,
backTo,
backToReport,
isMultiScanEnabled,
isStartingScan,
updateScanAndNavigate,
getSource,
});
Expand Down Expand Up @@ -127,7 +125,7 @@ function IOURequestStepScan({
if (isAllScanFilesCanBeRead) {
return;
}
setIsMultiScanEnabled?.(false);
setIsMultiScanEnabled(false);
removeTransactionReceipt(CONST.IOU.OPTIMISTIC_TRANSACTION_ID);
removeDraftTransactionsByIDs(draftTransactionIDs, true);
});
Expand Down
24 changes: 6 additions & 18 deletions src/pages/iou/request/step/IOURequestStepScan/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,6 @@ type UseReceiptScanParams = {
/** Report ID to navigate back to */
backToReport: string | undefined;

/** Whether multi-scan is enabled */
isMultiScanEnabled: boolean | undefined;

/** Whether the user is starting a scan request */
isStartingScan: boolean | undefined;

/** Callback to replace receipt and navigate back when editing */
updateScanAndNavigate: (file: FileObject, source: string) => void;

Expand All @@ -62,7 +56,7 @@ type UseMobileReceiptScanParams = {
isMultiScanEnabled?: boolean;

/** Whether the user is starting a scan request */
isStartingScan?: boolean;
isStartingScan: boolean;

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

/** Callback to update multi-scan enabled state in parent */
setIsMultiScanEnabled: ((value: boolean) => void) | undefined;
/** Callback to update multi-scan enabled state */
setIsMultiScanEnabled: (value: boolean) => void;

/** Callback to update scanned receipt files */
setReceiptFiles: (value: ReceiptFile[]) => void;
};

type IOURequestStepScanProps = WithCurrentUserPersonalDetailsProps &
Expand All @@ -90,15 +87,6 @@ type IOURequestStepScanProps = WithCurrentUserPersonalDetailsProps &
* Receives a function (`setTestReceiptAndNavigate`) as an argument,
*/
onLayout?: (setTestReceiptAndNavigate: () => void) => void;

/** If the receipts preview should be shown */
isMultiScanEnabled?: boolean;

/** Updates isMultiScanEnabled flag */
setIsMultiScanEnabled?: (value: boolean) => void;

/** Indicates whether users start to create scan request */
isStartingScan?: boolean;
};

type ReceiptFile = {
Expand Down
10 changes: 7 additions & 3 deletions tests/ui/IOURequestStepScanTest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,15 +171,22 @@ describe('IOURequestStepScan', () => {
const REPORT_ID = '1';
const POLICY_ID = 'policy-1';
const TRANSACTION_ID_1 = '101';
const TRANSACTION_ID_2 = '102';

const transaction1 = createRandomTransaction(1);
transaction1.reportID = REPORT_ID;
transaction1.transactionID = TRANSACTION_ID_1;
transaction1.receipt = {source: 'file://first-receipt.png', state: CONST.IOU.RECEIPT_STATE.OPEN};

const transaction2 = createRandomTransaction(2);
transaction2.reportID = REPORT_ID;
transaction2.transactionID = TRANSACTION_ID_2;
transaction2.receipt = {source: 'file://second-receipt.png', state: CONST.IOU.RECEIPT_STATE.OPEN};

await act(async () => {
await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, createMinimalReport(REPORT_ID, POLICY_ID));
await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID_1}`, transaction1);
await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${TRANSACTION_ID_2}`, transaction2);
});
await waitForBatchedUpdates();

Expand All @@ -202,9 +209,6 @@ describe('IOURequestStepScan', () => {
} as unknown as PlatformStackScreenProps<MoneyRequestNavigatorParamList, typeof SCREENS.MONEY_REQUEST.STEP_SCAN>['route']
}
navigation={{} as never}
isMultiScanEnabled
isStartingScan
setIsMultiScanEnabled={jest.fn()}
/>
</NavigationContainer>
</LocaleContextProvider>
Expand Down
31 changes: 31 additions & 0 deletions tests/unit/hooks/useMobileReceiptScan.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ function createDefaultParams(): UseMobileReceiptScanParams {
shouldSkipConfirmation: false,
setStartLocationPermissionFlow: jest.fn(),
setIsMultiScanEnabled: jest.fn(),
setReceiptFiles: jest.fn(),
};
}

Expand Down Expand Up @@ -129,6 +130,36 @@ describe('useMobileReceiptScan', () => {
expect(mockRemoveTransactionReceipt).toHaveBeenCalledWith(CONST.IOU.OPTIMISTIC_TRANSACTION_ID);
expect(mockRemoveDraftTransactions).toHaveBeenCalledWith(expect.anything(), true);
});

it('should clear receiptFiles when disabling multi-scan', async () => {
const setIsMultiScanEnabled = jest.fn();
const setReceiptFiles = jest.fn();
const toggleParams = {...params, setIsMultiScanEnabled, setReceiptFiles, isMultiScanEnabled: true};
const {result} = renderHook(() => useMobileReceiptScan(toggleParams));
await waitForBatchedUpdatesWithAct();

await act(async () => {
result.current.toggleMultiScan();
});

expect(setReceiptFiles).toHaveBeenCalledWith([]);
expect(setIsMultiScanEnabled).toHaveBeenCalledWith(false);
});

it('should not clear receiptFiles when enabling multi-scan', async () => {
const setIsMultiScanEnabled = jest.fn();
const setReceiptFiles = jest.fn();
const toggleParams = {...params, setIsMultiScanEnabled, setReceiptFiles, isMultiScanEnabled: false};
const {result} = renderHook(() => useMobileReceiptScan(toggleParams));
await waitForBatchedUpdatesWithAct();

await act(async () => {
result.current.toggleMultiScan();
});

expect(setReceiptFiles).not.toHaveBeenCalled();
expect(setIsMultiScanEnabled).toHaveBeenCalledWith(true);
});
});

describe('dismissMultiScanEducationalPopup', () => {
Expand Down
Loading
Loading