Skip to content

Commit

Permalink
Merge pull request #7200 from parasharrajat/trans-amount-scaffold
Browse files Browse the repository at this point in the history
Add ChooseTransferAccountPage and allow selecting accounts for wallet transfer
  • Loading branch information
stitesExpensify authored Jan 24, 2022
2 parents f594800 + 0043cec commit 921fa4f
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 39 deletions.
4 changes: 2 additions & 2 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,8 @@ export default {
},
paymentMethodList: {
addPaymentMethod: 'Add payment method',
addDebitCard: 'Add debit card',
addBankAccount: 'Add bank account',
addNewDebitCard: 'Add new debit card',
addNewBankAccount: 'Add new bank account',
accountLastFour: 'Account ending in',
cardLastFour: 'Card ending in',
addFirstPaymentMethod: 'Add a payment method to send and receive payments directly in the app.',
Expand Down
4 changes: 2 additions & 2 deletions src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,8 @@ export default {
},
paymentMethodList: {
addPaymentMethod: 'Agrega método de pago',
addDebitCard: 'Agregar tarjeta de débito',
addBankAccount: 'Agregar cuenta de banco',
addNewDebitCard: 'Agregar nueva tarjeta de débito',
addNewBankAccount: 'Agregar nueva cuenta de banco',
accountLastFour: 'Cuenta con terminación',
cardLastFour: 'Tarjeta con terminacíon',
addFirstPaymentMethod: 'Añade un método de pago para enviar y recibir pagos directamente desde la aplicación.',
Expand Down
2 changes: 1 addition & 1 deletion src/libs/PaymentUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ function formatPaymentMethods(bankAccountList, cardList, payPalMeUsername = '',
combinedPaymentMethods.push({
title: card.addressName,
description: formattedCardNumber,
methodID: card.cardNumber,
methodID: card.fundID,
icon,
iconSize,
key: `card-${card.cardNumber}`,
Expand Down
33 changes: 24 additions & 9 deletions src/libs/actions/PaymentMethods.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,10 @@ function clearDebitCardFormErrorAndSubmit() {
* Call the API to transfer wallet balance.
* @param {Object} paymentMethod
* @param {*} paymentMethod.methodID
* @param {String} paymentMethod.type
* @param {String} paymentMethod.accountType
*/
function transferWalletBalance(paymentMethod) {
const paymentMethodIDKey = paymentMethod.type === CONST.PAYMENT_METHODS.BANK_ACCOUNT
const paymentMethodIDKey = paymentMethod.accountType === CONST.PAYMENT_METHODS.BANK_ACCOUNT
? CONST.PAYMENT_METHOD_ID_KEYS.BANK_ACCOUNT
: CONST.PAYMENT_METHOD_ID_KEYS.DEBIT_CARD;
const parameters = {
Expand All @@ -209,13 +209,10 @@ function transferWalletBalance(paymentMethod) {
});
}

/**
* Set the transfer account and reset the transfer data for Wallet balance transfer
* @param {String} selectedAccountID
*/
function saveWalletTransferAccountAndResetData(selectedAccountID) {
function resetWalletTransferData() {
Onyx.merge(ONYXKEYS.WALLET_TRANSFER, {
selectedAccountID,
selectedAccountType: '',
selectedAccountID: null,
filterPaymentMethodType: null,
loading: false,
shouldShowConfirmModal: false,
Expand All @@ -229,6 +226,22 @@ function saveWalletTransferAmount(transferAmount) {
Onyx.merge(ONYXKEYS.WALLET_TRANSFER, {transferAmount});
}

/**
* @param {String} selectedAccountType
* @param {String} selectedAccountID
*/
function saveWalletTransferAccountTypeAndID(selectedAccountType, selectedAccountID) {
Onyx.merge(ONYXKEYS.WALLET_TRANSFER, {selectedAccountType, selectedAccountID});
}

/**
* Toggles the user's selected type of payment method (bank account or debit card) on the wallet transfer balance screen.
* @param {String} filterPaymentMethodType
*/
function saveWalletTransferMethodType(filterPaymentMethodType) {
Onyx.merge(ONYXKEYS.WALLET_TRANSFER, {filterPaymentMethodType});
}

function dismissWalletConfirmModal() {
Onyx.merge(ONYXKEYS.WALLET_TRANSFER, {shouldShowConfirmModal: false});
}
Expand All @@ -243,7 +256,9 @@ export {
continueSetup,
clearDebitCardFormErrorAndSubmit,
transferWalletBalance,
saveWalletTransferAccountAndResetData,
resetWalletTransferData,
saveWalletTransferAmount,
saveWalletTransferAccountTypeAndID,
saveWalletTransferMethodType,
dismissWalletConfirmModal,
};
99 changes: 86 additions & 13 deletions src/pages/settings/Payments/ChooseTransferAccountPage.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,100 @@
import React from 'react';
import {withOnyx} from 'react-native-onyx';
import {View} from 'react-native';
import HeaderWithCloseButton from '../../../components/HeaderWithCloseButton';
import ScreenWrapper from '../../../components/ScreenWrapper';
import Navigation from '../../../libs/Navigation/Navigation';
import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
import KeyboardAvoidingView from '../../../components/KeyboardAvoidingView';
import CONST from '../../../CONST';
import PaymentMethodList from './PaymentMethodList';
import * as PaymentMethods from '../../../libs/actions/PaymentMethods';
import ROUTES from '../../../ROUTES';
import MenuItem from '../../../components/MenuItem';
import * as Expensicons from '../../../components/Icon/Expensicons';
import compose from '../../../libs/compose';
import ONYXKEYS from '../../../ONYXKEYS';
import walletTransferPropTypes from './walletTransferPropTypes';
import styles from '../../../styles/styles';

const propTypes = {
/** Wallet transfer propTypes */
walletTransfer: walletTransferPropTypes,

...withLocalizePropTypes,
};

const ChooseTransferAccountPage = props => (
<ScreenWrapper>
<KeyboardAvoidingView>
<HeaderWithCloseButton
title={props.translate('chooseTransferAccountPage.chooseAccount')}
shouldShowBackButton
onBackButtonPress={() => Navigation.goBack()}
onCloseButtonPress={() => Navigation.dismissModal()}
/>
</KeyboardAvoidingView>
</ScreenWrapper>
);
const defaultProps = {
walletTransfer: {},
};

const ChooseTransferAccountPage = (props) => {
/**
* Go back to transfer balance screen with the selected bank account set
* @param {Object} event Click event object
* @param {String} accountType of the selected account type
* @param {Object} account of the selected account data
*/
const selectAccountAndNavigateBack = (event, accountType, account) => {
PaymentMethods.saveWalletTransferAccountTypeAndID(
accountType,
accountType === CONST.PAYMENT_METHODS.BANK_ACCOUNT
? account.bankAccountID
: account.fundID,
);
Navigation.navigate(ROUTES.SETTINGS_PAYMENTS_TRANSFER_BALANCE);
};

/**
* @param {String} paymentType
*/
const navigateToAddPaymentMethodPage = () => {
if (props.walletTransfer.filterPaymentMethodType === CONST.PAYMENT_METHODS.DEBIT_CARD) {
Navigation.navigate(ROUTES.SETTINGS_ADD_DEBIT_CARD);
return;
}
Navigation.navigate(ROUTES.SETTINGS_ADD_BANK_ACCOUNT);
};

return (
<ScreenWrapper>
<KeyboardAvoidingView>
<HeaderWithCloseButton
title={props.translate('chooseTransferAccountPage.chooseAccount')}
shouldShowBackButton
onBackButtonPress={() => Navigation.goBack()}
onCloseButtonPress={() => Navigation.dismissModal()}
/>
<View style={[styles.mt6, styles.flexShrink1, styles.flexBasisAuto]}>
<PaymentMethodList
onPress={selectAccountAndNavigateBack}
shouldShowSelectedState
filterType={props.walletTransfer.filterPaymentMethodType}
selectedMethodID={props.walletTransfer.selectedAccountID}
shouldShowAddPaymentMethodButton={false}
/>
</View>
<MenuItem
onPress={navigateToAddPaymentMethodPage}
title={props.walletTransfer.filterPaymentMethodType === CONST.PAYMENT_METHODS.BANK_ACCOUNT
? props.translate('paymentMethodList.addNewBankAccount')
: props.translate('paymentMethodList.addNewDebitCard')}
icon={Expensicons.Plus}
/>
</KeyboardAvoidingView>
</ScreenWrapper>
);
};

ChooseTransferAccountPage.propTypes = propTypes;
ChooseTransferAccountPage.defaultProps = defaultProps;
ChooseTransferAccountPage.displayName = 'ChooseTransferAccountPage';

export default withLocalize(ChooseTransferAccountPage);
export default compose(
withLocalize,
withOnyx({
walletTransfer: {
key: ONYXKEYS.WALLET_TRANSFER,
},
}),
)(ChooseTransferAccountPage);
20 changes: 20 additions & 0 deletions src/pages/settings/Payments/PaymentMethodList.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ const propTypes = {
cardID: PropTypes.number,
})),

/** Whether the add Payment button be shown on the list */
shouldShowAddPaymentMethodButton: PropTypes.bool,

/** Type to filter the payment Method list */
filterType: PropTypes.oneOf([CONST.PAYMENT_METHODS.DEBIT_CARD, CONST.PAYMENT_METHODS.BANK_ACCOUNT, '']),

/** User wallet props */
userWallet: PropTypes.shape({
/** The ID of the linked account */
walletLinkedAccountID: PropTypes.number,
Expand All @@ -66,6 +73,8 @@ const defaultProps = {
},
isLoadingPayments: false,
isAddPaymentMenuActive: false,
shouldShowAddPaymentMethodButton: true,
filterType: '',
};

class PaymentMethodList extends Component {
Expand All @@ -82,6 +91,11 @@ class PaymentMethodList extends Component {
*/
createPaymentMethodList() {
let combinedPaymentMethods = PaymentUtils.formatPaymentMethods(this.props.bankAccountList, this.props.cardList, this.props.payPalMeUsername, this.props.userWallet);

if (!_.isEmpty(this.props.filterType)) {
combinedPaymentMethods = _.filter(combinedPaymentMethods, paymentMethod => paymentMethod.accountType === this.props.filterType);
}

combinedPaymentMethods = _.map(combinedPaymentMethods, paymentMethod => ({
...paymentMethod,
type: MENU_ITEM,
Expand All @@ -96,6 +110,10 @@ class PaymentMethodList extends Component {
});
}

if (!this.props.shouldShowAddPaymentMethodButton) {
return combinedPaymentMethods;
}

combinedPaymentMethods.push({
type: MENU_ITEM,
title: this.props.translate('paymentMethodList.addPaymentMethod'),
Expand Down Expand Up @@ -132,6 +150,8 @@ class PaymentMethodList extends Component {
iconWidth={item.iconSize}
badgeText={item.isDefault ? this.props.translate('paymentMethodList.defaultPaymentMethod') : null}
wrapperStyle={item.wrapperStyle}
shouldShowSelectedState={this.props.shouldShowSelectedState}
isSelected={this.props.selectedMethodID === item.methodID}
/>
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/settings/Payments/PaymentsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ class PaymentsPage extends React.Component {
</>
)}
<Text
style={[styles.ph5, styles.formLabel]}
style={[styles.ph5, styles.mt6, styles.formLabel]}
>
{this.props.translate('paymentsPage.paymentMethodsTitle')}
</Text>
Expand Down
51 changes: 40 additions & 11 deletions src/pages/settings/Payments/TransferBalancePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import React from 'react';
import {View, ScrollView} from 'react-native';
import PropTypes from 'prop-types';
import {withOnyx} from 'react-native-onyx';
import lodashGet from 'lodash/get';
import ONYXKEYS from '../../../ONYXKEYS';
import HeaderWithCloseButton from '../../../components/HeaderWithCloseButton';
import ScreenWrapper from '../../../components/ScreenWrapper';
Expand All @@ -24,6 +23,7 @@ import walletTransferPropTypes from './walletTransferPropTypes';
import * as PaymentMethods from '../../../libs/actions/PaymentMethods';
import * as PaymentUtils from '../../../libs/PaymentUtils';
import userWalletPropTypes from '../../EnablePayments/userWalletPropTypes';
import ROUTES from '../../../ROUTES';

const propTypes = {
/** User's wallet information */
Expand Down Expand Up @@ -96,35 +96,62 @@ class TransferBalancePage extends React.Component {
},
];

this.saveTransferAmountAndBalance = this.saveTransferAmountAndBalance.bind(this);
this.getSelectedPaymentMethodAccount = this.getSelectedPaymentMethodAccount.bind(this);

PaymentMethods.resetWalletTransferData();
const selectedAccount = this.getSelectedPaymentMethodAccount();
PaymentMethods.saveWalletTransferAccountAndResetData(selectedAccount ? selectedAccount.id : '');

// Select the default payment account when page is opened,
// so that user can see that preselected on choose transfer account page
if (!selectedAccount || !selectedAccount.isDefault) {
return;
}

PaymentMethods.saveWalletTransferAccountTypeAndID(
selectedAccount.accountType,
selectedAccount.methodID,
);
}

/**
* Get the selected/default payment method account for wallet transfer
* @returns {Object|undefined}
*/
getSelectedPaymentMethodAccount() {
const paymentMethods = PaymentUtils.formatPaymentMethods(this.props.bankAccountList, this.props.cardList, '', this.props.userWallet);
const accountID = this.props.walletTransfer.selectedAccountID || lodashGet(this.props, 'userWallet.walletLinkedAccountID', '');
return _.find(paymentMethods, method => method.methodID === accountID);
const paymentMethods = PaymentUtils.formatPaymentMethods(
this.props.bankAccountList,
this.props.cardList,
'',
this.props.userWallet,
);

const defaultAccount = _.find(paymentMethods, method => method.isDefault);
const selectedAccount = _.find(
paymentMethods,
method => method.accountType === this.props.walletTransfer.selectedAccountType
&& method.methodID === this.props.walletTransfer.selectedAccountID,
);
return selectedAccount || defaultAccount;
}

/**
* @param {Number} transferAmount
* @param {Object} selectedAccount
*/
saveTransferAmountAndBalance(transferAmount, selectedAccount) {
saveTransferAmountAndStartTransfer(transferAmount, selectedAccount) {
PaymentMethods.saveWalletTransferAmount(transferAmount);
PaymentMethods.transferWalletBalance(selectedAccount);
}

/**
* @param {String} filterPaymentMethodType
*/
navigateToChooseTransferAccount(filterPaymentMethodType) {
PaymentMethods.saveWalletTransferMethodType(filterPaymentMethodType);
Navigation.navigate(ROUTES.SETTINGS_PAYMENTS_CHOOSE_TRANSFER_ACCOUNT);
}

render() {
const selectedAccount = this.getSelectedPaymentMethodAccount();
const selectedPaymentType = selectedAccount && selectedAccount.type === CONST.PAYMENT_METHODS.BANK_ACCOUNT
const selectedPaymentType = selectedAccount && selectedAccount.accountType === CONST.PAYMENT_METHODS.BANK_ACCOUNT
? CONST.WALLET.TRANSFER_METHOD_TYPE.ACH
: CONST.WALLET.TRANSFER_METHOD_TYPE.INSTANT;

Expand Down Expand Up @@ -162,6 +189,7 @@ class TransferBalancePage extends React.Component {
...(selectedPaymentType === paymentType.key
&& styles.transferBalanceSelectedPayment),
}}
onPress={() => this.navigateToChooseTransferAccount(paymentType.type)}
/>
))}
<Text
Expand All @@ -182,6 +210,7 @@ class TransferBalancePage extends React.Component {
...styles.mrn5,
...styles.ph0,
}}
onPress={() => this.navigateToChooseTransferAccount(selectedAccount.accountType)}
/>
)}
<Text
Expand Down Expand Up @@ -210,7 +239,7 @@ class TransferBalancePage extends React.Component {
pressOnEnter
isLoading={this.props.walletTransfer.loading}
isDisabled={isButtonDisabled}
onPress={() => this.saveTransferAmountAndBalance(transferAmount, selectedAccount)}
onPress={() => this.saveTransferAmountAndStartTransfer(transferAmount, selectedAccount)}
text={this.props.translate(
'transferAmountPage.transfer',
{
Expand Down

0 comments on commit 921fa4f

Please sign in to comment.