client-ui
Version:
Testing implementation of nodeJs Backend, angular frontend, and hopefully in a way that this can be deployed to s3/cloudfront
421 lines (395 loc) • 17.6 kB
JavaScript
/* global config document moduleName */
(function () {
"use strict";
function accountCreationController(stateChangeManager, $state, $stateParams, util, auth, client, loan, requiredDisclosures, $parse, $scope, $timeout, equifax, recaptchaService, loadingService, $q, $window) {
var self = this;
self.requiredDisclosures = requiredDisclosures;
self.prospectData = {};
self.userInput = {};
self.userInput.loan = {};
self.userInput.client = {};
self.userInput.client.personalInformation = {};
self.showLoanPurpose = false;
self.showLoanAmount = false;
self.errorMessage = false;
self.accountCreationAttempts = 0;
self.errorCode = false;
self.patterns = {
name: /^[a-zA-Z\ ]+$/,
address: /^[a-zA-Z0-9\.\,\#\-\/\ ]+$/,
city: /^[a-zA-Z0-9\-\'\.\ ]+$/
};
self.loggedIn = false;
function setWatches() {
var yearlyIncomeGetter = $parse("userInput.loan.incomeSummary.stated.annualAmount");
var monthlyIncomeGetter = $parse("userInput.loan.incomeSummary.stated.monthlyAmount");
$scope.$watch(
function() {
return yearlyIncomeGetter(self);
},
function( newValue ) {
if(util.isNumeric(newValue)) {
var roundedMonthlyAmount = Math.round((newValue / 12) * 100) / 100;
parseInt(monthlyIncomeGetter.assign(self, roundedMonthlyAmount));
}
}
);
$scope.$watch(
function() {
return auth.check();
},
function( newValue ) {
self.loggedIn = newValue;
}
);
$scope.$watch(
function() {
return self.score;
},
function( newValue ) {
self.evaluateScore();
},
true
);
}
self.checkUrlParams = function () {
// fill form fields
self.userInput.loan.loanPurpose = $stateParams.loanPurpose;
self.userInput.loan.requestedAmount = $stateParams.loanAmount;
self.userInput.loan.promoCode = $stateParams.promoCode;
self.userInput.client.referredBy = $stateParams.r;
self.userInput.client.campaignReferral = $stateParams.c;
self.userInput.client.partnerReferral = $stateParams.p;
//could perhaps prefill email using url param...?
//prefer URL params for referrals, but check session storage for fields that might not be present
if ($window.sessionStorage && $window.sessionStorage.getItem('prospect')) {
var sessionProspect = JSON.parse($window.sessionStorage.getItem('prospect'));
if (!self.userInput.client.referredBy) {
self.userInput.client.referredBy = sessionProspect.r;
}
if (!self.userInput.client.campaignReferral) {
self.userInput.client.campaignReferral = sessionProspect.c;
}
if (!self.userInput.client.partnerReferral) {
self.userInput.client.partnerReferral = sessionProspect.p;
}
}
if (self.userInput.loan.requestedAmount) {
self.userInput.loan.requestedAmount = Number($stateParams.loanAmount);
}
// get prospect data
var urlParameters =
{
"loanPurpose": "loanPurpose",
"loanAmount": "loanAmount",
"promoCode": "promoCode",
"r": "referredBy",
"e": "email",
"c": "campaignReferral",
"p": "partnerReferral"
};
for (var urlParameter in urlParameters) {
var urlParameterDisplay = urlParameters[urlParameter];
util.conditionalSet(self.prospectData, urlParameterDisplay, $stateParams[urlParameter]);
}
};
self.validState = function() {
if (config.invalidStates.indexOf(self.userInput.client.personalInformation.state) > -1) {
self.errorMessage = "Unfortunately we are not licensed to lend in your state at this time. Please call us at " + globalConfig.company.phone.short +" with any questions or concerns.";
return false;
} else {
self.errorMessage = "";
return true;
}
};
self.stateSpecificMinimumsMet = function() {
if (config.stateMinimums.hasOwnProperty(self.userInput.client.personalInformation.state) && self.userInput.loan.requestedAmount < config.stateMinimums[self.userInput.client.personalInformation.state]) {
self.errorMessage = "The minimum amount that we can lend to residents of the state of "
+ config.stateNames[self.userInput.client.personalInformation.state] + " is " + util.applyFilter("loanAmount", [config.stateMinimums[self.userInput.client.personalInformation.state]]);
return false;
} else {
self.errorMessage = "";
return true;
}
};
self.formatSsn = function () {
var ssn = self.userInput.client.personalInformation.socialSecurity;
if (ssn) {
if (!ssn.match(/^(\d{3}-?\d{2}-?\d{4}|XXX-XX-XXXX)$/g)) {
self.acform.socialSecurity.$setValidity('isssn', false);
} else {
self.acform.socialSecurity.$setValidity('isssn', true);
}
self.userInput.client.personalInformation.socialSecurity = ssn.replace(/-/g, '');
}
};
self.formSubmit = function () {
self.errorCode = false;
self.errorMessage = false;
self.formatSsn();
if (self.validState()
&& self.stateSpecificMinimumsMet()
&& !self.acform.$invalid) {
self.working = true;
loadingService.open();
if (self.loggedIn) {
self.performUpdate();
} else {
self.accountCreationAttempts = 0;
self.performAccountCreation();
}
}
};
self.performUpdate = function() {
function done(completedCalls) {
if (completedCalls >= 2) {
self.exitToState("loanApplication.loanOptions");
}
}
function error() {
self.exitToState("sorry");
}
var numCalls = 0;
client.updateClient(self.userInput.client)
.then(function (clientObj) {
self.userInput.client = clientObj;
++numCalls;
done(numCalls);
}, function (errorClient) {
error();
});
loan.updateLoan(self.userInput.loan)
.then(function(loanObj) {
self.userInput.loan = loanObj;
++numCalls;
done(numCalls);
}, function(errorLoan) {
error();
});
};
self.checkRecaptcha = function() {
var deferred = $q.defer();
if (self.accountCreationAttempts === 0) {
recaptchaService.getResponse()
.then(function(response) {
self.userInput.client.recaptchaResponse = response;
deferred.resolve(response);
}, function(error) {
deferred.reject(error);
});
} else {
deferred.resolve();
}
return deferred.promise;
};
self.performAccountCreation = function() {
self.checkRecaptcha()
.then(function() {
return equifax.getBlackBox();
}, function(error) {
throw error;
})
.then(function(blackBox) {
self.userInput.client.deviceData = {};
self.userInput.client.deviceData.DeviceFingerprint = blackBox;
return client.createClient(self.userInput);
}, function(error){
throw error;
})
.then(function (data) {
var clientData = data.client;
self.userInput.loan.clientId = clientData.clientId;
auth.performLogin(clientData);
loan.setCurrentLoan(data.loan);
if ($window.sessionStorage) {
$window.sessionStorage.removeItem('prospect');
}
if (data.loan.statusCode < 200) {
throw {
code: "TIMEOUT_CREDIT_PULL"
};
}
}, function (error) {
if(error.mesg && error.mesg.response && error.mesg.response.code){
throw {
code: error.mesg.response.code
};
} else {
throw error;
}
})
.then(function () {
self.exitToState("loanApplication.loanOptions");
}, function (error) {
throw error;
})
.catch(function (error) {
self.handleError(error);
});
};
self.handleError = function(error) {
if(typeof error === "object"
&& error.hasOwnProperty("code")) {
switch(error.code) {
case "ALREADY_LOGGED_IN":
if (auth.check()) {
self.exitToState("loanDashboard.myDashboard");
break;
} else {
auth.logout()
.then(function() {
self.tryAccountCreationAgain();
}, function() {
self.tryAccountCreationAgain();
});
}
break;
case "NO_SESSION":
self.tryAccountCreationAgain();
break;
case "TIMEOUT_CREDIT_PULL":
var checkCreditReportAttempts = 0;
stateChangeManager.doUntilStateChange(function() {
if (++checkCreditReportAttempts < 10) {
self.checkCreditReport();
} else {
self.exitToState("sorry");
}
}, 5000);
break;
case "ALREADY_EXISTS":
self.errorCode = error.code;
self.working = false;
loadingService.close();
break;
case "INVALID_RECAPTCHA":
self.displayErrorMessage("Your recaptcha was invalid. Please check the \"I'm not a robot\" button again, and resubmit. If you continue seeing this error, contact us.");
break;
case "TECHNICAL_ISSUES":
self.displayErrorMessage("We are currently experiencing heavy traffic and are unable to service this request. Please try again later.");
break;
case "INVALID_PROMO_CODE":
self.displayErrorMessage("Invalid promo code");
break;
case "CREATION_TIMEOUT":
self.exitToState("sorry", {reasons: ["CREATION_TIMEOUT"]});
break;
case "SUSPENDED":
self.exitToState("sorry", {reasons: ["SUSPENDED"]});
break;
case "DISPLAY_SORRY_PAGE":
self.exitToState("sorry");
break;
default:
self.displayErrorMessage(error);
break;
}
} else {
self.displayErrorMessage(error);
}
};
self.tryAccountCreationAgain = function() {
if (self.accountCreationAttempts++ < 1) {
client.createProspect(self.prospectData)
.then(function() {
self.performAccountCreation();
}, function() {
self.performAccountCreation();
});
} else {
self.exitToState("sorry");
}
};
self.displayErrorMessage = function(error) {
self.working = false;
loadingService.close();
self.errorMessage = "Unable to create account";
if (typeof error === "object"
&& error.hasOwnProperty("mesg")) {
self.errorMessage = error.mesg;
} else if (typeof error === "string") {
self.errorMessage = error;
} else if (typeof error === "object" && error.hasOwnProperty("code")) {
switch(error.code) {
case "RECAPTCHA_NO_RESPONSE":
self.errorMessage = "Please check the \"I'm not a robot\" button";
break;
}
}
};
self.exitToState = function(state, options) {
if (typeof options === "undefined") {
options = {};
}
self.working = false;
loadingService.close();
$state.go(state, options);
};
self.checkCreditReport = function() {
loan.refreshCurrentLoanFromDB()
.then(function(loanData) {
if (loanData.statusCode >= 200) {
self.exitToState("loanApplication.loanOptions");
}
}, function(errorLoanData) {
self.working = false;
loadingService.close();
});
};
self.evaluateScore = function() {
if (self.hasOwnProperty('score')) {
switch (self.score) {
case false:
self.strwk = "";
break;
case 0:
self.strwk = "Very Weak";
break;
case 25:
self.color = "progress-bar-danger";
self.strwk = "Weak";
break;
case 50:
self.color = "progress-bar-warning";
self.strwk = "Average";
break;
case 75:
self.color = "progress-bar-info";
self.strwk = "Strong";
break;
case 100:
self.color = "progress-bar-success";
self.strwk = "Very Strong";
break;
}
}
};
self.init = function () {
self.working = false;
self.checkUrlParams();
config.enableBootstrapJsElements();
setWatches();
// apply watches
$timeout(function() {
if (self.loggedIn) {
self.userInput.loan = loan.getCurrentLoan();
if (self.userInput.loan.hasOwnProperty("selectedOffer")
&& self.userInput.loan.selectedOffer.hasOwnProperty("amount")) {
self.userInput.loan.requestedAmount = self.userInput.loan.selectedOffer.amount;
}
self.formatInput();
self.userInput.client = client.getClientStore();
} else {
client.createProspect(self.prospectData);
}
});
};
self.formatInput = function() {
if (util.testElement(self.userInput, "loan.incomeSummary.stated.employmentStatus") !== false) {
self.userInput.loan.incomeSummary.stated.employmentStatus = self.userInput.loan.incomeSummary.stated.employmentStatus.toString();
}
};
}
angular.module(moduleName).controller("accountCreationController", accountCreationController);
accountCreationController.$inject = ["stateChangeManager", "$state", "$stateParams", "util", "AuthStateFactory", "client", "loan", "requiredDisclosures", "$parse", "$scope", "$timeout", "equifax", "recaptchaService", "loadingService", "$q", "$window"];
})();