Team ORANGE

"Oh, ik zit weer
vol ideëen. Echt, ik zit zo vol ideëen, je kunt er geen voorstelling van
maken"

Security word

  UK_RETRY_PROCESS_INITIAL_COMMUNICATION              ( 1,  2, true,  "Payment pending due to insufficient funds"),
  UK_AVAILABLE_BALANCE_ALMOST_EXCEEDED                ( 2,  3, true,  "Within \u00a3100 of available balance"),
  UK_CANCELLED_DIRECT_DEBIT                           ( 3, 13, true,  "Cancelled Direct Debit"),
  UK_COWORKER_CHANGED_NAME                            ( 4,  9, false, "Change of name"),
  UK_CHANGED_CONTACT_DETAILS_PHONE                    ( 5,  7, false, "Change of phone number"),
  UK_CHANGED_CONTACT_DETAILS_EMAIL                    ( 6,  8, false, "Change of email address"),
  UK_CUSTOMER_SETUP_AMENDED_CANCELLED_STANDING_ORDER  ( 7, 10, true,  "Set up, amend or cancel Standing Order"),
  UK_CUSTOMER_INSTRUCTED_PAYMNENT_NEW_PAYEE           ( 8, 11, true,  "Make a payment to a new payee"),
  UK_CUSTOMER_CHANGED_SECURITY_WORD_OR_HINT           ( 9, 12, false, "Change security word and hint"),
  UK_CUSTOMER_CLICKED_SECURITY_WORD_HINT              (10, 16, true,  "---"),
  UK_ACCOUNTOPENING_CONTACT_US                        (11, 17, true,  "Account opening - contact us"),
  UK_ACCOUNTOPENING_SIGNATURE_REMINDER                (12, 18, true,  "Account opening - signature reminder"),
  UK_ACCOUNTOPENING_CREDITAGREEMENT_REMINDER          (13, 19, true,  "Account opening - credit letter reminder"),
  UK_CASS_SWITCH_STARTED                              (14, 14, true,  "Current Account Switch in has started"),
  UK_CASS_SWITCH_COMPLETED                            (15, 15, true,  "Current Account Switch in has completed"),
  UK_PAYMENT_OUT_LARGE_AMOUNT                         (16,  4, true,  "Payment sent exceeding \u00a3500 (excludes DD's & SO's)"),
  UK_PAYMENT_DEPOSIT_LARGE_AMOUNT                     (17,  6, true,  "Payment received exceeding \u00a31000"),
  UK_WEEKLY_BALANCE                                   (18,  5, true,  "Weekly balance (sent Friday)"),
  UK_UNARRANGED_OVERDRAFT                             (19,  1, true,  "Account in unarranged overdraft");

SMS

Blueprint

<s:sequence>
	<s:element minOccurs="0" maxOccurs="1" name="Flat">
		<s:simpleType>
			<s:restriction base="s:string">
				<s:pattern value="[0-9A-Za-z'\\/* \-]*"/>
				<s:maxLength value="30"/>
			</s:restriction>
		</s:simpleType>
	</s:element>
	<s:element minOccurs="0" maxOccurs="1" name="HouseName">
		<s:simpleType>
			<s:restriction base="s:string">
				<s:pattern value="[-0-9A-Za-z'\- ]*"/>
				<s:maxLength value="50"/>
			</s:restriction>
		</s:simpleType>
	</s:element>
	<s:element minOccurs="0" maxOccurs="1" name="HouseNumber">
		<s:simpleType>
			<s:restriction base="s:string">
				<s:pattern value="[0-9A-Za-z'\\/\- ]*"/>
				<s:maxLength value="10"/>
			</s:restriction>
		</s:simpleType>
	</s:element>
	<s:element minOccurs="0" maxOccurs="1" name="Street">
		<s:simpleType>
			<s:restriction base="s:string">
				<s:pattern value="[0-9A-Za-z'\- .]*"/>
				<s:maxLength value="60"/>
			</s:restriction>
		</s:simpleType>
	</s:element>
	<s:element minOccurs="0" maxOccurs="1" name="Street2">
		<s:simpleType>
			<s:restriction base="s:string">
				<s:pattern value="[0-9A-Za-z'\- ]*"/>
				<s:maxLength value="60"/>
			</s:restriction>
		</s:simpleType>
	</s:element>
package com.triodos.blueprint.service;

