IdentityAndEligibilityResponseFactory.java
package uk.gov.dhsc.htbhf.dwp.factory;
import org.springframework.stereotype.Component;
import uk.gov.dhsc.htbhf.dwp.entity.uc.UCAdult;
import uk.gov.dhsc.htbhf.dwp.entity.uc.UCChild;
import uk.gov.dhsc.htbhf.dwp.entity.uc.UCHousehold;
import uk.gov.dhsc.htbhf.dwp.model.*;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;
import static java.util.Collections.emptyList;
import static uk.gov.dhsc.htbhf.dwp.factory.IdentityVerificationUtils.areEqualIgnoringWhitespace;
import static uk.gov.dhsc.htbhf.dwp.factory.IdentityVerificationUtils.determineVerificationOutcome;
import static uk.gov.dhsc.htbhf.dwp.factory.IdentityVerificationUtils.firstSixCharacterMatch;
import static uk.gov.dhsc.htbhf.dwp.factory.IdentityVerificationUtils.matchingAdult;
@Component
public class IdentityAndEligibilityResponseFactory {
private static final String NO_HOUSEHOLD_IDENTIFIER_PROVIDED = "";
/**
* Full details of how the identity and eligibility response is built can be found in README.md.
*
* @param household household to check
* @param request request to check
* @return the response based on what's the request and the household in the database.
*/
public IdentityAndEligibilityResponse determineIdentityAndEligibilityResponse(UCHousehold household, DWPEligibilityRequest request) {
IdentityAndEligibilityResponse.IdentityAndEligibilityResponseBuilder builder = setupDefaultBuilder();
PersonDTO person = request.getPerson();
IdentityOutcome identityStatus = determineIdentityStatus(household, person, builder);
EligibilityOutcome eligibilityStatus = determineAndSetEligibilityStatus(identityStatus, household, builder);
if (IdentityOutcome.NOT_MATCHED == identityStatus || EligibilityOutcome.NOT_CONFIRMED == eligibilityStatus) {
return builder.build();
}
UCAdult matchingAdult = household.getAdults().stream().filter(adult -> matchingAdult(adult, person)).findFirst().get();
setAddressLine1VerificationOutcome(matchingAdult, person, builder);
setPostcodeVerificationOutcome(matchingAdult, person, builder);
builder.qualifyingBenefits(QualifyingBenefits.UNIVERSAL_CREDIT);
setEmailVerificationOutcome(matchingAdult, person, builder);
setMobileVerificationOutcome(matchingAdult, person, builder);
setDobOfChildrenUnder4(household, builder);
setPregnantDependantDob(person, builder);
return builder.build();
}
private void setPregnantDependantDob(PersonDTO person, IdentityAndEligibilityResponse.IdentityAndEligibilityResponseBuilder builder) {
if (person.getPregnantDependentDob() == null) {
builder.pregnantChildDOBMatch(VerificationOutcome.NOT_SUPPLIED);
}
}
//Make sure we only include those children which are under 4
private void setDobOfChildrenUnder4(UCHousehold household, IdentityAndEligibilityResponse.IdentityAndEligibilityResponseBuilder builder) {
LocalDate fourYearsAgo = LocalDate.now().minusYears(4);
List<LocalDate> childrenDobs = household.getChildren().stream()
.filter(child -> child.getDateOfBirth().isAfter(fourYearsAgo))
.map(UCChild::getDateOfBirth)
.collect(Collectors.toList());
builder.dobOfChildrenUnder4(childrenDobs);
}
private void setMobileVerificationOutcome(UCAdult matchingAdult, PersonDTO person,
IdentityAndEligibilityResponse.IdentityAndEligibilityResponseBuilder builder) {
VerificationOutcome mobileVerificationOutcome = determineVerificationOutcome(
matchingAdult.getMobilePhoneNumber(),
person.getMobilePhoneNumber(),
IdentityVerificationUtils::areEqual);
builder.mobilePhoneMatch(mobileVerificationOutcome);
}
private void setEmailVerificationOutcome(UCAdult matchingAdult, PersonDTO person,
IdentityAndEligibilityResponse.IdentityAndEligibilityResponseBuilder builder) {
VerificationOutcome emailVerificationOutcome = determineVerificationOutcome(
matchingAdult.getEmailAddress(),
person.getEmailAddress(),
IdentityVerificationUtils::areEqual);
builder.emailAddressMatch(emailVerificationOutcome);
}
private void setPostcodeVerificationOutcome(UCAdult matchingAdult, PersonDTO person,
IdentityAndEligibilityResponse.IdentityAndEligibilityResponseBuilder builder) {
VerificationOutcome postcodeVerificationOutcome = (areEqualIgnoringWhitespace(matchingAdult.getPostcode(), person.getPostcode()))
? VerificationOutcome.MATCHED : VerificationOutcome.NOT_MATCHED;
builder.postcodeMatch(postcodeVerificationOutcome);
}
private void setAddressLine1VerificationOutcome(UCAdult adult, PersonDTO person,
IdentityAndEligibilityResponse.IdentityAndEligibilityResponseBuilder builder) {
VerificationOutcome addressLine1VerificationOutcome = (firstSixCharacterMatch(adult.getAddressLine1(), person.getAddressLine1()))
? VerificationOutcome.MATCHED : VerificationOutcome.NOT_MATCHED;
builder.addressLine1Match(addressLine1VerificationOutcome);
}
private EligibilityOutcome determineAndSetEligibilityStatus(IdentityOutcome identityStatus,
UCHousehold household,
IdentityAndEligibilityResponse.IdentityAndEligibilityResponseBuilder builder) {
EligibilityOutcome outcome = determineEligibilityOutcome(identityStatus, household);
builder.eligibilityStatus(outcome);
return outcome;
}
private EligibilityOutcome determineEligibilityOutcome(IdentityOutcome identityStatus, UCHousehold household) {
if (identityStatus == IdentityOutcome.NOT_MATCHED) {
return EligibilityOutcome.NOT_SET;
} else if (household.isEarningsThresholdExceeded()) {
return EligibilityOutcome.NOT_CONFIRMED;
}
return EligibilityOutcome.CONFIRMED;
}
private IdentityOutcome determineIdentityStatus(UCHousehold household, PersonDTO person,
IdentityAndEligibilityResponse.IdentityAndEligibilityResponseBuilder builder) {
IdentityOutcome identityStatus = household.getAdults().stream().anyMatch(adult -> matchingAdult(adult, person))
? IdentityOutcome.MATCHED : IdentityOutcome.NOT_MATCHED;
builder.identityStatus(identityStatus);
return identityStatus;
}
private IdentityAndEligibilityResponse.IdentityAndEligibilityResponseBuilder setupDefaultBuilder() {
return IdentityAndEligibilityResponse.builder()
.identityStatus(IdentityOutcome.NOT_MATCHED)
.eligibilityStatus(EligibilityOutcome.NOT_SET)
.addressLine1Match(VerificationOutcome.NOT_SET)
.postcodeMatch(VerificationOutcome.NOT_SET)
.mobilePhoneMatch(VerificationOutcome.NOT_SET)
.emailAddressMatch(VerificationOutcome.NOT_SET)
.qualifyingBenefits(QualifyingBenefits.NOT_SET)
.dobOfChildrenUnder4(emptyList())
.householdIdentifier(NO_HOUSEHOLD_IDENTIFIER_PROVIDED)
.pregnantChildDOBMatch(VerificationOutcome.NOT_SET)
.deathVerificationFlag(DeathVerificationFlag.N_A);
}
}