Skip to content

Commit

Permalink
Merge pull request #34075 from shubham1206agra/fix-currency-step
Browse files Browse the repository at this point in the history
Fixed currency selection on confirm step
  • Loading branch information
techievivek authored Feb 5, 2024
2 parents 26b2e16 + 2bf606f commit 8034a1b
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 55 deletions.
23 changes: 21 additions & 2 deletions src/libs/actions/IOU.js
Original file line number Diff line number Diff line change
Expand Up @@ -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});
}

Expand All @@ -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
Expand Down Expand Up @@ -3791,6 +3809,7 @@ export {
setMoneyRequestCategory_temporaryForRefactor,
setMoneyRequestCreated_temporaryForRefactor,
setMoneyRequestCurrency_temporaryForRefactor,
setMoneyRequestOriginalCurrency_temporaryForRefactor,
setMoneyRequestDescription_temporaryForRefactor,
setMoneyRequestMerchant_temporaryForRefactor,
setMoneyRequestParticipants_temporaryForRefactor,
Expand Down
28 changes: 23 additions & 5 deletions src/pages/iou/request/step/IOURequestStepAmount.js
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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;
Expand All @@ -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);
};
Expand All @@ -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) {
Expand All @@ -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);
Expand Down
82 changes: 50 additions & 32 deletions src/pages/iou/request/step/IOURequestStepConfirmation.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 (
<ScreenWrapper
includeSafeAreaPaddingBottom={false}
Expand All @@ -342,38 +356,42 @@ function IOURequestStepConfirmation({
},
]}
/>
<MoneyRequestConfirmationList
transaction={transaction}
hasMultipleParticipants={iouType === CONST.IOU.TYPE.SPLIT}
selectedParticipants={participants}
iouAmount={transaction.amount}
iouComment={lodashGet(transaction, 'comment.comment', '')}
iouCurrencyCode={transaction.currency}
iouIsBillable={transaction.billable}
onToggleBillable={setBillable}
iouCategory={transaction.category}
iouTag={transaction.tag}
onConfirm={createTransaction}
onSendMoney={sendMoney}
onSelectParticipant={addNewParticipant}
receiptPath={receiptPath}
receiptFilename={receiptFilename}
iouType={iouType}
reportID={reportID}
isPolicyExpenseChat={isPolicyExpenseChat}
// The participants can only be modified when the action is initiated from directly within a group chat and not the floating-action-button.
// This is because when there is a group of people, say they are on a trip, and you have some shared expenses with some of the people,
// but not all of them (maybe someone skipped out on dinner). Then it's nice to be able to select/deselect people from the group chat bill
// split rather than forcing the user to create a new group, just for that expense. The reportID is empty, when the action was initiated from
// the floating-action-button (since it is something that exists outside the context of a report).
canModifyParticipants={!transaction.isFromGlobalCreate}
policyID={report.policyID}
bankAccountRoute={ReportUtils.getBankAccountRoute(report)}
iouMerchant={transaction.merchant}
iouCreated={transaction.created}
isDistanceRequest={requestType === CONST.IOU.REQUEST_TYPE.DISTANCE}
shouldShowSmartScanFields={_.isEmpty(lodashGet(transaction, 'receipt.source', ''))}
/>
{isLoading ? (
<FullScreenLoadingIndicator />
) : (
<MoneyRequestConfirmationList
transaction={transaction}
hasMultipleParticipants={iouType === CONST.IOU.TYPE.SPLIT}
selectedParticipants={participants}
iouAmount={transaction.amount}
iouComment={lodashGet(transaction, 'comment.comment', '')}
iouCurrencyCode={transaction.currency}
iouIsBillable={transaction.billable}
onToggleBillable={setBillable}
iouCategory={transaction.category}
iouTag={transaction.tag}
onConfirm={createTransaction}
onSendMoney={sendMoney}
onSelectParticipant={addNewParticipant}
receiptPath={receiptPath}
receiptFilename={receiptFilename}
iouType={iouType}
reportID={reportID}
isPolicyExpenseChat={isPolicyExpenseChat}
// The participants can only be modified when the action is initiated from directly within a group chat and not the floating-action-button.
// This is because when there is a group of people, say they are on a trip, and you have some shared expenses with some of the people,
// but not all of them (maybe someone skipped out on dinner). Then it's nice to be able to select/deselect people from the group chat bill
// split rather than forcing the user to create a new group, just for that expense. The reportID is empty, when the action was initiated from
// the floating-action-button (since it is something that exists outside the context of a report).
canModifyParticipants={!transaction.isFromGlobalCreate}
policyID={report.policyID}
bankAccountRoute={ReportUtils.getBankAccountRoute(report)}
iouMerchant={transaction.merchant}
iouCreated={transaction.created}
isDistanceRequest={requestType === CONST.IOU.REQUEST_TYPE.DISTANCE}
shouldShowSmartScanFields={_.isEmpty(lodashGet(transaction, 'receipt.source', ''))}
/>
)}
</View>
)}
</ScreenWrapper>
Expand Down
14 changes: 4 additions & 10 deletions src/pages/iou/request/step/IOURequestStepCurrency.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}&currency=${selectedCurrency}`);
} else {
Navigation.goBack(routeToAmountPageWithConfirmationAsBackTo);
}
Navigation.goBack(routeToAmountPageWithConfirmationAsBackTo);
return;
}
Navigation.goBack(backTo || ROUTES.HOME);
Expand All @@ -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(() => {
Expand Down
30 changes: 24 additions & 6 deletions src/pages/iou/request/step/IOURequestStepTaxAmountPage.js
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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,
}) {
Expand All @@ -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);
Expand All @@ -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);
Expand Down

0 comments on commit 8034a1b

Please sign in to comment.