import com.triodos.service.webservices.experian.blueprint.Input;
import com.triodos.service.webservices.experian.blueprint.Output;
import com.triodos.service.webservices.experian.blueprint.OutputRoot;
import com.triodos.service.webservices.experian.blueprint.Root;
import com.triodos.triton.bankaccount.creditcheck.BaProductCreditCheckConstants;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class BlueprintServiceStub implements BlueprintServiceProxy {

  private Output.ExperianRequestDet experianRequestDet = null;
  private Output.SMDecisionData smDecisionData = null;
  private Output.CreditRiskCallRes creditRiskCallRes = null;
  private final Output.Control control;
  private final List<Output.AuthPlusResults> authPlusResults = new ArrayList<>();
  private Output.FirstAppDetails firstAppDetails = null;
  private Output.SecondAppDetails secondAppDetails = null;

  public BlueprintServiceStub() {
    control = new Output.Control();
    control.setExperianReference("YGKMVLHTA6");

    experianRequestDet = new Output.ExperianRequestDet();
    experianRequestDet.setCaseReference("YGKMVLHTA6");
    creditRiskCallRes = new Output.CreditRiskCallRes();
    creditRiskCallRes.setCreditRiskScoreID("00000007");
    creditRiskCallRes.setCreditRiskScore(820);
  }

  @Override
  public OutputRoot interactive(Root root) {
    OutputRoot outputRoot = new OutputRoot();
    Output output = handleErrorCases(root.getInput().getApplicant());

    if (output == null) {
      output = new Output();
      output.setControl(control);
      setupApplicants(root.getInput().getApplicant());
      output.setSMDecisionData(smDecisionData);
      output.setCreditRiskCallRes(creditRiskCallRes);
      output.setFirstAppDetails(firstAppDetails);
      output.setSecondAppDetails(secondAppDetails);
      output.getAuthPlusResults().addAll(authPlusResults);
      output.setExperianRequestDet(experianRequestDet);
    }
    outputRoot.setOutput(output);
    return outputRoot;
  }

  private Output handleErrorCases(List<Input.Applicant> applicant) {
    Output output = null;
    if (!applicant.isEmpty()) {
      output = handleErrors(applicant.get(0).getName().getSurname());
      if (applicant.size() == 2 && output == null) {
        output = handleErrors(applicant.get(1).getName().getSurname());
      }
    }
    return output;
  }

  private Output handleErrors(String lastName) {
    Output output = new Output();
    if (lastName.equals("Error")) {
      output.setError(stubError());
    } else if (lastName.equals("ValidationError")) {
      output.setValidationError(stubValidationError());
    } else if (lastName.equals("SystemError")) {
      output.setSystemError(stubSystemError());
    } else {
      output = null;
    }
    return output;
  }

  private Set<String> getMatchingCodes(String name) {
    final Set<String> referralCodes = new HashSet<>(BaProductCreditCheckConstants.ALL_KNOWN_CODES);
    referralCodes.add("R666");
    return referralCodes.stream()
        .filter(name::contains)
        .collect(Collectors.toSet());
  }

  public void stubAuthPlus(final String au01, final int index, final String indexText) {
    Output.AuthPlusResults.AuthConsumer authConsumer = new Output.AuthPlusResults.AuthConsumer();
    Output.AuthPlusResults.AuthConsumer.DecisionData decisionData = new Output.AuthPlusResults.AuthConsumer.DecisionData();
    decisionData.setAuthPlusDecision(au01);
    decisionData.setAuthIndexText(indexText);
    decisionData.setAuthenticationIndex(index);
    authConsumer.setDecisionData(decisionData);

    Output.AuthPlusResults authPlusResult = new Output.AuthPlusResults();
    authPlusResult.setAuthConsumer(authConsumer);
    authPlusResults.add(authPlusResult);
  }

  private void stubSMDecision(Set<String> codes) {
    Output.SMDecisionData data = new Output.SMDecisionData();
    if (codes.isEmpty()) {
      data.setDecisionCategory("Accept");
      data.setDecisionText("Accept");
    } else {
      data.setDecisionCategory("Pend");
      data.setDecisionText("Pend");
      codes.forEach(code -> {
        Output.SMDecisionData.PolicyRules policyRules = new Output.SMDecisionData.PolicyRules();
        policyRules.setReasonCode(code);
        data.getPolicyRules().add(policyRules);
      });
    }
    smDecisionData = data;
  }

  public void stubFirstApplicant(String foreName, String surname, LocalDate birthDate) {
    Output.FirstAppDetails frstAppDetails = new Output.FirstAppDetails();
    Output.FirstAppDetails.Person.InputName.Name inputName = new Output.FirstAppDetails.Person.InputName.Name();
    Output.FirstAppDetails.Person person = new Output.FirstAppDetails.Person();
    Output.FirstAppDetails.Person.AgreedName agreedName = new Output.FirstAppDetails.Person.AgreedName();
    Output.FirstAppDetails.Person.AgreedName.Name name = new Output.FirstAppDetails.Person.AgreedName.Name();
    inputName.setForename(foreName);
    inputName.setSurname(surname);
    person.setInputName(new Output.FirstAppDetails.Person.InputName());
    person.getInputName().setName(inputName);
    name.setForename(foreName);
    name.setSurname(surname);
    agreedName.setName(name);
    agreedName.setFormattedDOB(birthDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")));
    person.setAgreedName(agreedName);
    frstAppDetails.setPerson(person);
    firstAppDetails = frstAppDetails;
  }

  public void stubSecondApplicant(String foreName, String surname, LocalDate birthDate) {
    Output.SecondAppDetails scndAppDetails = new Output.SecondAppDetails();
    Output.SecondAppDetails.Person.InputName.Name inputName = new Output.SecondAppDetails.Person.InputName.Name();
    Output.SecondAppDetails.Person person = new Output.SecondAppDetails.Person();
    Output.SecondAppDetails.Person.AgreedName agreedName = new Output.SecondAppDetails.Person.AgreedName();
    Output.SecondAppDetails.Person.AgreedName.Name name = new Output.SecondAppDetails.Person.AgreedName.Name();
    inputName.setForename(foreName);
    inputName.setSurname(surname);
    person.setInputName(new Output.SecondAppDetails.Person.InputName());
    person.getInputName().setName(inputName);
    name.setForename(foreName);
    name.setSurname(surname);
    agreedName.setName(name);
    agreedName.setFormattedDOB(birthDate.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")));
    person.setAgreedName(agreedName);
    scndAppDetails.setPerson(person);
    secondAppDetails = scndAppDetails;
  }

  private Output.SystemError stubSystemError() {
    Output.SystemError systemError = new Output.SystemError();
    systemError.setErrorCode("PPEX004");
    systemError.setMessage("Mainframe error creating object");
    systemError.setSeverity("8");
    return systemError;
  }

  private Output.ValidationError stubValidationError() {
    Output.ValidationError validationError = new Output.ValidationError();
    validationError.setErrorCode("PPEX004");
    validationError.setMessage("The Process Engine returned the following error :\n\n    9694-4080-A62B");
    validationError.setSeverity("7");
    return validationError;
  }

  private Output.Error stubError() {
    Output.Error error = new Output.Error();
    error.setErrorCode("PPEX004");
    error.setMessage("The Process Engine returned the following error :\n\n    9694-4080-A62B");
    error.setSeverity("7");
    return error;
  }

  private void setupApplicants(List<Input.Applicant> applicants) {
    Set<String> codes  = new HashSet<>();
    for (Input.Applicant applicant : applicants) {
      Input.Applicant.DateOfBirth dateOfBirth = applicant.getDateOfBirth();
      LocalDate birthDate = LocalDate.of(dateOfBirth.getCCYY(), dateOfBirth.getMM(), dateOfBirth.getDD());
      if (firstAppDetails == null) {
        stubFirstApplicant(applicant.getName().getForename(), applicant.getName().getSurname(), birthDate);
      } else {
        stubSecondApplicant(applicant.getName().getForename(), applicant.getName().getSurname(), birthDate);
      }
      codes.addAll(getMatchingCodes(applicant.getName().getSurname()));
      if (applicant.getName().getForename().toUpperCase().endsWith("NA")) {
        stubAuthPlus("NA00", 30, "The identity supplied has not been Authenticated. You should seek other proofs of identity before dealing with this Applicant");
      } else if (applicant.getName().getForename().toUpperCase().endsWith("RA")) {
        stubAuthPlus("RA00", 30, "The identity supplied has not been Authenticated. You should seek other proofs of identity before dealing with this Applicant");
      } else {
        stubAuthPlus("AU00", 90, "");
      }
    }
    stubSMDecision(codes);
  }
}

Mouse vs keyboard

Transaction authorisation

bypass

Final wording...

Made with Slides.com