diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 8e4c84f24965..df5c510ca954 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -352,8 +352,8 @@ const ROUTES = { }, MONEY_REQUEST_STEP_CURRENCY: { route: ':action/:iouType/currency/:transactionID/:reportID/:pageIndex?', - getRoute: (action: ValueOf, iouType: ValueOf, transactionID: string, reportID: string, pageIndex = '', backTo = '') => - getUrlWithBackToParam(`${action}/${iouType}/currency/${transactionID}/${reportID}/${pageIndex}`, backTo), + getRoute: (action: ValueOf, iouType: ValueOf, transactionID: string, reportID: string, pageIndex = '', currency = '', backTo = '') => + getUrlWithBackToParam(`${action}/${iouType}/currency/${transactionID}/${reportID}/${pageIndex}?currency=${currency}`, backTo), }, MONEY_REQUEST_STEP_DATE: { route: ':action/:iouType/date/:transactionID/:reportID', diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index c70671e48fde..06f0df4700ff 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -396,6 +396,7 @@ type MoneyRequestNavigatorParamList = { transactionID: string; reportID: string; backTo: Routes; + currency?: string; }; [SCREENS.MONEY_REQUEST.STEP_TAG]: { action: ValueOf; @@ -457,6 +458,7 @@ type MoneyRequestNavigatorParamList = { // for IOURequestStepDistance and IOURequestStepAmount components backTo: never; action: never; + currency: never; }; [SCREENS.MONEY_REQUEST.START]: { iouType: ValueOf; @@ -470,6 +472,7 @@ type MoneyRequestNavigatorParamList = { transactionID: string; backTo: Routes; action: ValueOf; + currency?: string; }; [SCREENS.MONEY_REQUEST.STEP_PARTICIPANTS]: { iouType: ValueOf; @@ -499,6 +502,7 @@ type MoneyRequestNavigatorParamList = { reportID: string; pageIndex?: string; backTo?: Routes; + currency?: string; }; }; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index cd0264ddb6ea..85f4b74f3436 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -371,11 +371,7 @@ function startMoneyRequest(iouType: ValueOf, reportID: st } // eslint-disable-next-line @typescript-eslint/naming-convention -function setMoneyRequestAmount_temporaryForRefactor(transactionID: string, amount: number, currency: string, removeOriginalCurrency = false) { - if (removeOriginalCurrency) { - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {amount, currency, originalCurrency: null}); - return; - } +function setMoneyRequestAmount_temporaryForRefactor(transactionID: string, amount: number, currency: string) { Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {amount, currency}); } @@ -385,20 +381,11 @@ function setMoneyRequestCreated(transactionID: string, created: string, isDraft: } // eslint-disable-next-line @typescript-eslint/naming-convention -function setMoneyRequestCurrency_temporaryForRefactor(transactionID: string, currency: string, removeOriginalCurrency = false, isEditing = false) { +function setMoneyRequestCurrency_temporaryForRefactor(transactionID: string, currency: string, isEditing = false) { const fieldToUpdate = isEditing ? 'modifiedCurrency' : 'currency'; - if (removeOriginalCurrency) { - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {[fieldToUpdate]: currency, originalCurrency: null}); - return; - } Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {[fieldToUpdate]: currency}); } -// eslint-disable-next-line @typescript-eslint/naming-convention -function setMoneyRequestOriginalCurrency_temporaryForRefactor(transactionID: string, originalCurrency: string) { - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {originalCurrency}); -} - function setMoneyRequestDescription(transactionID: string, comment: string, isDraft: boolean) { Onyx.merge(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, {comment: {comment: comment.trim()}}); } @@ -5567,7 +5554,6 @@ export { setMoneyRequestCreated, setMoneyRequestCurrency_temporaryForRefactor, setMoneyRequestDescription, - setMoneyRequestOriginalCurrency_temporaryForRefactor, setMoneyRequestParticipants_temporaryForRefactor, setMoneyRequestPendingFields, setMoneyRequestReceipt, diff --git a/src/pages/iou/request/step/IOURequestStepAmount.tsx b/src/pages/iou/request/step/IOURequestStepAmount.tsx index 1936a132c665..690a7e3d9d0d 100644 --- a/src/pages/iou/request/step/IOURequestStepAmount.tsx +++ b/src/pages/iou/request/step/IOURequestStepAmount.tsx @@ -44,7 +44,7 @@ type IOURequestStepAmountProps = IOURequestStepAmountOnyxProps & function IOURequestStepAmount({ report, route: { - params: {iouType, reportID, transactionID, backTo, action}, + params: {iouType, reportID, transactionID, backTo, action, currency: selectedCurrency = ''}, }, transaction, splitDraftTransaction, @@ -54,13 +54,13 @@ function IOURequestStepAmount({ const textInput = useRef(null); const focusTimeoutRef = useRef(null); const isSaveButtonPressed = useRef(false); - const originalCurrency = useRef(null); const iouRequestType = getRequestType(transaction); const isEditing = action === CONST.IOU.ACTION.EDIT; const isSplitBill = iouType === CONST.IOU.TYPE.SPLIT; const isEditingSplitBill = isEditing && isSplitBill; const {amount: transactionAmount} = ReportUtils.getTransactionDetails(isEditingSplitBill && !isEmptyObject(splitDraftTransaction) ? splitDraftTransaction : transaction) ?? {amount: 0}; - const {currency} = ReportUtils.getTransactionDetails(isEditing ? draftTransaction : transaction) ?? {currency: CONST.CURRENCY.USD}; + const {currency: originalCurrency} = ReportUtils.getTransactionDetails(isEditing ? draftTransaction : transaction) ?? {currency: CONST.CURRENCY.USD}; + const currency = CurrencyUtils.isValidCurrencyCode(selectedCurrency) ? selectedCurrency : originalCurrency; useFocusEffect( useCallback(() => { @@ -75,30 +75,19 @@ function IOURequestStepAmount({ ); useEffect(() => { - if (isEditing) { - // A temporary solution to not prevent users from editing the currency - // We create a backup transaction and use it to save the currency and remove this transaction backup if we don't save the amount - // It should be removed after this issue https://github.com/Expensify/App/issues/34607 is fixed - TransactionEdit.createBackupTransaction(isEditingSplitBill && !isEmptyObject(splitDraftTransaction) ? splitDraftTransaction : transaction); - - return () => { - if (isSaveButtonPressed.current) { - return; - } - TransactionEdit.removeBackupTransaction(transaction?.transactionID ?? ''); - }; - } - if (transaction?.originalCurrency) { - originalCurrency.current = transaction.originalCurrency; - } else { - originalCurrency.current = currency; - IOU.setMoneyRequestOriginalCurrency_temporaryForRefactor(transactionID, currency); + if (!isEditing) { + return; } + // A temporary solution to not prevent users from editing the currency + // We create a backup transaction and use it to save the currency and remove this transaction backup if we don't save the amount + // It should be removed after this issue https://github.com/Expensify/App/issues/34607 is fixed + TransactionEdit.createBackupTransaction(isEditingSplitBill && !isEmptyObject(splitDraftTransaction) ? splitDraftTransaction : transaction); + return () => { if (isSaveButtonPressed.current) { return; } - IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, originalCurrency.current ?? '', true); + TransactionEdit.removeBackupTransaction(transaction?.transactionID ?? ''); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -108,14 +97,17 @@ function IOURequestStepAmount({ }; const navigateToCurrencySelectionPage = () => { - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_CURRENCY.getRoute(action, iouType, transactionID, reportID, backTo ? 'confirm' : '', Navigation.getActiveRouteWithoutParams())); + Navigation.navigate( + ROUTES.MONEY_REQUEST_STEP_CURRENCY.getRoute(action, iouType, transactionID, reportID, backTo ? 'confirm' : '', currency, Navigation.getActiveRouteWithoutParams()), + ); }; const navigateToNextPage = ({amount}: AmountParams) => { isSaveButtonPressed.current = true; const amountInSmallestCurrencyUnits = CurrencyUtils.convertToBackendAmount(Number.parseFloat(amount)); - IOU.setMoneyRequestAmount_temporaryForRefactor(transactionID, amountInSmallestCurrencyUnits, currency || CONST.CURRENCY.USD, true); + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + IOU.setMoneyRequestAmount_temporaryForRefactor(transactionID, amountInSmallestCurrencyUnits, currency || CONST.CURRENCY.USD); if (backTo) { Navigation.goBack(backTo); diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx index 83f831708799..9bf194e2e74e 100644 --- a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx +++ b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx @@ -2,7 +2,6 @@ import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; -import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Expensicons from '@components/Icon/Expensicons'; import MoneyRequestConfirmationList from '@components/MoneyTemporaryForRefactorRequestConfirmationList'; @@ -103,15 +102,6 @@ function IOURequestStepConfirmation({ const isPolicyExpenseChat = useMemo(() => ReportUtils.isPolicyExpenseChat(ReportUtils.getRootParentReport(report)), [report]); const formHasBeenSubmitted = useRef(false); - useEffect(() => { - if (!transaction?.originalCurrency) { - return; - } - // If user somehow lands on this page without the currency reset, then reset it here. - IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, transaction.originalCurrency, true); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - useEffect(() => { const policyExpenseChat = participants?.find((participant) => participant.isPolicyExpenseChat); if (policyExpenseChat?.policyID) { @@ -461,10 +451,6 @@ function IOURequestStepConfirmation({ IOU.setMoneyRequestBillable_temporaryForRefactor(transactionID, billable); }; - // This loading indicator is shown because the transaction originalCurrency is being updated later than the component mounts. - // To prevent the component from rendering with the wrong currency, we show a loading indicator until the correct currency is set. - const isLoading = !!transaction?.originalCurrency; - return ( - {isLoading && } - - - + )} diff --git a/src/pages/iou/request/step/IOURequestStepCurrency.tsx b/src/pages/iou/request/step/IOURequestStepCurrency.tsx index e55f510aa589..a8a95383e48b 100644 --- a/src/pages/iou/request/step/IOURequestStepCurrency.tsx +++ b/src/pages/iou/request/step/IOURequestStepCurrency.tsx @@ -39,15 +39,16 @@ type CurrencyListItem = ListItem & { function IOURequestStepCurrency({ currencyList, route: { - params: {backTo, iouType, pageIndex, reportID, transactionID, action}, + params: {backTo, iouType, pageIndex, reportID, transactionID, action, currency: selectedCurrency = ''}, }, draftTransaction, }: IOURequestStepCurrencyProps) { const {translate} = useLocalize(); const [searchValue, setSearchValue] = useState(''); - const {currency = ''} = ReportUtils.getTransactionDetails(draftTransaction) ?? {}; + const {currency: originalCurrency = ''} = ReportUtils.getTransactionDetails(draftTransaction) ?? {}; + const currency = CurrencyUtils.isValidCurrencyCode(selectedCurrency) ? selectedCurrency : originalCurrency; - const navigateBack = () => { + const navigateBack = (selectedCurrencyValue = '') => { // If the currency selection was done from the confirmation step (eg. + > request money > manual > confirm > amount > currency) // then the user needs taken back to the confirmation page instead of the initial amount page. This is because the route params // are only able to handle one backTo param at a time and the user needs to go back to the amount page before going back @@ -57,7 +58,11 @@ function IOURequestStepCurrency({ backTo as string, `/${ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID)}`, ); - Navigation.goBack(routeToAmountPageWithConfirmationAsBackTo as Route); + if (selectedCurrencyValue) { + Navigation.navigate(`${routeToAmountPageWithConfirmationAsBackTo}¤cy=${selectedCurrencyValue}` as Route); + } else { + Navigation.goBack(routeToAmountPageWithConfirmationAsBackTo as Route); + } return; } Navigation.goBack(backTo); @@ -65,8 +70,10 @@ function IOURequestStepCurrency({ const confirmCurrencySelection = (option: CurrencyListItem) => { Keyboard.dismiss(); - IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, option.currencyCode, false, action === CONST.IOU.ACTION.EDIT); - navigateBack(); + if (pageIndex !== 'confirm') { + IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, option.currencyCode, action === CONST.IOU.ACTION.EDIT); + } + navigateBack(option.currencyCode); }; const {sections, headerMessage, initiallyFocusedOptionKey} = useMemo(() => { @@ -101,7 +108,7 @@ function IOURequestStepCurrency({ return ( navigateBack()} shouldShowWrapper testID={IOURequestStepCurrency.displayName} includeSafeAreaPaddingBottom={false} diff --git a/src/pages/iou/request/step/IOURequestStepTaxAmountPage.tsx b/src/pages/iou/request/step/IOURequestStepTaxAmountPage.tsx index c2c9c5e7fe67..40e3e5a06991 100644 --- a/src/pages/iou/request/step/IOURequestStepTaxAmountPage.tsx +++ b/src/pages/iou/request/step/IOURequestStepTaxAmountPage.tsx @@ -1,5 +1,5 @@ import {useFocusEffect} from '@react-navigation/native'; -import React, {useCallback, useEffect, useRef} from 'react'; +import React, {useCallback, useRef} from 'react'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import type {BaseTextInputRef} from '@components/TextInput/BaseTextInput/types'; @@ -49,7 +49,7 @@ function getTaxAmount(transaction: OnyxEntry, taxRates: TaxRatesWit function IOURequestStepTaxAmountPage({ route: { - params: {action, iouType, reportID, transactionID, backTo}, + params: {action, iouType, reportID, transactionID, backTo, currency: selectedCurrency = ''}, }, transaction, report, @@ -63,28 +63,10 @@ function IOURequestStepTaxAmountPage({ const focusTimeoutRef = useRef(); - const isSaveButtonPressed = useRef(false); - const originalCurrency = useRef(); - const transactionDetails = ReportUtils.getTransactionDetails(transaction); + const currency = CurrencyUtils.isValidCurrencyCode(selectedCurrency) ? selectedCurrency : transactionDetails?.currency; const taxRates = policy?.taxRates; - useEffect(() => { - if (transaction?.originalCurrency) { - originalCurrency.current = transaction.originalCurrency; - } else if (transaction?.currency) { - originalCurrency.current = transaction.currency; - IOU.setMoneyRequestOriginalCurrency_temporaryForRefactor(transactionID, transaction?.currency); - } - return () => { - if (isSaveButtonPressed.current || !originalCurrency.current) { - return; - } - IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, originalCurrency.current, true); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - useFocusEffect( useCallback(() => { focusTimeoutRef.current = setTimeout(() => textInput.current?.focus(), CONST.ANIMATED_TRANSITION); @@ -106,12 +88,19 @@ function IOURequestStepTaxAmountPage({ // Only USD is allowed for distance requests. // Remove query from the route and encode it. Navigation.navigate( - ROUTES.MONEY_REQUEST_STEP_CURRENCY.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID, backTo ? 'confirm' : '', Navigation.getActiveRouteWithoutParams()), + ROUTES.MONEY_REQUEST_STEP_CURRENCY.getRoute( + CONST.IOU.ACTION.CREATE, + iouType, + transactionID, + reportID, + backTo ? 'confirm' : '', + currency, + Navigation.getActiveRouteWithoutParams(), + ), ); }; const updateTaxAmount = (currentAmount: CurrentMoney) => { - isSaveButtonPressed.current = true; const amountInSmallestCurrencyUnits = CurrencyUtils.convertToBackendAmount(Number.parseFloat(currentAmount.amount)); if (isEditing) { @@ -127,7 +116,7 @@ function IOURequestStepTaxAmountPage({ IOU.setMoneyRequestTaxAmount(transactionID, amountInSmallestCurrencyUnits, true); // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, transaction?.currency || CONST.CURRENCY.USD, true); + IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, currency || CONST.CURRENCY.USD); if (backTo) { Navigation.goBack(backTo); @@ -159,7 +148,7 @@ function IOURequestStepTaxAmountPage({ > (textInput.current = e)}