Skip to content

Commit

Permalink
Merge pull request #17474 from Expensify/francois-dateRequirementIncl…
Browse files Browse the repository at this point in the history
…usiveComparison

Fix `meetsAgeRequirements` for min/max dates
  • Loading branch information
marcochavezf authored Apr 27, 2023
2 parents 6f0888c + e3cfbc4 commit 47898da
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 15 deletions.
30 changes: 21 additions & 9 deletions src/libs/ValidationUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,16 +195,27 @@ function isValidPaypalUsername(paypalUsername) {
}

/**
* Validate that "date" is between 18 and 150 years in the past
* Validate that a date meets the minimum age requirement.
*
* @param {String} date
* @returns {Boolean}
*/
function meetsAgeRequirements(date) {
const eighteenYearsAgo = moment().subtract(18, 'years');
const oneHundredFiftyYearsAgo = moment().subtract(150, 'years');
function meetsMinimumAgeRequirement(date) {
const testDate = moment(date);
return testDate.isValid() && testDate.isBetween(oneHundredFiftyYearsAgo, eighteenYearsAgo);
const minDate = moment().subtract(CONST.DATE_BIRTH.MIN_AGE_FOR_PAYMENT, 'years');
return testDate.isValid() && testDate.isSameOrBefore(minDate, 'day');
}

/**
* Validate that a date meets the maximum age requirement.
*
* @param {String} date
* @returns {Boolean}
*/
function meetsMaximumAgeRequirement(date) {
const testDate = moment(date);
const maxDate = moment().subtract(CONST.DATE_BIRTH.MAX_AGE, 'years');
return testDate.isValid() && testDate.isSameOrAfter(maxDate, 'day');
}

/**
Expand All @@ -222,7 +233,7 @@ function getAgeRequirementError(date, minimumAge, maximumAge) {
if (!testDate.isValid()) {
return Localize.translateLocal('common.error.dateInvalid');
}
if (testDate.isBetween(longAgoDate, recentDate, undefined, [])) {
if (testDate.isBetween(longAgoDate, recentDate, undefined, '[]')) {
return '';
}
if (testDate.isSameOrAfter(recentDate)) {
Expand Down Expand Up @@ -267,9 +278,9 @@ function validateIdentity(identity) {
}

// dob field has multiple validations/errors, we are handling it temporarily like this.
if (!isValidDate(identity.dob)) {
if (!isValidDate(identity.dob) || !meetsMaximumAgeRequirement(identity.dob)) {
errors.dob = true;
} else if (!meetsAgeRequirements(identity.dob)) {
} else if (!meetsMinimumAgeRequirement(identity.dob)) {
errors.dobAge = true;
}

Expand Down Expand Up @@ -432,7 +443,8 @@ function isValidTaxID(taxID) {
}

export {
meetsAgeRequirements,
meetsMinimumAgeRequirement,
meetsMaximumAgeRequirement,
getAgeRequirementError,
isValidAddress,
isValidDate,
Expand Down
4 changes: 2 additions & 2 deletions src/pages/EnablePayments/AdditionalDetailsStep.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ class AdditionalDetailsStep extends React.Component {
errors[INPUT_IDS.LEGAL_LAST_NAME] = this.props.translate(this.errorTranslationKeys.legalLastName);
}

if (!ValidationUtils.isValidPastDate(values[INPUT_IDS.DOB])) {
if (!ValidationUtils.isValidPastDate(values[INPUT_IDS.DOB]) || !ValidationUtils.meetsMaximumAgeRequirement(values[INPUT_IDS.DOB])) {
ErrorUtils.addErrorMessage(errors, INPUT_IDS.DOB, this.props.translate(this.errorTranslationKeys.dob));
} else if (!ValidationUtils.meetsAgeRequirements(values[INPUT_IDS.DOB])) {
} else if (!ValidationUtils.meetsMinimumAgeRequirement(values[INPUT_IDS.DOB])) {
ErrorUtils.addErrorMessage(errors, INPUT_IDS.DOB, this.props.translate(this.errorTranslationKeys.age));
}

Expand Down
8 changes: 6 additions & 2 deletions src/pages/ReimbursementAccount/ACHContractStep.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,12 @@ class ACHContractStep extends React.Component {
}
});

if (values[`beneficialOwner_${ownerKey}_dob`] && !ValidationUtils.meetsAgeRequirements(values[`beneficialOwner_${ownerKey}_dob`])) {
errors[`beneficialOwner_${ownerKey}_dob`] = this.props.translate('bankAccount.error.age');
if (values[`beneficialOwner_${ownerKey}_dob`]) {
if (!ValidationUtils.meetsMinimumAgeRequirement(values[`beneficialOwner_${ownerKey}_dob`])) {
errors[`beneficialOwner_${ownerKey}_dob`] = this.props.translate('bankAccount.error.age');
} else if (!ValidationUtils.meetsMaximumAgeRequirement(values[`beneficialOwner_${ownerKey}_dob`])) {
errors[`beneficialOwner_${ownerKey}_dob`] = this.props.translate('bankAccount.error.dob');
}
}

if (values[`beneficialOwner_${ownerKey}_ssnLast4`] && !ValidationUtils.isValidSSNLastFour(values[`beneficialOwner_${ownerKey}_ssnLast4`])) {
Expand Down
8 changes: 6 additions & 2 deletions src/pages/ReimbursementAccount/RequestorStep.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,12 @@ class RequestorStep extends React.Component {
errors.dob = this.props.translate('bankAccount.error.dob');
}

if (values.dob && !ValidationUtils.meetsAgeRequirements(values.dob)) {
errors.dob = this.props.translate('bankAccount.error.age');
if (values.dob) {
if (!ValidationUtils.meetsMinimumAgeRequirement(values.dob)) {
errors.dob = this.props.translate('bankAccount.error.age');
} else if (!ValidationUtils.meetsMaximumAgeRequirement(values.dob)) {
errors.dob = this.props.translate('bankAccount.error.dob');
}
}

if (!ValidationUtils.isRequiredFulfilled(values.ssnLast4) || !ValidationUtils.isValidSSNLastFour(values.ssnLast4)) {
Expand Down

0 comments on commit 47898da

Please sign in to comment.