From f864ca0e3fc65f3479e8f76ae3a97e62a6e560af Mon Sep 17 00:00:00 2001 From: Carlos Alvarez Date: Thu, 22 Jan 2026 15:22:32 -0800 Subject: [PATCH] Revert "Update create transaction Manual flow to ask for merchant after asking for amount" --- src/libs/IOUUtils.ts | 32 ++--------------- .../iou/request/step/IOURequestStepAmount.tsx | 16 ++------- .../request/step/IOURequestStepMerchant.tsx | 16 +-------- .../step/IOURequestStepParticipants.tsx | 35 ++++--------------- 4 files changed, 12 insertions(+), 87 deletions(-) diff --git a/src/libs/IOUUtils.ts b/src/libs/IOUUtils.ts index 7d373e0b33338..c40a3045397fd 100644 --- a/src/libs/IOUUtils.ts +++ b/src/libs/IOUUtils.ts @@ -4,15 +4,14 @@ import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type {OnyxInputOrEntry, PersonalDetails, Policy, Report} from '@src/types/onyx'; import type {Attendee} from '@src/types/onyx/IOU'; -import type Transaction from '@src/types/onyx/Transaction'; import SafeString from '@src/utils/SafeString'; import type {IOURequestType} from './actions/IOU'; import {getCurrencyUnit} from './CurrencyUtils'; import Navigation from './Navigation/Navigation'; import Performance from './Performance'; import {isPaidGroupPolicy} from './PolicyUtils'; -import {getReportTransactions, isExpenseRequest, isPolicyExpenseChat} from './ReportUtils'; -import {getCurrency, getTagArrayFromName, isMerchantMissing, isScanRequest} from './TransactionUtils'; +import {getReportTransactions} from './ReportUtils'; +import {getCurrency, getTagArrayFromName} from './TransactionUtils'; function navigateToStartMoneyRequestStep(requestType: IOURequestType, iouType: IOUType, transactionID: string, reportID: string, iouAction?: IOUAction): void { if (iouAction === CONST.IOU.ACTION.CATEGORIZE || iouAction === CONST.IOU.ACTION.SUBMIT || iouAction === CONST.IOU.ACTION.SHARE) { @@ -324,32 +323,6 @@ function formatCurrentUserToAttendee(currentUser?: PersonalDetails, reportID?: s return [initialAttendee]; } -/** - * Checks if merchant is required and missing for a transaction. - * Merchant is required for policy expense chats, expense requests, or when any participant is a policy expense chat. - * For scan requests, merchant is not required unless it's a split bill being edited. - * - * @param transaction - The transaction to check - * @param report - The report associated with the transaction - * @param isEditingSplitBill - Whether this is editing a split bill - * @returns true if merchant is required and missing, false otherwise - */ -function shouldRequireMerchant(transaction: OnyxInputOrEntry | undefined, report: OnyxInputOrEntry | undefined, isEditingSplitBill = false): boolean { - if (!transaction) { - return false; - } - - // Check if merchant is required based on report type and participants - const isMerchantRequired = !!(isPolicyExpenseChat(report) || isExpenseRequest(report) || transaction?.participants?.some((participant) => !!participant.isPolicyExpenseChat)); - - // For scan requests, merchant is not required unless it's a split bill being edited - if (isScanRequest(transaction) && !isEditingSplitBill) { - return false; - } - - return isMerchantRequired && isMerchantMissing(transaction); -} - function navigateToConfirmationPage( iouType: IOUType, transactionID: string, @@ -398,6 +371,5 @@ export { formatCurrentUserToAttendee, navigateToParticipantPage, shouldShowReceiptEmptyState, - shouldRequireMerchant, navigateToConfirmationPage, }; diff --git a/src/pages/iou/request/step/IOURequestStepAmount.tsx b/src/pages/iou/request/step/IOURequestStepAmount.tsx index 96c373133a6b5..2049e518ef147 100644 --- a/src/pages/iou/request/step/IOURequestStepAmount.tsx +++ b/src/pages/iou/request/step/IOURequestStepAmount.tsx @@ -18,7 +18,7 @@ import useShowNotFoundPageInIOUStep from '@hooks/useShowNotFoundPageInIOUStep'; import {setTransactionReport} from '@libs/actions/Transaction'; import {convertToBackendAmount} from '@libs/CurrencyUtils'; import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; -import {isMovingTransactionFromTrackExpense, navigateToConfirmationPage, navigateToParticipantPage, shouldRequireMerchant} from '@libs/IOUUtils'; +import {isMovingTransactionFromTrackExpense, navigateToConfirmationPage, navigateToParticipantPage} from '@libs/IOUUtils'; import Navigation from '@libs/Navigation/Navigation'; import {getParticipantsOption, getReportOption} from '@libs/OptionsListUtils'; import {isPaidGroupPolicy} from '@libs/PolicyUtils'; @@ -283,14 +283,8 @@ function IOURequestStepAmount({ setSplitShares(transaction, amountInSmallestCurrencyUnits, selectedCurrency || CONST.CURRENCY.USD, participantAccountIDs); } setMoneyRequestParticipantsFromReport(transactionID, report, currentUserPersonalDetails.accountID).then(() => { - // If merchant is required and missing, navigate to merchant step first - if (shouldRequireMerchant(transaction, report, isEditingSplitBill)) { - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_MERCHANT.getRoute(action, CONST.IOU.TYPE.SUBMIT, transactionID, reportID, undefined, reportActionID)); - return; - } navigateToConfirmationPage(iouType, transactionID, reportID, backToReport); }); - return; } @@ -310,9 +304,7 @@ function IOURequestStepAmount({ const resetToDefaultWorkspace = () => { setTransactionReport(transactionID, {reportID: transactionReportID}, true); setMoneyRequestParticipantsFromReport(transactionID, activePolicyExpenseChat, currentUserPersonalDetails.accountID).then(() => { - Navigation.navigate( - ROUTES.MONEY_REQUEST_STEP_MERCHANT.getRoute(action, CONST.IOU.TYPE.SUBMIT, transactionID, activePolicyExpenseChat?.reportID, undefined, reportActionID), - ); + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, CONST.IOU.TYPE.SUBMIT, transactionID, activePolicyExpenseChat?.reportID)); }); }; @@ -334,10 +326,6 @@ function IOURequestStepAmount({ const chatReportID = selectedReport?.chatReportID ?? iouReportID; Navigation.setNavigationActionToMicrotaskQueue(() => { - if (shouldRequireMerchant(transaction, selectedReport, isEditingSplitBill)) { - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_MERCHANT.getRoute(CONST.IOU.ACTION.CREATE, navigationIOUType, transactionID, chatReportID, undefined, reportActionID)); - return; - } Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, navigationIOUType, transactionID, chatReportID)); }); } else { diff --git a/src/pages/iou/request/step/IOURequestStepMerchant.tsx b/src/pages/iou/request/step/IOURequestStepMerchant.tsx index 0caf69269ceb6..949fa2633c258 100644 --- a/src/pages/iou/request/step/IOURequestStepMerchant.tsx +++ b/src/pages/iou/request/step/IOURequestStepMerchant.tsx @@ -1,4 +1,3 @@ -import {useFocusEffect} from '@react-navigation/native'; import React, {useCallback, useEffect, useRef, useState} from 'react'; import {InteractionManager, View} from 'react-native'; import FormProvider from '@components/Form/FormProvider'; @@ -21,7 +20,6 @@ import {isValidInputLength} from '@libs/ValidationUtils'; import {setDraftSplitTransaction, setMoneyRequestMerchant, updateMoneyRequestMerchant} from '@userActions/IOU'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import INPUT_IDS from '@src/types/form/MoneyRequestMerchantForm'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; @@ -76,24 +74,13 @@ function IOURequestStepMerchant({ Navigation.goBack(backTo); }, [backTo]); - useFocusEffect( - useCallback(() => { - setIsSaved(false); - setCurrentMerchant(initialMerchant); - }, [initialMerchant]), - ); - useEffect(() => { if (!isSaved || !shouldNavigateAfterSaveRef.current) { return; } shouldNavigateAfterSaveRef.current = false; - if (!isEditing && !backTo) { - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(action, iouType, transactionID, reportID, undefined, undefined, Navigation.getActiveRoute())); - return; - } navigateBack(); - }, [isSaved, navigateBack, action, iouType, transactionID, reportID, backTo, isEditing]); + }, [isSaved, navigateBack]); const validate = useCallback( (value: FormOnyxValues) => { @@ -180,7 +167,6 @@ function IOURequestStepMerchant({ inputID={INPUT_IDS.MONEY_REQUEST_MERCHANT} name={INPUT_IDS.MONEY_REQUEST_MERCHANT} defaultValue={initialMerchant} - value={currentMerchant} onValueChange={updateMerchantRef} label={translate('common.merchant')} accessibilityLabel={translate('common.merchant')} diff --git a/src/pages/iou/request/step/IOURequestStepParticipants.tsx b/src/pages/iou/request/step/IOURequestStepParticipants.tsx index 0523fd0df7138..a83880c8a8767 100644 --- a/src/pages/iou/request/step/IOURequestStepParticipants.tsx +++ b/src/pages/iou/request/step/IOURequestStepParticipants.tsx @@ -22,7 +22,7 @@ import {isPaidGroupPolicy} from '@libs/PolicyUtils'; import {findSelfDMReportID, generateReportID, isInvoiceRoomWithID} from '@libs/ReportUtils'; import {shouldRestrictUserBillableActions} from '@libs/SubscriptionUtils'; import {endSpan} from '@libs/telemetry/activeSpans'; -import {getRequestType, hasRoute, isCorporateCardTransaction, isDistanceRequest, isMerchantMissing, isPerDiemRequest} from '@libs/TransactionUtils'; +import {getRequestType, hasRoute, isCorporateCardTransaction, isDistanceRequest, isPerDiemRequest} from '@libs/TransactionUtils'; import MoneyRequestParticipantsSelector from '@pages/iou/request/MoneyRequestParticipantsSelector'; import { navigateToStartStepIfScanFileCannotBeRead, @@ -38,7 +38,6 @@ import {createDraftWorkspace} from '@userActions/Policy/Policy'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {Route} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {Policy} from '@src/types/onyx'; import type {Participant} from '@src/types/onyx/IOU'; @@ -98,8 +97,6 @@ function IOURequestStepParticipants({ // We need to set selectedReportID if user has navigated back from confirmation page and navigates to confirmation page with already selected participant const selectedReportID = useRef(participants?.length === 1 ? (participants.at(0)?.reportID ?? reportID) : reportID); - const selectedParticipants = useRef(participants); - // We can assume that shouldAutoReport is true as the initial value is not used. shouldAutoReport is only used after the selectedReportID changes in addParticipant where we'd update shouldAutoReport too const shouldAutoReport = useRef(true); const numberOfParticipants = useRef(participants?.length ?? 0); @@ -236,7 +233,6 @@ function IOURequestStepParticipants({ (val: Participant[]) => { HttpUtils.cancelPendingRequests(READ_COMMANDS.SEARCH_FOR_REPORTS); - selectedParticipants.current = val; const firstParticipant = val.at(0); if (firstParticipant?.isSelfDM && !isSplitRequest) { @@ -371,9 +367,6 @@ function IOURequestStepParticipants({ return; } - const firstParticipant = selectedParticipants.current?.at(0); - const isMerchantRequired = !!firstParticipant?.isPolicyExpenseChat && isMerchantMissing(initialTransaction) && iouRequestType === CONST.IOU.REQUEST_TYPE.MANUAL; - const iouConfirmationPageRoute = ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute( action, iouType === CONST.IOU.TYPE.CREATE || iouType === CONST.IOU.TYPE.TRACK ? CONST.IOU.TYPE.SUBMIT : iouType, @@ -384,18 +377,9 @@ function IOURequestStepParticipants({ action === CONST.IOU.ACTION.SHARE ? Navigation.getActiveRoute() : undefined, ); - let route: Route = iouConfirmationPageRoute; - - if (isCategorizing) { - ROUTES.MONEY_REQUEST_STEP_CATEGORY.getRoute(action, iouType, initialTransactionID, selectedReportID.current || reportID, iouConfirmationPageRoute); - } else { - route = ROUTES.MONEY_REQUEST_STEP_MERCHANT.getRoute( - action, - iouType === CONST.IOU.TYPE.CREATE || iouType === CONST.IOU.TYPE.TRACK ? CONST.IOU.TYPE.SUBMIT : iouType, - initialTransactionID, - newReportID, - ); - } + const route = isCategorizing + ? ROUTES.MONEY_REQUEST_STEP_CATEGORY.getRoute(action, iouType, initialTransactionID, selectedReportID.current || reportID, iouConfirmationPageRoute) + : iouConfirmationPageRoute; Performance.markStart(CONST.TIMING.OPEN_CREATE_EXPENSE_APPROVE); waitForKeyboardDismiss(() => { @@ -403,15 +387,11 @@ function IOURequestStepParticipants({ // We wrap navigation in setNavigationActionToMicrotaskQueue so that data loading in Onyx and navigation do not occur simultaneously, which resets the amount to 0. // More information can be found here: https://github.com/Expensify/App/issues/73728 Navigation.setNavigationActionToMicrotaskQueue(() => { - if (backTo && !isMerchantRequired) { + if (backTo) { // We don't want to compare params because we just changed the participants. Navigation.goBack(route, {compareParams: false}); } else { - // If the merchant step is required and the backTo parameter is set, we need to go back the the confirmation screen first and then navigate to the merchant page with forceReplace to remove this screen from the stack - if (isMerchantRequired && backTo) { - Navigation.goBack(); - } - Navigation.navigate(route, {forceReplace: isMerchantRequired && !!backTo}); + Navigation.navigate(route); } }); }); @@ -421,15 +401,14 @@ function IOURequestStepParticipants({ participants, iouType, initialTransaction, - iouRequestType, initialTransactionID, + reportID, waitForKeyboardDismiss, transactions, isMovingTransactionFromTrackExpense, allPolicies, policyForMovingExpenses, introSelected, - reportID, backTo, ], );