diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index a0ed5b9c593f..7da6e13d1f86 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -178,8 +178,13 @@ function clearMoneyRequest(transactionID) { * @param {String} transactionID * @param {Number} amount * @param {String} currency + * @param {Boolean} [removeOriginalCurrency] */ -function setMoneyRequestAmount_temporaryForRefactor(transactionID, amount, currency) { +function setMoneyRequestAmount_temporaryForRefactor(transactionID, amount, currency, removeOriginalCurrency = false) { + if (removeOriginalCurrency) { + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {amount, currency, originalCurrency: null}); + return; + } Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {amount, currency}); } @@ -194,11 +199,24 @@ function setMoneyRequestCreated_temporaryForRefactor(transactionID, created) { /** * @param {String} transactionID * @param {String} currency + * @param {Boolean} [removeOriginalCurrency] */ -function setMoneyRequestCurrency_temporaryForRefactor(transactionID, currency) { +function setMoneyRequestCurrency_temporaryForRefactor(transactionID, currency, removeOriginalCurrency = false) { + if (removeOriginalCurrency) { + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {currency, originalCurrency: null}); + return; + } Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {currency}); } +/** + * @param {String} transactionID + * @param {String} originalCurrency + */ +function setMoneyRequestOriginalCurrency_temporaryForRefactor(transactionID, originalCurrency) { + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`, {originalCurrency}); +} + /** * @param {String} transactionID * @param {String} comment @@ -3791,6 +3809,7 @@ export { setMoneyRequestCategory_temporaryForRefactor, setMoneyRequestCreated_temporaryForRefactor, setMoneyRequestCurrency_temporaryForRefactor, + setMoneyRequestOriginalCurrency_temporaryForRefactor, setMoneyRequestDescription_temporaryForRefactor, setMoneyRequestMerchant_temporaryForRefactor, setMoneyRequestParticipants_temporaryForRefactor, diff --git a/src/pages/iou/request/step/IOURequestStepAmount.js b/src/pages/iou/request/step/IOURequestStepAmount.js index 84e0ac8533c5..f91e7cea533b 100644 --- a/src/pages/iou/request/step/IOURequestStepAmount.js +++ b/src/pages/iou/request/step/IOURequestStepAmount.js @@ -1,6 +1,6 @@ import {useFocusEffect} from '@react-navigation/native'; import PropTypes from 'prop-types'; -import React, {useCallback, useRef} from 'react'; +import React, {useCallback, useEffect, useRef} from 'react'; import {withOnyx} from 'react-native-onyx'; import taxPropTypes from '@components/taxPropTypes'; import transactionPropTypes from '@components/transactionPropTypes'; @@ -59,18 +59,19 @@ const getTaxAmount = (transaction, defaultTaxValue, amount) => { function IOURequestStepAmount({ report, route: { - params: {iouType, reportID, transactionID, backTo, currency: selectedCurrency}, + params: {iouType, reportID, transactionID, backTo}, }, transaction, - transaction: {currency: originalCurrency}, + transaction: {currency}, policyTaxRates, policy, }) { const {translate} = useLocalize(); const textInput = useRef(null); const focusTimeoutRef = useRef(null); + const isSaveButtonPressed = useRef(false); + const originalCurrency = useRef(null); const iouRequestType = getRequestType(transaction); - const currency = selectedCurrency || originalCurrency; const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(ReportUtils.getRootParentReport(report)); const isTaxTrackingEnabled = isPolicyExpenseChat && policy.isTaxTrackingEnabled; @@ -87,6 +88,22 @@ function IOURequestStepAmount({ }, []), ); + useEffect(() => { + if (transaction.originalCurrency) { + originalCurrency.current = transaction.originalCurrency; + } else { + originalCurrency.current = currency; + IOU.setMoneyRequestOriginalCurrency_temporaryForRefactor(transactionID, currency); + } + return () => { + if (isSaveButtonPressed.current) { + return; + } + IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, originalCurrency.current, true); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const navigateBack = () => { Navigation.goBack(backTo || ROUTES.HOME); }; @@ -99,6 +116,7 @@ function IOURequestStepAmount({ * @param {Number} amount */ const navigateToNextPage = ({amount}) => { + isSaveButtonPressed.current = true; const amountInSmallestCurrencyUnits = CurrencyUtils.convertToBackendAmount(Number.parseFloat(amount)); if ((iouRequestType === CONST.IOU.REQUEST_TYPE.MANUAL || backTo) && isTaxTrackingEnabled) { @@ -107,7 +125,7 @@ function IOURequestStepAmount({ IOU.setMoneyRequestTaxAmount(transaction.transactionID, taxAmountInSmallestCurrencyUnits); } - IOU.setMoneyRequestAmount_temporaryForRefactor(transactionID, amountInSmallestCurrencyUnits, currency || CONST.CURRENCY.USD); + IOU.setMoneyRequestAmount_temporaryForRefactor(transactionID, amountInSmallestCurrencyUnits, currency || CONST.CURRENCY.USD, true); if (backTo) { Navigation.goBack(backTo); diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.js b/src/pages/iou/request/step/IOURequestStepConfirmation.js index 0f1c2b27ad2e..2efba59e0acc 100644 --- a/src/pages/iou/request/step/IOURequestStepConfirmation.js +++ b/src/pages/iou/request/step/IOURequestStepConfirmation.js @@ -5,6 +5,7 @@ import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import categoryPropTypes from '@components/categoryPropTypes'; +import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Expensicons from '@components/Icon/Expensicons'; import MoneyRequestConfirmationList from '@components/MoneyTemporaryForRefactorRequestConfirmationList'; @@ -103,6 +104,15 @@ function IOURequestStepConfirmation({ ); const isPolicyExpenseChat = useMemo(() => ReportUtils.isPolicyExpenseChat(ReportUtils.getRootParentReport(report)), [report]); + useEffect(() => { + if (!transaction || !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 = _.find(participants, (participant) => participant.isPolicyExpenseChat); if (policyExpenseChat) { @@ -321,6 +331,10 @@ 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 && transaction.originalCurrency); + return ( - + {isLoading ? ( + + ) : ( + + )} )} diff --git a/src/pages/iou/request/step/IOURequestStepCurrency.js b/src/pages/iou/request/step/IOURequestStepCurrency.js index b4281de4d16e..06af0ecf3ca4 100644 --- a/src/pages/iou/request/step/IOURequestStepCurrency.js +++ b/src/pages/iou/request/step/IOURequestStepCurrency.js @@ -59,18 +59,14 @@ function IOURequestStepCurrency({ const [searchValue, setSearchValue] = useState(''); const optionsSelectorRef = useRef(); - const navigateBack = (selectedCurrency = undefined) => { + const navigateBack = () => { // 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 // to the confirmation page if (pageIndex === 'confirm') { const routeToAmountPageWithConfirmationAsBackTo = getUrlWithBackToParam(backTo, `/${ROUTES.MONEY_REQUEST_STEP_CONFIRMATION.getRoute(iouType, transactionID, reportID)}`); - if (selectedCurrency) { - Navigation.navigate(`${routeToAmountPageWithConfirmationAsBackTo}¤cy=${selectedCurrency}`); - } else { - Navigation.goBack(routeToAmountPageWithConfirmationAsBackTo); - } + Navigation.goBack(routeToAmountPageWithConfirmationAsBackTo); return; } Navigation.goBack(backTo || ROUTES.HOME); @@ -82,10 +78,8 @@ function IOURequestStepCurrency({ */ const confirmCurrencySelection = (option) => { Keyboard.dismiss(); - if (pageIndex !== 'confirm') { - IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, option.currencyCode); - } - navigateBack(option.currencyCode); + IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, option.currencyCode); + navigateBack(); }; const {sections, headerMessage, initiallyFocusedOptionKey} = useMemo(() => { diff --git a/src/pages/iou/request/step/IOURequestStepTaxAmountPage.js b/src/pages/iou/request/step/IOURequestStepTaxAmountPage.js index a9f3195bfdfd..d1352f5b1f5d 100644 --- a/src/pages/iou/request/step/IOURequestStepTaxAmountPage.js +++ b/src/pages/iou/request/step/IOURequestStepTaxAmountPage.js @@ -1,5 +1,5 @@ import {useFocusEffect} from '@react-navigation/native'; -import React, {useCallback, useRef} from 'react'; +import React, {useCallback, useEffect, useRef} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; @@ -53,10 +53,10 @@ const getTaxAmount = (transaction, defaultTaxValue) => { function IOURequestStepTaxAmountPage({ route: { - params: {iouType, reportID, transactionID, backTo, currency: selectedCurrency}, + params: {iouType, reportID, transactionID, backTo}, }, transaction, - transaction: {currency: originalCurrency}, + transaction: {currency}, report, policyTaxRates, }) { @@ -65,10 +65,27 @@ function IOURequestStepTaxAmountPage({ const textInput = useRef(null); const isEditing = Navigation.getActiveRoute().includes('taxAmount'); - const currency = selectedCurrency || originalCurrency; - const focusTimeoutRef = useRef(null); + const isSaveButtonPressed = useRef(false); + const originalCurrency = useRef(null); + + useEffect(() => { + if (transaction.originalCurrency) { + originalCurrency.current = transaction.originalCurrency; + } else { + originalCurrency.current = currency; + IOU.setMoneyRequestOriginalCurrency_temporaryForRefactor(transactionID, currency); + } + return () => { + if (isSaveButtonPressed.current) { + return; + } + IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, originalCurrency.current, true); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + useFocusEffect( useCallback(() => { focusTimeoutRef.current = setTimeout(() => textInput.current && textInput.current.focus(), CONST.ANIMATED_TRANSITION); @@ -93,10 +110,11 @@ function IOURequestStepTaxAmountPage({ }; const updateTaxAmount = (currentAmount) => { + isSaveButtonPressed.current = true; const amountInSmallestCurrencyUnits = CurrencyUtils.convertToBackendAmount(Number.parseFloat(currentAmount.amount)); IOU.setMoneyRequestTaxAmount(transactionID, amountInSmallestCurrencyUnits); - IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, currency || CONST.CURRENCY.USD); + IOU.setMoneyRequestCurrency_temporaryForRefactor(transactionID, currency || CONST.CURRENCY.USD, true); if (backTo) { Navigation.goBack(backTo);