Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor part of ActivateWallet into UpdatePersonalDetailsForWallet #9914

Merged
merged 28 commits into from
Aug 15, 2022
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,10 @@ const CONST = {
},
},
ERROR: {
// If these get updated, we need to update the codes on the Web side too
SSN: 'ssnError',
Gonals marked this conversation as resolved.
Show resolved Hide resolved
KBA: 'kbaNeeded',
KYC: 'kycFailed',
FULL_SSN_NOT_FOUND: 'Full SSN not found',
MISSING_FIELD: 'Missing required additional details fields',
WRONG_ANSWERS: 'Wrong answers',
Expand Down
66 changes: 66 additions & 0 deletions src/libs/actions/Wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import * as DeprecatedAPI from '../deprecatedAPI';
import CONST from '../../CONST';
import * as PaymentMethods from './PaymentMethods';
import * as Localize from '../Localize';
import * as API from '../API';

/**
* Fetch and save locally the Onfido SDK token and applicantID
Expand Down Expand Up @@ -153,6 +154,70 @@ function buildIdologyError(idologyErrors) {
return `${errorStart} ${Localize.arrayToString(errorsTranslated)}. ${errorEnd}`;
}

/**
* Validates a user's provided details against a series of checks
*
* @param {Object} personalDetails
*/
function updatePersonalDetails(personalDetails) {
if (!personalDetails) {
return;
}
const firstName = personalDetails.legalFirstName || '';
const lastName = personalDetails.legalLastName || '';
const dob = personalDetails.dob || '';
const addressStreet = personalDetails.addressStreet || '';
const addressCity = personalDetails.addressCity || '';
const addressState = personalDetails.addressState || '';
const addressZip = personalDetails.addressZip || '';
const ssn = personalDetails.ssn || '';
const phoneNumber = personalDetails.phoneNumber || '';
API.write('UpdatePersonalDetailsForWallet', {
firstName,
lastName,
dob,
addressStreet,
addressCity,
addressState,
addressZip,
ssn,
phoneNumber,
}, {
optimisticData: [
{
onyxMethod: CONST.ONYX.METHOD.MERGE,
key: ONYXKEYS.WALLET_ADDITIONAL_DETAILS,
value: {
isLoading: true,
error: '',
chiragsalian marked this conversation as resolved.
Show resolved Hide resolved
},

chiragsalian marked this conversation as resolved.
Show resolved Hide resolved
},
],
successData: [
{
onyxMethod: CONST.ONYX.METHOD.MERGE,
key: ONYXKEYS.WALLET_ADDITIONAL_DETAILS,
value: {
isLoading: false,
error: '',
chiragsalian marked this conversation as resolved.
Show resolved Hide resolved
},

chiragsalian marked this conversation as resolved.
Show resolved Hide resolved
},
],
failureData: [
{
onyxMethod: CONST.ONYX.METHOD.MERGE,
key: ONYXKEYS.WALLET_ADDITIONAL_DETAILS,
value: {
isLoading: false,
Gonals marked this conversation as resolved.
Show resolved Hide resolved
},

chiragsalian marked this conversation as resolved.
Show resolved Hide resolved
},
],
});
}

/**
* This action can be called repeatedly with different steps until an Expensify Wallet has been activated.
*
Expand Down Expand Up @@ -361,4 +426,5 @@ export {
setAdditionalDetailsQuestions,
buildIdologyError,
updateCurrentStep,
updatePersonalDetails,
};
41 changes: 21 additions & 20 deletions src/pages/EnablePayments/AdditionalDetailsStep.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize
import Navigation from '../../libs/Navigation/Navigation';
import styles from '../../styles/styles';
import Text from '../../components/Text';
import * as BankAccounts from '../../libs/actions/BankAccounts';
import CONST from '../../CONST';
import compose from '../../libs/compose';
import ONYXKEYS from '../../ONYXKEYS';
Expand All @@ -28,6 +27,7 @@ import FormHelper from '../../libs/FormHelper';
import walletAdditionalDetailsDraftPropTypes from './walletAdditionalDetailsDraftPropTypes';
import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../components/withCurrentUserPersonalDetails';
import * as PersonalDetails from '../../libs/actions/PersonalDetails';
import OfflineIndicator from '../../components/OfflineIndicator';

const propTypes = {
...withLocalizePropTypes,
Expand All @@ -36,13 +36,13 @@ const propTypes = {
/** Stores additional information about the additional details step e.g. loading state and errors with fields */
walletAdditionalDetails: PropTypes.shape({
/** Are we waiting for a response? */
loading: PropTypes.bool,
isLoading: PropTypes.bool,

/** Which field needs attention? */
errorFields: PropTypes.objectOf(PropTypes.bool),

/** Any additional error message to show */
additionalErrorMessage: PropTypes.string,
errors: PropTypes.objectOf(PropTypes.string),

/** Questions returned by Idology */
questions: PropTypes.arrayOf(PropTypes.shape({
Expand All @@ -54,8 +54,8 @@ const propTypes = {
/** ExpectID ID number related to those questions */
idNumber: PropTypes.string,

/** If we should ask for the full SSN (when LexisNexis failed retrieving the first 5 from the last 4) */
shouldAskForFullSSN: PropTypes.bool,
/** Error code to determine additional behavior */
errorCode: PropTypes.string,
}),

/** Stores the personal details typed by the user */
Expand All @@ -65,11 +65,11 @@ const propTypes = {
const defaultProps = {
walletAdditionalDetails: {
errorFields: {},
loading: false,
additionalErrorMessage: '',
isLoading: false,
errors: {},
questions: [],
idNumber: '',
shouldAskForFullSSN: false,
errorCode: '',
},
walletAdditionalDetailsDraft: {
legalFirstName: '',
Expand Down Expand Up @@ -187,7 +187,7 @@ class AdditionalDetailsStep extends React.Component {
errors.phoneNumber = true;
}

if (this.props.walletAdditionalDetails.shouldAskForFullSSN) {
if (this.props.walletAdditionalDetails.errorCode === CONST.WALLET.ERROR.SSN) {
if (!ValidationUtils.isValidSSNFullNine(this.props.walletAdditionalDetailsDraft.ssn)) {
errors.ssnFull9 = true;
}
Expand All @@ -211,13 +211,11 @@ class AdditionalDetailsStep extends React.Component {
if (!this.validate()) {
return;
}

BankAccounts.activateWallet(CONST.WALLET.STEP.ADDITIONAL_DETAILS, {
personalDetails: {
...this.props.walletAdditionalDetailsDraft,
phoneNumber: LoginUtils.getPhoneNumberWithoutUSCountryCodeAndSpecialChars(this.props.walletAdditionalDetailsDraft.phoneNumber),
},
});
const personalDetails = {
...this.props.walletAdditionalDetailsDraft,
phoneNumber: LoginUtils.getPhoneNumberWithoutUSCountryCodeAndSpecialChars(this.props.walletAdditionalDetailsDraft.phoneNumber),
};
Wallet.updatePersonalDetails(personalDetails);
}

/**
Expand Down Expand Up @@ -267,10 +265,12 @@ class AdditionalDetailsStep extends React.Component {
);
}

const errors = lodashGet(this.props, 'walletAdditionalDetails.errors', {});
const isErrorVisible = _.size(this.getErrors()) > 0
|| lodashGet(this.props, 'walletAdditionalDetails.additionalErrorMessage', '').length > 0;
const shouldAskForFullSSN = this.props.walletAdditionalDetails.shouldAskForFullSSN;
|| !_.isEmpty(errors);
const shouldAskForFullSSN = this.props.walletAdditionalDetails.errorCode === CONST.WALLET.ERROR.SSN;
const {firstName, lastName} = PersonalDetails.extractFirstAndLastNameFromAvailableDetails(this.props.currentUserPersonalDetails);
const errorMessage = _.isEmpty(errors) ? '' : _.last(_.values(errors));

return (
<ScreenWrapper style={[styles.flex1]} keyboardAvoidingViewBehavior="height">
Expand Down Expand Up @@ -386,10 +386,11 @@ class AdditionalDetailsStep extends React.Component {
onFixTheErrorsLinkPressed={() => {
this.form.scrollTo({y: 0, animated: true});
}}
message={this.props.walletAdditionalDetails.additionalErrorMessage}
isLoading={this.props.walletAdditionalDetails.loading}
message={errorMessage}
isLoading={this.props.walletAdditionalDetails.isLoading}
buttonText={this.props.translate('common.saveAndContinue')}
/>
<OfflineIndicator containerStyles={[styles.mh5, styles.mb3]} />
</FormScrollView>
</View>
</ScreenWrapper>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/EnablePayments/EnablePaymentsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class EnablePaymentsPage extends React.Component {
return <FullScreenLoadingIndicator />;
}

if (this.props.userWallet.shouldShowFailedKYC) {
if (this.props.userWallet.errorCode === CONST.WALLET.ERROR.KYC) {
return (
<ScreenWrapper style={[styles.flex1]} keyboardAvoidingViewBehavior="height">
<HeaderWithCloseButton
Expand Down
4 changes: 2 additions & 2 deletions src/pages/EnablePayments/userWalletPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default {
/** Status of wallet - e.g. SILVER or GOLD */
tierName: PropTypes.string,

/** If we should show the FailedKYC view after the user submitted their info with a non fixable error */
shouldShowFailedKYC: PropTypes.bool,
/** Error code returned by the server */
errorCode: PropTypes.string,
}),
};