";
}
// }
}
}
return insurance_disp;
}
/**
* @memberof MAR_scenario
*/
function getSummary() {
}
/**
* @memberof MAR_scenario
*/
function getSummaryHoa() {
var hoa_disp = "";
var _s = getScenario_v2();
if (_s.property_type_community_options == "cknow") {
if (_s.hoa_estimate != "") {
hoa_disp += "
HOA est : $"+num(_s.hoa_estimate)+"
";
}
} else {
hoa_disp += mar._txt(_s.property_type_community_options);
}
/**
* if they want us to estimate for them we need to know the square footage and we may not have asked
* this before if they did not ask us to estimate the insurance
*/
if (_s.property_type_community_options == "chigh" || _s.property_type_community_options == "clow") {
// var sqft = square_foot;
// var cnty = county_number(txt("#property_county"));
// var ptype = radio("property_type");
// var copt = property_type_community_options;
if (_s.square_foot != "") {
hoa_disp += ("
size : "+_s.square_foot+" sq. ft
");
}
var _he = getScenario_data("hoi_estimate",false);
if (_he) {
if ("hoa_estimate" in _he) {
hoa_disp += ("
Est : $"+Math.floor(_he.hoa_estimate)+"/y
");
hoa_disp += ("
Est : $"+Math.floor(_he.hoa_estimate/12)+"/m
");
}
}
}
if (_s.loan_type != "purchase") {
if (_s.scenario_hoa != "") {
hoa_disp = "$"+_s.scenario_hoa;
}
}
return hoa_disp;
}
/**
* @memberof MAR_applicants
*
* @param {string} ROLE current role 're','c1','c2','c2','lo'
*
* @returns {int} status -1,0,1,2
*
*/
function getConsents(ROLE) {
let status = false;
let applicantid = false;
let theRealStatus = function(bucket) {
if ("consents" in bucket == false) return -1; // no consents at all
if ("credit" in bucket.consents == false) return 0; // no record of the credit
if ("t4506" in bucket.consents == false) return 0; // ditto t4506
if ("ec" in bucket.consents == false) return 0; // ditto ec
if (bucket.consents.credit == "N") return 0; // credit is N
if (bucket.consents.t4506 == "N") return 0; // ditto 4506t
if (bucket.consents.ec == "N") return 0; // ditto ec
return 1;
}
if (typeof ROLE !== 'undefined' && ROLE == "re") {
status = 9;
} else {
if (ROLE == "cl") applicantid=0;
if (ROLE == "c2") applicantid=1
if (ROLE == "c3") applicantid=2;
if (ROLE == "lo") {
if ("lo" in mar.answers.v2 == false) {
mar.answers.v2.lo = {};
mar.fakesave();
}
if ("consent_soft_bucketid" in mar.answers.v2.lo == true) {
var bucketid = mar.answers.v2.lo.consent_soft_bucketid;
var bucket = mar.answers.v2.buckets[bucketid];
status = theRealStatus(bucket);
}
} else {
if ("consent_soft_bucketid" in mar.answers.v2.applicants[applicantid] == true) {
var bucketid = mar.answers.v2.applicants[applicantid].consent_soft_bucketid;
var bucket = mar.answers.v2.buckets[bucketid];
status = theRealStatus(bucket);
}
}
}
return status;
}
function isPersonalData_complete(n) {
let _applicant = getApplicant_v2(n);
return true;
}
function is_primary_address_not_on_drivers_license(n) {
let _applicant = getApplicant_v2(n);
if ("addresses" in _applicant == false) return `no addresses for applicant ${n}`;
if (_applicant.addresses.length == 0) return `address length is 0 for applicant ${n}`;
let appears_on_drivers_license = 0;
let items = _applicant.addresses;
(function() {
for (var i=0; i < items.length; i++) {
var bucketid = items[i];
if (bucketid in mar.answers.v2.buckets) {
var bucket = mar.answers.v2.buckets[bucketid];
var uuid = bucket.uuid;
var address = bucket.address;
var type = bucket.type;
if (type !== `current`) continue;
if (bucket.appears_on_drivers_license == "Y") appears_on_drivers_license = 1;
if (bucket.appears_on_drivers_license == "N") appears_on_drivers_license = -1;
break
}
}
})();
if (appears_on_drivers_license === 1) return true;
if (appears_on_drivers_license === -1) return false;
return `No primary address found`;
}
function isAddressData_complete(n) {
let _applicant = getApplicant_v2(n);
if ("addresses" in _applicant == false) return `no addresses for applicant ${n}`;
if (_applicant.addresses.length == 0) return `address length is 0 for applicant ${n}`;
let totalmonths = 0;
let appears_on_tax_returns = 0;
let appears_on_drivers_license = 0;
let items = _applicant.addresses;
(function() {
for (var i=0; i < items.length; i++) {
var bucketid = items[i];
if (bucketid in mar.answers.v2.buckets) {
var bucket = mar.answers.v2.buckets[bucketid];
var uuid = bucket.uuid;
var address = bucket.address;
var type = bucket.type;
var years = bucket.years;
var months = bucket.months;
if (bucket.appears_on_tax_returns == "Y") appears_on_tax_returns = 1;
if (bucket.appears_on_drivers_license == "Y") appears_on_drivers_license = 1;
totalmonths += (parseInt(years,10)*12)+parseInt(months);
}
}
})();
if (totalmonths < 24) return `total months less than 24 for applicant ${n}`;
if (appears_on_tax_returns == 0) return `tax return address not found for applicant ${n}`;
if (appears_on_tax_returns == 0) return `tax return address not found for applicant ${n}`;
return true;
}
function isAddressData_complete(n) {
let _applicant = getApplicant_v2(n);
if ("addresses" in _applicant == false) return `no addresses for applicant ${n}`;
if (_applicant.addresses.length == 0) return `address length is 0 for applicant ${n}`;
let totalmonths = 0;
let appears_on_tax_returns = 0;
let appears_on_drivers_license = 0;
let items = _applicant.addresses;
(function() {
for (var i=0; i < items.length; i++) {
var bucketid = items[i];
if (bucketid in mar.answers.v2.buckets) {
var bucket = mar.answers.v2.buckets[bucketid];
var uuid = bucket.uuid;
var address = bucket.address;
var type = bucket.type;
var years = bucket.years;
var months = bucket.months;
if (bucket.appears_on_tax_returns == "Y") appears_on_tax_returns = 1;
if (bucket.appears_on_drivers_license == "Y") appears_on_drivers_license = 1;
totalmonths += (parseInt(years,10)*12)+parseInt(months);
}
}
})();
if (totalmonths < 24) return `total months less than 24 for applicant ${n}`;
if (appears_on_tax_returns == 0) return `tax return address not found for applicant ${n}`;
if (appears_on_tax_returns == 0) return `tax return address not found for applicant ${n}`;
return true;
}
/**
* @memberof MAR_scenario
*/
function isReadyFor4506tStatus() {
return false;
let _numberofapplicants = getApplicants_v2().length;
if (_numberofapplicants == 0) return "no applicants";
for (let i=0; i < _numberofapplicants; i++) {
let pdc = isPersonalData_complete(i);
let adc = isAddressData_complete(i);
if (pdc !== true) return pdc;
if (adc !== true) return adc;
}
return true;
}
/**
* @memberof MAR_scenario
*/
function isLive() {
// if (!context) return false;
// if ("global" in context == false) return false;
// if ("cache" in context.global == false) return false;
// if ("app_status" in context.global.cache == false) return false;
// if ("app_status" in context.global.cache == false) return false;
// if ("appid" in mar.answers == false) return false;
//
// let key = `a${mar.answers.appid}`;
// let status = (key in context.global.cache.app_status == true) ? context.global.cache.app_status[key] : "";
//
// if (status == "L") return true;
return false;
}
/**
* @memberof MAR_scenario
*/
function isUnderContract() {
if (MAR.getOpt(mar, "answers.v2.scenario.loan_type_purchase_options","") == "contract") return true;
let loan_type = MAR.getOpt(mar, "answers.v2.scenario.loan_type","");
if (loan_type !== "" && loan_type !== "purchase") {
return true;
}
return false;
}
/**
* @memberof MAR_scenario
*/
function realtor_options(S) {
//appraisal_information
//loan_calcs_and_docs
//direct_underwriting_report
return MAR.getOpt(mar, `answers.v2.scenario.realtor_permission_${S}`,``);
}
/**
* @memberof MAR_scenario
*/
function isOffering() {
if (mar.answers.v2.scenario.loan_type_purchase_options == "contract") return true;
if (mar.answers.v2.scenario.loan_type_purchase_options == "soon") return true;
return false;
}
/**
* @memberof MAR_scenario
*/
function fixFirstTimeBuyer() {
/**
* set the has ANY applicant owned property
*/
mar.answers.v2.scenario.has_any_applicant_owned_property_in_last_3_years = "N";
for (i=1; i < 4; i++) {
var __property = "has_applicant"+i+"_owned_property_in_last_3_years";
if (__property in mar.answers.v2.scenario && mar.answers.v2.scenario[__property] == "Y"){
mar.answers.v2.scenario.has_any_applicant_owned_property_in_last_3_years = "Y";
}
}
}
/**
* @memberof MAR_scenario
*/
function isFirstTimeBuyer() {
fixFirstTimeBuyer();
return (getScenario_data("has_any_applicant_owned_property_in_last_3_years","N") == "N");
}
/**
* @memberof MAR_scenario
*/
function ownsProperty(n) {
let applicantNum = `${num(n)+1}`;
return (getScenario_data("does_applicant"+applicantNum+"_own_property","") === "Y");
}
/**
* @memberof MAR_scenario
*/
function ownsPrimaryScenario(n) {
let applicantNum = `${num(n)+1}`;
if (getScenario_data("does_applicant"+applicantNum+"_own_property","") !== "Y") return false;
if (getScenario_data("has_applicant"+applicantNum+"_owned_property_in_last_3_years_type","") !== "Y") return true;
return false;
}
/**
* @memberof MAR_scenario
*/
function getFTHB(n) {
let applicantNum = `${num(n)+1}`;
let rv = {};
rv.owned = getScenario_data("has_applicant"+applicantNum+"_owned_property_in_last_3_years","");
rv.otype = getScenario_data("has_applicant"+applicantNum+"_owned_property_in_last_3_years_type","");
rv.ohow = getScenario_data("has_applicant"+applicantNum+"_owned_property_in_last_3_years_how","");
rv.owns = getScenario_data("does_applicant"+applicantNum+"_own_property","");
rv.current = getScenario_data("applicant"+applicantNum+"_ftbh_current",``);
rv.current_rent = getScenario_data("applicant"+applicantNum+"_ftbh_current_rent",``);
rv.current_prim = getScenario_data("applicant"+applicantNum+"_ftbh_current_prim",``);
return rv;
}
/**
* @memberof MAR_scenario
*/
function setFTHB(n, obj) {
let applicantNum = `${num(n)+1}`;
MAR.ifOpt(obj, `owned`, function(v){
setScenario_data("has_applicant"+applicantNum+"_owned_property_in_last_3_years",v);
});
MAR.ifOpt(obj, `otype`, function(v){
setScenario_data("has_applicant"+applicantNum+"_owned_property_in_last_3_years_type",v);
});
MAR.ifOpt(obj, `ohow`, function(v){
setScenario_data("has_applicant"+applicantNum+"_owned_property_in_last_3_years_how",v);
});
MAR.ifOpt(obj, `owns`, function(v){
setScenario_data("does_applicant"+applicantNum+"_own_property",v);
});
MAR.ifOpt(obj, `current`, function(v){
setScenario_data("applicant"+applicantNum+"_ftbh_current",v);
});
MAR.ifOpt(obj, `current_rent`, function(v){
setScenario_data("applicant"+applicantNum+"_ftbh_current_rent",v);
});
MAR.ifOpt(obj, `current_prim`, function(v){
setScenario_data("applicant"+applicantNum+"_ftbh_current_prim",v);
});
}
/**
* @memberof MAR_scenario
*/
function ownsPropertyUnanswered(n) {
let applicantNum = `${num(n)+1}`;
return (getScenario_data("does_applicant"+applicantNum+"_own_property","") === "");
}
/**
* @memberof MAR_scenario
*/
function ownsPrimary(n) {
let a_current = MAR.getApplicantAddressCurrent(n);
if (a_current.length == 0) return false;
if (MAR.getOpt(a_current[0],"use","") === "own") {
return true;
}
return false;
}
/**
* @memberof MAR_scenario
*/
function isMccEligible() {
var pt = getScenario_data("property_type","");
var use = getScenario_data("occupancy_type","");
var secondA = getScenario_data("second_applicant","");
var thirdA = getScenario_data("third_applicant","");
if (use == "occupancy_investment") return false;
if ((pt == "sfr" || pt == "condo") == false) return false;
if (isFirstTimeBuyer() == false) return false;
if (secondA == mar.APPLICANT_TYPE.COBORROWER_NON_RESIDENT) return false;
if (thirdA == mar.APPLICANT_TYPE.COBORROWER_NON_RESIDENT) return false;
return true;
}
/**
* @memberof MAR_scenario
*/
function rec_prog() {
var use = getScenario_data("occupancy_type","");
if (use === mar.OCCUPANCY_INVESTMENT) return "conv";
if (use === mar.OCCUPANCY_2ND_HOME) return "conv";
if (isVaEligible()) return "va";
if (MAR.getOpt(mar.answers.v2.scenario, `has_applicant1_served_in_us_forces`, "") === "") {
if (MAR.getOpt(mar.answers.v2.scenario, `target_va`, "") === "Y") {
return "va"
}
}
let cscore = num(MAR.getOpt(mar.answers.v2, `cscore`, ""));
let rv = "conv";
if (cscore > 100 && cscore < 700) {
rv = "fha";
}
return rv;
}
/**
* @memberof MAR_scenario
*/
function rec_progs() {
var use = getScenario_data("occupancy_type","");
if (isVaEligible() && MAR.is_refi()) {
if (use === mar.OCCUPANCY_INVESTMENT) return ["conv","jumbo","va"];
if (use === mar.OCCUPANCY_2ND_HOME) return ["conv","jumbo","va"];
} else {
if (use === mar.OCCUPANCY_INVESTMENT) return ["conv","jumbo"];
if (use === mar.OCCUPANCY_2ND_HOME) return ["conv","jumbo"];
}
if (isVaEligible()) return ["va","fha","conv","jumbo"];
if (MAR.getOpt(mar.answers.v2.scenario, `has_applicant1_served_in_us_forces`, "") === "") {
if (MAR.getOpt(mar.answers.v2.scenario, `target_va`, "") === "Y") {
return ["va","fha","conv","jumbo"];
}
}
let cscore = num(MAR.getOpt(mar.answers.v2, `cscore`, ""));
let rv = ["conv","fha","jumbo"];
if (cscore > 100 && cscore < 640) {
rv = ["fha"];
}
return rv;
}
/**
* @memberof MAR_scenario
*/
function rec_min_dp() {
let prog = rec_prog();
if (prog === "va") {
return 0;
}
if (MAR.getOpt(mar.answers.v2.scenario, `target_fthb`, "") === "Y") {
return 3;
}
return 5;
}
/**
* @memberof MAR_scenario
*/
function set_target_va(val) {
MAR.setOpt(mar.answers.v2.scenario, `target_va`, val)
}
/**
* @memberof MAR_scenario
*/
function isVaEligible(ans = null, obj = {}) {
/**
* set the has ANY applicant owned property
*/
let answers = (ans === null)? mar.answers : ans;
answers.v2.scenario.is_va_eligible = "N";
for (i=1; i < 4; i++) {
var __eligible = "has_applicant"+i+"_served_in_us_forces";
if (__eligible in answers.v2.scenario && answers.v2.scenario[__eligible] == "Y"){
answers.v2.scenario.is_va_eligible = "Y";
obj.disabled = MAR.getOpt(answers,`v2.scenario.va_disabled${i}`,`N`);
obj.disabled_percentage = MAR.getOpt(answers,`v2.scenario.va_disabled${i}_percentage`,``);
obj.first_time_use = MAR.getOpt(answers,`v2.scenario.vafirst_time_use${i}`,`N`);
obj.employment = MAR.getOpt(answers,`v2.scenario.va_employment${i}`,`regular`);
obj.nofee = MAR.getOpt(answers,`v2.scenario.va_nofee${i}`,`N`);
return true;
}
}
return false;
}
/**
* @memberof MAR_scenario
*/
function isVaPartial(ans = null) {
/**
* set the has ANY applicant owned property
*/
let answers = (ans === null)? mar.answers : ans;
answers.v2.scenario.vaused = 0;
if (isVaEligible() === false) return 0;
for (i=1; i < 4; i++) {
if (MAR.getOpt(answers,`v2.scenario.va_coefull${i}`,``) !== `Y`) continue;
let vaused = MAR.getOptNum(answers,`v2.scenario.va_coeused${i}`,0);
answers.v2.scenario.vaused = vaused;
break;
}
return answers.v2.scenario.vaused;
}
/**
* get Property type
* @memberof MAR_scenario
*/
function getPropertyType_v2(_sc) {
/**
* type of property
*/
if (!mar.STATIC) setStaticVars();
if (arguments.length == 0 || !_sc) {
_sc = mar.answers.v2.scenario;
}
var retval = "";
if (_sc.property_type == mar.PROPERTY_TYPE_SFR) retval = "sfr";
if (_sc.property_type == mar.PROPERTY_TYPE_CONDO) retval = "condo";
if (_sc.property_type == mar.PROPERTY_TYPE_DUPLEX) retval = "2unit";
if (_sc.property_type == mar.PROPERTY_TYPE_TRIPLEX) retval = "3unit";
if (_sc.property_type == mar.PROPERTY_TYPE_FOURPLEX) retval = "4unit";
if (_sc.property_type == mar.PROPERTY_TYPE_OTHER) retval = "Other";
return retval;
}
/**
* get Property type
* @memberof MAR_scenario
*/
function getCounty(_sc) {
/**
* type of property
*/
if (!mar.STATIC) setStaticVars();
if (arguments.length == 0 || !_sc) {
_sc = mar.answers.v2.scenario;
}
return MAR.getOpt(_sc, `property_county`,``);
}
/**
* get the type of loan
* @memberof MAR_scenario
*/
function getLoanType_v2(_sc) {
return _sc.loan_type;
}
/**
* refinance options
* @memberof MAR_scenario
*/
function getRefi_v2(_sc) {
if (!mar.STATIC) setStaticVars();
var retval = {
loan_type_refinance_takehome_value : 0,
refi_home_insurance_cost : 0,
flood_estimate : 0
}
if (getLoanType(_sc) && getLoanType(_sc) == mar.LOAN_TYPE_REFINANCE) {
retval = {
loan_type_refinance_takehome_value : num(_sc.loan_type_refinance_takehome_value),
refi_home_insurance_cost : num(_sc.refi_home_insurance_cost),
flood_estimate : num(_sc.flood_estimate)
};
}
return retval;
}
/**
* @namespace MAR.math
*/
var math = (function(){
/**
* @memberof MAR.math
*/
function PMT(rate, nperiod, pv, fv, type) {
// http://stackoverflow.com/questions/5294074/pmt-function-in-javascript
// rate - monthly interest e.g. 0.08 /12
// period in months
// pv - start value
// fv - end value
// 0 or 1
if (!fv) fv = 0;
if (!type) type = 0;
if (rate == 0) return -(pv + fv)/nperiod;
var pvif = Math.pow(1 + rate, nperiod);
var pmt = rate / (pvif - 1) * -(pv * pvif + fv);
if (type == 1) {
pmt /= (1 + rate);
};
return pmt;
}
/**
* @memberof MAR.math
*/
function middleCreditScore(arr) {
if (arr.length == 0) return 0;
if (arr.length == 1) return arr[0];
if (arr.length == 3) return arr.sort()[1];//Math.floor(max(min(arr[0],arr[1]), min(max(arr[0],arr[1]),arr[2]))); // thanks https://stackoverflow.com/questions/1582356/fastest-way-of-finding-the-middle-value-of-a-triple
/**
* fall back to average
*/
let sum = arr.reduce(function(a, b) { return a + b; });
let avg = sum / arr.length;
return Math.floor(avg);
}
function lowestCreditScore(arr) {
let lowest = false;
for (let i=0; i < arr.length; i++) {
if (lowest === false || arr[i] < lowest) lowest = arr[i];
}
return lowest;
}
function lowest() {
let rv = false;
for (let i=0; i < arguments.length; i++) {
if (rv === false || arguments[i] < rv) rv = arguments[i];
}
return rv;
}
function low(arr) {
let lowest = false;
for (let i=0; i < arr.length; i++) {
if (lowest === false || arr[i] < lowest) lowest = arr[i];
}
return lowest;
}
function high(arr) {
let highest = false;
for (let i=0; i < arr.length; i++) {
if (highest === false || arr[i] > highest) highest = arr[i];
}
return highest;
}
function dp(num, places) {
return Math.round(num * Math.pow(10,places)) / Math.pow(10,places);
}
return {
PMT : PMT,
low : low,
high : high,
dp : dp,
lowest : lowest,
lowestCreditScore : lowestCreditScore,
middleCreditScore : middleCreditScore,
___id : "math"
}
})();
/**
* @memberof MAR
*/
var addVariableCLosingCostsToApproximate_costs_t = {
Insurance_Factor : 0,
Property_Tax : 0,
HOA_SFR_nolux_pm : 0,
HOA_SFR_Lux_pm : 0,
HOA_Cond_lux_pm : 0,
HOA_Cond_nolux_pm : 0,
sqft_int : 0
}
/**
* @memberof MAR
* -- never called , depreciated --
*/
function addVariableCLosingCostsToApproximate_costs(obj /*addVariableCLosingCostsToApproximate_costs_t*/) {
/**
*
* from HOI HOA Matrix
* ===================
* Insurance_Factor 2.9
* Property_Tax 0.009
* HOA_SFR_nolux_pm 0.06
* HOA_SFR_Lux_pm 0.4
* HOA_Cond_lux_pm 0.85
* HOA_Cond_nolux_pm 0.4
*
*/
}
//additional_lender_credit
let RS = {
processing_fee : { lbl : "Processing fee", filter : [""], apr : false, qm : true, cols : [""] },
underwriting_fee : { lbl : "Underwriting fee", filter : [""], apr : false, qm : true, cols : [""] },
additional_lender_credit: { lbl : "Additional lender credit", filter : [""], apr : false, qm : true, cols : [""] , template : `hidden` },
A : { lbl : "Appraisal fee", filter : ["",""], apr : true, qm : true, cols : ["SFR/Condo","other"] , same_as : `appraisal_fee` },
B : { lbl : "Condo Questionairre", filter : [""], apr : false, qm : true, cols : ["If Condo"] , same_as : `condo_questionairre` },
RRA : { lbl : "Rent Roll Analysis", filter : [""], apr : false, qm : true, cols : ["If Needed"] , same_as : `rent_roll_analysis`},
credit_report_key : { lbl : "Credit report fee", filter : [""], apr : true, qm : true, cols : [""] },
E : { lbl : "Title search", filter : ["p"], apr : false, qm : true, cols : ["Purchase"] , same_as : `title_search`},
various_endorsements : { lbl : "Various endorsements", filter : [""], apr : false, qm : true, cols : [""] },
title_settlement_fee : { lbl : "Title settlement fee", filter : ["p","r"], apr : false, qm : true, cols : ["Purchase", "Refi"] },
C : { lbl : "Mortgage policy (x loan)", filter : ["p","r"], apr : true, qm : true, cols : ["Purchase","Refi"] , same_as : `mortgage_policy`},
F : { lbl : "Owner title ins", filter : ["p"], apr : true, qm : true, cols : ["Purchase"] , same_as : `owner_title_insurance`},
buy_agent_fee : { lbl : "Buyers agent fee", filter : [""], apr : true, qm : true, cols : ["Purchase"] },
bp_commission : { lbl : "Origination fee", filter : [""], apr : true, qm : true, cols : [""] },
recording_fee : { lbl : "Recording fee", filter : [""], apr : true, qm : true, cols : [""] },
D : { lbl : "Survey", filter : ["r"], apr : true, qm : true, cols : ["If not Condo"] , same_as : `survey`},
G : { lbl : "Fl Doc Stamps", filter : ["p","r"], apr : false, qm : true, cols : ["N x loan"] , same_as : `fl_doc_stamps`},
H : { lbl : "State taxes", filter : ["p"], apr : false, qm : true, cols : ["(Purch) N x loan"] , same_as : `state_taxes`}
}
//owner_title_insurance
/**
* default values , only called internally
*/
let RDEF = {
processing_fee : [625],
underwriting_fee : [799],
additional_lender_credit : [0],
A : [475,625], // appraisal fee
B : [350], // condo questionairre
RRA : [150], // Rent Roll Analysis
credit_report_key : [65],
E : [172], // title search
various_endorsements : [50],
title_settlement_fee : [495,859],
C : [0.00585,0.00330], // Mortgage policy
F : [172], // Owner title Ins
buy_agent_fee : [0],
bp_commission : [0],
recording_fee : [152],
D : [350], // Survey
G : [0.0035,0.0035], // Fl Doc Stamps
H : [0.002] // State Taxes
};
function getRatesheet() {
return {
RS : RS,
R : RDEF
}
}
function get_estimated_closing_date( ans = false) {
if (ans !== false) {
mar.answers = ans;
}
let Moment = (typeof context === "object") ? context.global.moment : moment;
let start_d = moment();
if (MAR.application.isRefi()) {
let closing_d = (function(){
let plus_50 = start_d.clone().add(50, "day");
if (plus_50.date() > 15) {
plus_50.date(15);
} else {
plus_50.subtract(1, "month")
plus_50.date(15);
}
return plus_50;
})();
return closing_d.format("YYYY-MM-DD");
} else {
let closing_d = (function(){
let timeframe = getScenario_data("loan_type_purchase_options",``);
if (timeframe === `contract`) {
let plus_50 = start_d.clone().add(1, "months");
return plus_50;
}
else if (timeframe === `soon`) {
let plus_50 = start_d.clone().add(30, "days");
return plus_50;
}
else if (timeframe === `one_month`) {
let plus_50 = start_d.clone().add(60, "days");
return plus_50;
}
else if (timeframe === `three_months`) {
let plus_50 = start_d.clone().add(90, "days");
return plus_50;
}
else if (timeframe === `just_looking`) {
let plus_50 = start_d.clone().add(90, "days");
return plus_50;
}
else {
let plus_50 = start_d.clone().add(30, "days");
return plus_50;
}
})();
return closing_d.format("YYYY-MM-DD");
}
}
/**
* @memberof MAR
*
* called from
* _universal.js
* libs/durunner.app.js
* libs/durunner.api.chatbot.js
*
*/
function getApproximateClosingCosts(max_loan, final_ufmi, buydown_points, ptype_str, loantype_str = ``, hoipm_int, hoapm_int, taxpm_int, rate_dbl,dbg_arr, {
hoi_due_date,
refi_date_now,
closing_date = false,
branch,
prog,
ratesheet,
over_ratesheet,
refi_mort_rate,
refi_mort_terms,
refi_mort_pmtinc,
refi_mort_escrow,
refi_mort_sdate,
buy_agent_val = 0,
buy_agent_perc = 0,
comp_type = `L`,
comp_perc = 2,
comp_fee = 0,
tax_due,
propertyvalue = 0,
opt_rra_needed = ``, // '' or true or false
adjusters = {}
}) {
let Moment = (typeof context === "object") ? context.global.moment : moment;
if (arguments.length > 3) {
/* -- take it from the variales -- */
var property_type = ptype_str;
var loan_type = ((typeof loantype_str === `string` && loantype_str.toLowerCase().indexOf("refi") > -1) || (typeof loantype_str === `string` && loantype_str.toLowerCase().indexOf("cashout") > -1)) ? mar.LOAN_TYPE_REFINANCE : mar.LOAN_TYPE_PURCHASE;
} else {
/* -- take it from the answers -- */
var property_type = getPropertyType_v2(mar.answers.v2.scenario);
var loan_type = getLoanType_v2(mar.answers.v2.scenario);
}
var dbg = (arguments.length > 9 && dbg_arr !== false);
if (dbg) dbg_arr.push(`gacc start`);
let trace = false;
if (trace) console.log(`ACC ${loantype_str} -> ${loan_type}`);
let R = JSON.parse(JSON.stringify(RDEF)); /* -- these are the default values for the standard items -- */
if (typeof ratesheet === "object") {
for (let x in ratesheet) {
if (typeof ratesheet[x] === "object" && ratesheet[x].length === R[x].length) {
R[x] = ratesheet[x];
if (trace) console.log(`RS replace ${x} with ${JSON.stringify(ratesheet[x])}`); /* -- the ratesheet values that would overview the R[] -- */
}
}
}
if (typeof over_ratesheet === "object") {
for (let x in over_ratesheet) {
if (typeof over_ratesheet[x] === "object" && over_ratesheet[x].length === R[x].length) {
for (let j=0; j < R[x].length; j++) {
if (typeof over_ratesheet[x][j] === "number") {
R[x][j] = over_ratesheet[x][j];
if (trace) console.log(`RS OVER replace ${x}[${j}] with ${JSON.stringify(over_ratesheet[x][j])}`);
} else {
if (trace) console.log(`RS OVER NOT replace ${x}[${j}] with ${JSON.stringify(over_ratesheet[x][j])} type ${typeof over_ratesheet[x][j]}`);
}
}
}
}
}
var hoipm = (arguments.length > 5) ? hoipm_int : 0;
var hoapm = (arguments.length > 6) ? hoapm_int : 0;
var taxpm = (arguments.length > 7) ? taxpm_int : 0;
var rate = (arguments.length > 8) ? rate_dbl : 0.06;
let escrows = {};
if (arguments.length < 3 || !buydown_points) buydown_points = 0;
var A = (property_type == mar.PROPERTY_TYPE_SFR || property_type == mar.PROPERTY_TYPE_CONDO) ? R.A[0] : R.A[1]; /* if fha +$25 */
/*
fha diff
*/
var B = (property_type == mar.PROPERTY_TYPE_CONDO) ? R.B[0] : 0; /* fixed */
var C = (loan_type !== mar.LOAN_TYPE_REFINANCE) ? (R.C[0] * max_loan) : (R.C[1] * max_loan); /* todo not sure, for 2 states !! */
// var D = (loan_type !== mar.LOAN_TYPE_REFINANCE && property_type != mar.PROPERTY_TYPE_CONDO) ? R.D[0] : 0;
var D = (loan_type === mar.LOAN_TYPE_REFINANCE && property_type != mar.PROPERTY_TYPE_CONDO) ? R.D[0] : 0;
/*
if you are buying a condo then 350
*/
var E = (loan_type == mar.LOAN_TYPE_REFINANCE) ? 0 : R.E[0]; /* only if purchase , add 125 */
/*
if loan amount < 100k then loan /1000 * 5.75
if < 1m then loan /100 * 5
otherwise 2.5
** this is C becasue it is a refi
refi & have copy of old owners policy
if loan amount < 100k then loan /1000 * 3.3
if < 1m then loan /100 * 3
otherwise 2
*/
escrows.tax_months = 4;
escrows.hoi_months = 2;
escrows.int_days = 15;
if (typeof closing_date === "string" && closing_date.trim().length > 0) {
let closing_d = moment(new Date(closing_date));
escrows.day_of_month = closing_d.date();
escrows.days_in_month = closing_d.daysInMonth();
escrows.int_days = (escrows.days_in_month - escrows.day_of_month);
if (escrows.day_of_month < 3) {
escrows.int_days = (escrows.day_of_month*-1);
escrows.tax_months = 3;
escrows.hoi_months = 1;
}
}
(function adjust_for_uwm() {
escrows.hoi_months++;
escrows.tax_months++;
escrows.int_days++;
})();
escrows.auto_tax_months = escrows.tax_months;
escrows.auto_hoi_months = escrows.hoi_months;
escrows.auto_int_days = escrows.int_days;
(function overrides() {
MAR.ifOpt(adjusters, `rq_tax_months`, function(v) {
if (v !== ``) {
escrows.tax_months = num(v);
}
});
MAR.ifOpt(adjusters, `rq_hoi_months`, function(v) {
if (v !== ``) {
escrows.hoi_months = num(v);
}
});
MAR.ifOpt(adjusters, `rq_int_days`, function(v) {
if (v !== ``) {
escrows.int_days = num(v);
}
});
})();
var F = (loan_type !== mar.LOAN_TYPE_REFINANCE) ? R.F[0] : 0; /* todo per county */
var G = (loan_type !== mar.LOAN_TYPE_REFINANCE) ? (R.G[0] * max_loan) : (R.G[1] * max_loan) ; /* todo per state */
// var H = (loan_type !== mar.LOAN_TYPE_REFINANCE) ? (R.H[0] * max_loan) : 0 ; /* todo per state */
var H = (R.H[0] * max_loan); /* todo per state */
var I = Math.round(taxpm * escrows.tax_months);
var J = Math.round(hoipm * escrows.hoi_months);
var JJ = (loan_type === mar.LOAN_TYPE_PURCHASE) ? Math.round(hoipm * 12) : 0; /* first year ins premium to prepaids */
var K = Math.round(((max_loan * rate) / 365) * escrows.int_days);
var RRA = 0;
if (opt_rra_needed === `` && loan_type !== mar.LOAN_TYPE_REFINANCE) {
RRA = R.RRA[0];
} else if (opt_rra_needed === `y` || opt_rra_needed === `Y` || opt_rra_needed === true) {
RRA = R.RRA[0];
}
let BAF = (loan_type === mar.LOAN_TYPE_PURCHASE) ? Math.round((num(propertyvalue) * num(buy_agent_perc))/100 + num(buy_agent_val)) : 0;
let BPC = (comp_type !== `B`) ? 0 : Math.round(((num(comp_perc) * num(max_loan)) / 100) + num(comp_fee)); // Borrower Paid Commission
if (loan_type == mar.LOAN_TYPE_REFINANCE) {
//hoi_due_date
// let Moment = (typeof context === "object") ? context.global.moment : moment;
let start_d = (typeof refi_date_now === "string") ? moment(new Date(refi_date_now)) : moment();
let closing_d = (function(){
if (typeof closing_date === "string" && closing_date.trim().length > 0) {
return moment(new Date(closing_date));
}
let plus_50 = start_d.clone().add(50, "day");
if (plus_50.date() > 15) {
plus_50.date(15);
} else {
plus_50.subtract(1, "month")
plus_50.date(15);
}
return plus_50;
})();
escrows.day_of_month = closing_d.date(); // e.g. 18
escrows.days_in_month = closing_d.daysInMonth();
escrows.start_d = start_d.format("YYYY-MM-DD");
escrows.closing_d = closing_d.format("YYYY-MM-DD");
let firstpay_d = closing_d.clone().add(2, "month").date(1);
if (escrows.day_of_month < 3) {
escrows.int_days = (closing_d.date()*-1); // escrows.days_in_month - closing_d.date(); /* e.g. 31 - 18 */
firstpay_d = closing_d.clone().add(1, "month").date(1);
// bump up the date maybe
} else {
escrows.int_days = escrows.days_in_month - closing_d.date(); /* e.g. 31 - 18 */
}
escrows.firstpay_d = firstpay_d.format("YYYY-MM-DD");
K = Math.round(((max_loan * rate) / 365) * escrows.int_days); // per day rate
if (trace) console.log(`ACC start_d ${start_d} -> closing_d ${closing_d} -> firstpay_d ${firstpay_d} -> hoi_due_date ${hoi_due_date} -> ${typeof hoi_due_date}`);
if (typeof hoi_due_date === "string") {
let hoi_dd = moment(new Date(hoi_due_date));
let now_d = moment();
if (hoi_dd.isBefore(firstpay_d)) {
hoi_dd.add(1, "year");
}
let diff_mo = hoi_dd.diff(firstpay_d, "months");
let missing_payments = (12 - diff_mo);
if (trace) console.log(`ACC hoi_dd ${hoi_dd} -> diff_mo ${diff_mo} -> missing_payments ${missing_payments} -> hoipm ${hoipm}`);
J = Math.round(hoipm * missing_payments);
escrows.hoi_dd = hoi_dd.format("YYYY-MM-DD");
escrows.hoi_months = missing_payments;
}
(function() {
let tax_dd = moment().month(10).day(1);
if (typeof tax_due === "string" && tax_due.trim() !== "") {
tax_dd = moment(new Date(tax_due));
}
let now_d = moment();
let closing_d = moment(escrows.closing_d);
if (tax_dd.isBefore(firstpay_d)) {
tax_dd.add(1, "year");
}
let diff_mo = tax_dd.diff(firstpay_d, "months",true);
let missing_payments = (12 - Math.abs(Math.round(diff_mo)));
escrows.tax_dbg = (`ACC IF1 closing_d ${closing_d} / firstpay_d ${firstpay_d} / tax_dd ${tax_dd} -> diff_mo ${diff_mo} -> missing_payments ${missing_payments}`);
// let missing_payments = 0;
// if (tax_dd.isBefore(closing_d)) {
// // paid off before closing , just need months uo to 1st payment
// let diff_mo = closing_d.diff(firstpay_d, "months",true);
// missing_payments = Math.abs(Math.round(diff_mo));
// escrows.tax_dbg = (`ACC IF1 closing_d ${closing_d} / firstpay_d ${firstpay_d} / tax_dd ${tax_dd} -> diff_mo ${diff_mo} -> missing_payments ${missing_payments}`);
// }
// else if (tax_dd.isBefore(firstpay_d)) {
// // paid off before closing , just need months uo to 1st payment
// let diff_mo = tax_dd.diff(firstpay_d, "months",true);
// missing_payments = 12 + Math.abs(Math.round(diff_mo));
// escrows.tax_dbg = (`ACC IF2 tax_dd ${tax_dd} / firstpay_d ${firstpay_d} / tax_dd ${tax_dd} -> diff_mo ${diff_mo} -> missing_payments ${missing_payments}`);
// } else {
// let diff_mo = tax_dd.diff(firstpay_d, "months",true);
// missing_payments = (12 - Math.abs(Math.round(diff_mo)));
// escrows.tax_dbg = (`ACC IF3 tax_dd ${tax_dd} / firstpay_d ${firstpay_d} / tax_dd ${tax_dd} -> diff_mo ${diff_mo} -> missing_payments ${missing_payments}`);
// }
I = Math.round(taxpm * missing_payments);
escrows.tax_dd = tax_dd.format("YYYY-MM-DD");
escrows.tax_months = missing_payments;
})();
}
(function alf(){
if (dbg) dbg_arr.push(`alf-start`);
let alf = MAR.getOpt(R, "additional_lender_credit.0",0);
if (dbg) dbg_arr.push(`alf[${alf}]`);
})();
var costs = {
"processing_fee" : R.processing_fee[0], /* fixed (per branch) was 500*/
"underwriting_fee" : R.underwriting_fee[0], /* fixed (per branch) was 999 */
//"doc_prep_fee" : 0,
"appraisal_fee" : (A),
"credit_report_key" : R.credit_report_key[0],// 35 or 70 /* fixed (per company) */
"buydown_points" : (buydown_points) > 0 ? buydown_points : 0, /* need full rate sheet */
"buydown_lender_credit" : (buydown_points) < 0 ? buydown_points : 0,
"flood_certification_fee" : 00, /* fixed (per comapny) was 16 */
"tax_service" : 00, /* fixed (per comapny) was 80*/
"re_inspection_fee" : 0, /* fixed (per comapny) */
"condo_questionairre" : (B),
"rent_roll_analysis" : (RRA),
"title_review_fee" : 0,
"title_search" : (E), /* depends on title company, if you use matt lerner */
"additional_lender_credit" : MAR.getOpt(R, "additional_lender_credit.0",0),
"various_endorsements" : R.various_endorsements[0], /* depends on title company */
"title_settlement_fee" : (loan_type !== mar.LOAN_TYPE_REFINANCE) ? R.title_settlement_fee[0] : R.title_settlement_fee[1], /* 595 refi, 495 pur*/ /* depends on title company */
"mortgage_policy" : 0,
"owner_title_insurance" : (F),
"recording_fee" : R.recording_fee[0], /* fixed (maybe per state) */
"buy_agent_fee" : BAF,
"bp_commission" : BPC,
"endorsements" : 0,
"fl_doc_stamps" : 0, /* warning in 95% of cases the seller pays this amount*/
"state_taxes" : 0, /* combine the last 2 */
"mcc_class" : (0), /* not sure , if ftb then 250 */
"survey" : (D), /* fixed */
"pest_inspection" : 0, /* non mandatory */
"ad_valoram_taxes" : 0,
"upfront_mi" : final_ufmi,
// "upfront_mi" : ((prog !== `fha`) ? final_ufmi : 0),
"end" : 0, /* paid outside of closing cost */
"taxes_escrow" : I, /* put 4/12 of average house size in county*/
"insurance_escrow" : J, /* put 2/12 of average house size in county*/
"home_insurance_escrow" : JJ,
"flood_insurance_escrow" : 0,
"daily_interest" : 0 /* put 1/2 mo of interest on purchase price 6% of loan amount / 365 * 15*/
};
MAR.ifOpt(adjusters, "rq_custom_table", function(v){
for (let i=0; i < v.length; i++) {
let itm = v[i];
let calctype = MAR.getOpt(itm, `calctype`,``);
if (calctype === `pla`) {
let perc = MAR.getOptNum(itm, `perc`,0);
itm.val = Math.round(num(max_loan) * num(perc) / 100);
}
if (calctype === `ppp`) {
let perc = MAR.getOptNum(itm, `perc`,0);
itm.val = Math.round(num(propertyvalue) * num(perc) / 100);
}
if (calctype === `pdi`) {
let perc = MAR.getOptNum(itm, `perc`,0);
itm.val = Math.round((num(propertyvalue) - num(max_loan)) * num(perc) / 100);
}
if (calctype === `pp`) {
let months = MAR.getOptNum(itm, `months`,0);
let monthly = MAR.getOptNum(itm, `monthly`,0);
itm.val = Math.round(num(months) * num(monthly));
}
if (num(itm.val) !== 0) {
let lbl = "_"+itm.lbl.replace(/ /g,"_");
costs[lbl] = num(itm.val);
}
}
});
var fixedcosts = 0;
for (let x in costs) {
fixedcosts += costs[x];
}
costs.mortgage_policy = C;
costs.fl_doc_stamps = G;
costs.state_taxes = H;
costs.daily_interest = K;
var totalcost = 0;
for (let x in costs) {
totalcost += num(costs[x]);
if (dbg && costs[x] > 0) dbg_arr.push(`{${x}=${costs[x]} (${typeof costs[x]}) (total ${totalcost})}`)
}
return {
costs : costs,
total : totalcost,
total10 : totalcost*1.35,
ufmi_fin : ((prog === `fha`) ? final_ufmi : 0),
fixed : fixedcosts,
variable : (totalcost -fixedcosts) / max_loan,
escrows : escrows,
loan_amount : max_loan,
points : buydown_points
}
}
/**
* @memberof MAR
*/
function getNiceMIname(MI) {
if (MI == "bpmi_rad_more20") return "BPMI";
if (MI == "split_uphigh_rad") return "UPHI";
if (MI == "split_uplow_rad") return "UPLO";
if (MI == "ufmi_more20") return "UFMI";
if (MI == "bpmi_FHA") return "BPMI";
return MI
}
/**
* application Navigation
* @namespace MAR.declarations
*/
var applicationNavObj = (function(){
let orderTable = [
"intro",
"general",
"timeframe",
"scenario",
"property",
"estimate",
"realtorinfo",
"assets",
"personalinfo",
"income",
"liabilities",
"homework"
];
function setHadToDoAll() {
for (let i=0; i < orderTable.length; i++) {
let section = orderTable[i];
setScenario_data(`_sec_${section}_verified`, "N");
}
for (let x in mar.answers.v2.scenario) {
if (x.startsWith("_page_") && x.endsWith("_verified")) {
delete mar.answers.v2.scenario[x];
}
}
}
function loanWasImported() {
return (getScenario_data("__application_imported_from_encompass","N") === "Y");
}
function loanWasImportedAndNotVerified() {
if (getScenario_data("__application_imported_from_encompass","N") !== "Y") return false;
if (getScenario_data("__application_imported_from_encompass_needs_verification","N") === "Y") return true;
return false;
}
function loanWasImportedAndHasUnverifiedIncomeChange() {
if (getScenario_data("__application_imported_from_encompass_needs_verification_incomechange","N") === "Y") return true;
return false;
}
function loanWasNotImportedAndNotSubmitted() {
if (getScenario_data("__application_imported_from_encompass","N") === "Y") return false;
return (getScenario_data("__application_submitted","N") !== "Y");
}
function loanWasSubmitted() {
if (loanWasImported() === true) {
return !loanWasImportedAndNotVerified();
} else {
return !loanWasNotImportedAndNotSubmitted();
}
}
function pageVerified(pagename,YN) {
if (!loanWasImported()) return true;
if (arguments.length > 1) {
setScenario_data(`_page_${pagename}_verified`, YN);
return;
}
return (getScenario_data(`_page_${pagename}_verified`, "N") === "Y");
}
let verifictions = {};
verifictions.sectionIsVerified_intro = function() {
return true;
}
verifictions.sectionIsVerified_general = function() {
if (!pageVerified("encompass-intro")) return "#import-encompass-intro";
return true;
}
verifictions.sectionIsVerified_timeframe = function() {
if (!pageVerified("timeframe")) { debugger; return "#scenario-timeframe";}
return true;
}
verifictions.sectionIsVerified_scenario = function() {
for (var i=0; i < mar.answers.v2.applicants.length; i++) {
if (!pageVerified(`creditscore.${i}`)) return `#scenario-creditscore.${i}`;
}
return true;
}
verifictions.sectionIsVerified_property = function() {
return true;
}
verifictions.sectionIsVerified_estimate = function() {
return true;
}
verifictions.sectionIsVerified_realtorinfo = function() {
return true;
}
verifictions.sectionIsVerified_assets = function() {
return true;
}
verifictions.sectionIsVerified_personalinfo = function() {
return true;
}
verifictions.sectionIsVerified_income = function() {
return true;
}
verifictions.sectionIsVerified_liabilities = function() {
return true;
}
verifictions.sectionIsVerified_homework = function() {
return true;
}
function sectionIsVerified(section) {
if (loanWasImported() == false) return true;
// if (getScenario_data(`_sec_${section}_verified`, "Y") === "Y") {
// return true;
// }
if (`sectionIsVerified_${section}` in verifictions == true) {
let isverified = verifictions[`sectionIsVerified_${section}`]();
if (isverified !== true) return isverified;
// setScenario_data(`_sec_${section}_verified`, "Y");
mar.fakesave();
}
return true;
}
function hasEnteredReatorInfo(answers) {
if (getScenario_data("loan_type" ,"purchase",answers) !== "purchase") return true;
if (getScenario_data("have_own_realtor" ,false,answers) == false) return "#scenario-realtor";
if (getScenario_data("have_own_realtor" ,false,answers) == "N") return true;
if (getScenario_data("realtor_name" ,false,answers) == false) return "#scenario-realtor";
return true
}
function hasEnteredAssets() {
//if (getScenario_data("__application_imported_from_encompass_purpose" ,"").indexOf("Refinance") > -1) return true
let _assets = getAssets_v2();
// if (_assets.has_unverified_items === true) return "#assets-choice";
if (_assets.total == 0 && MAR.is_refi() === false) return "#assets-choice";
// if (isRefi() === false && _assets.total == 0) return "#assets-choice";
return true;
}
function hasEnteredAssetsEver() {
//if (getScenario_data("__application_imported_from_encompass_purpose" ,"").indexOf("Refinance") > -1) return true
let _assets = getAssets_v2();
// if (_assets.has_unverified_items === true) return "#assets-choice";
if (_assets.total == 0 && MAR.is_refi() === false) return "#assets-choice";
if (getScenario_data("__assets_passed","") !== "Y") return "#assets-choice";
return true;
}
function missingFields() {
let applicantLength = getApplicants_v2().length;
let missingfields = [];
for (let i=0; i < applicantLength; i++) {
if (MAR.getOpt(getApplicantBucket(i), "ty" , "") === "") return `#scenario-personaldata.${i}`;
let adc = MAR.getApplicantAddressCurrent(i)[0];
if (MAR.getOpt(adc, "appears_on_drivers_license" , "") === "") return `#scenario-addresshistory.${i}.0`;
if (MAR.getOpt(adc, "appears_on_tax_returns" , "") === "") return `#scenario-addresshistory.${i}.0`;
if (MAR.getOpt(adc, "years" , "") === "") return `#scenario-addresshistory.${i}.0`;
if (MAR.getOpt(adc, "months" , "") === "") return `#scenario-addresshistory.${i}.0`;
}
}
function hasEnteredPersonalInfoByApplicant(applicantnum) {
let _scenario = getScenario_v2();
let i = applicantnum;
let sta = "";
sta = sup_data_status(`/applicants/address/_${i}/sup-data/personal-data`);
if (sta < 1) return `#scenario-personaldata.${i}`;
sta = sup_data_status(`/applicants/address/_${i}/sup-data/address-history`);
if (sta < 1) return `#scenario-addresshistory.${i}`;
return true;
}
function hasEnteredPersonalInfo(ROLE) {
let _scenario = getScenario_v2();
let _names = getApplicantsNames_v2();
let _applicantcount = _names.length;
for (let i=0; i < _applicantcount; i++) {
let sta = "";
sta = sup_data_status(`/applicants/address/_${i}/sup-data/personal-data`);
if (sta < 1) console.error("cfc sup data 1",sup_data.lasterror);
if (sta < 1) return `#scenario-personaldata.${i}`;
sta = sup_data_status(`/applicants/address/_${i}/sup-data/address-history`);
if (sta < 1) console.error("cfc sup data 2",sup_data.lasterror);
if (sta < 1) return `#scenario-addresshistory.${i}`;
if (i == 0) {
if (arguments.length == 0) {
ROLE = __ROLE;
}
let c = 0;
// let c = MAR.getConsents(ROLE);
if (getScenario_data(`authorizations-credit-ed_${i}_passed`,"N") != "Y") c = 0; else c = 1;
if (c == 0) return `#authorizations-credit-ed.${i}`;
}
}
return true;
}
function hasEnteredIncomeByApplicant(applicantnum, include_verfied_check = true) {
let i = applicantnum;
let _scenario = getScenario_v2();
getIncome_v2();
if (mar.answers.v2.income.length < (applicantnum+1)) return `#income-how.${i}`;
if ("items" in mar.answers.v2.income[i] == false) return `#income-how.${i}`;
if (mar.answers.v2.income[i].items.length == 0) return `#income-how.${i}`;
for (let j=0; j < mar.answers.v2.income[i].items.length; j++) {
if (MAR.getOpt(mar.answers.v2.income[i].items[j], "verified", "") === "N") {
if (include_verfied_check) {
return `#income-how.${i}`;
}
}
}
return true
}
function hasEnteredIncomeEverByApplicant(applicantnum, scenario_run = false) {
let i = applicantnum;
if (scenario_run !== true) {
let _scenario = getScenario_v2();
getIncome_v2();
}
if (mar.answers.v2.income.length < (applicantnum+1)) return false;
if ("items" in mar.answers.v2.income[i] == false) return false;
if (mar.answers.v2.income[i].items.length == 0) return false;
return true
}
function hasEnteredIncome(include_verfied_check = true) {
let _scenario = getScenario_v2();
let _names = getApplicantsNames_v2();
let _applicantcount = _names.length
getIncome_v2();
for (let i=0; i < _applicantcount; i++) {
if (mar.answers.v2.income.length < _applicantcount) return `#income-how.${i}`;
if ("items" in mar.answers.v2.income[i] == false) return `#income-how.${i}`;
if (mar.answers.v2.income[i].items.length == 0) return `#income-how.${i}`;
for (let j=0; j < mar.answers.v2.income[i].items.length; j++) {
if (MAR.getOpt(mar.answers.v2.income[i].items[j], "verified", "") === "N") {
if (include_verfied_check) {
return `#income-how.${i}`;
}
}
}
}
return true
}
function hasEnteredIncomeEver(include_verfied_check = true) {
let _scenario = getScenario_v2();
let _names = getApplicantsNames_v2();
let _applicantcount = _names.length
getIncome_v2();
if (_applicantcount > 1) _applicantcount = 1;
for (let i=0; i < _applicantcount; i++) {
if (mar.answers.v2.income.length < _applicantcount) return `#income-how.${i}`;
if ("items" in mar.answers.v2.income[i] == false) return `#income-how.${i}`;
if (mar.answers.v2.income[i].items.length == 0) return `#income-how.${i}`;
for (let j=0; j < mar.answers.v2.income[i].items.length; j++) {
if (MAR.getOpt(mar.answers.v2.income[i].items[j], "verified", "") === "N") {
if (include_verfied_check) {
return `#income-how.${i}`;
}
}
}
}
return true
}
function hasEnteredLiabilitiesEver(answers) {
if (getScenario_data("__liabilities_passed" ,false,answers) == false) return "#liabilities-home";
return true;
}
function hasEnteredReoEver(answers){
if (getScenario_data("__reo_passed_0" ,false,answers) == false) return "#reo-home";
return true;
}
function hasEnteredLoxEver(answers) {
if (getScenario_data("__application_submitted" ,false,answers) == false) return "#lox";
return true;
}
return {
hasEnteredReatorInfo : hasEnteredReatorInfo,
hasEnteredAssets : hasEnteredAssets,
hasEnteredAssetsEver : hasEnteredAssetsEver,
hasEnteredPersonalInfo : hasEnteredPersonalInfo,
hasEnteredPersonalInfoByApplicant : hasEnteredPersonalInfoByApplicant,
hasEnteredIncome : hasEnteredIncome,
hasEnteredIncomeEver : hasEnteredIncomeEver,
hasEnteredIncomeByApplicant : hasEnteredIncomeByApplicant,
hasEnteredIncomeEverByApplicant : hasEnteredIncomeEverByApplicant,
hasEnteredLiabilitiesEver : hasEnteredLiabilitiesEver,
hasEnteredReoEver : hasEnteredReoEver,
hasEnteredLoxEver : hasEnteredLoxEver,
/**
* section verification
*/
orderTable : orderTable,
setHadToDoAll : setHadToDoAll,
loanWasImported : loanWasImported,
loanWasImportedAndNotVerified : loanWasImportedAndNotVerified,
loanWasImportedAndHasUnverifiedIncomeChange
: loanWasImportedAndHasUnverifiedIncomeChange,
loanWasNotImportedAndNotSubmitted : loanWasNotImportedAndNotSubmitted,
loanWasSubmitted : loanWasSubmitted,
pageVerified : pageVerified,
verifictions : verifictions,
sectionIsVerified : sectionIsVerified,
/**
* id
*/
____id : "app nav"
}
})()
/**
* cf
* @namespace MAR.encompass
*/
var encompassObj = (function(){
let current = {
borrowers : {
}
};
function _swal({ msg, cancel, cancelfn, ok, okfn}){
var s = document.createElement("div");
s.setAttribute("class","normal-form");
s.innerHTML = `${msg}
`;
swal({
title : "Encompass",
className : (ok === "") ? "midelinfopopupOneButton" : "middleInfoPopup",
content : s,
buttons : {
cancel : (typeof cancel === "string") ? cancel : "cancel",
call : {
text: (typeof ok === "string") ? ok : "ok",
value: "continue",
closeModal: false
}
}
})
.then((act) => {
if (act == "continue") {
if (typeof okfn === "function") {
okfn()
} else {
swal.close();
}
} else {
if (typeof cancelfn === "function") {
cancelfn()
}
}
})
}
function isSynchedSync(appid) {
if (typeof appid === "undefined") appid = mar.ID;
return new Promise(function(resolve, reject) {
$.get(`/api/encompass/appHelpers/is_synced?appid=${appid}`, function(rv){
resolve(rv);
});
});
}
function waitSync(n) {
return new Promise(function(resolve, reject) {
setTimeout(function(){
resolve()
},n);
});
}
let isBorrowerInEncompass_rv = false;
function isBorrowerInEncompass(appid) {
if (typeof appid === "undefined") appid = mar.ID;
return new Promise(function(resolve, reject) {
$.get(`/api/encompass/appHelpers/is_there_a_new_borrower?appid=${appid}`, function(rv){
isBorrowerInEncompass_rv = rv;
resolve(rv);
});
});
}
function uploadNewBorrowerToEncompass(appid, bp) {
if (typeof appid === "undefined") appid = mar.ID;
let url = `/api/encompass/appHelpers/upload_new_borrowers?appid=${appid}&update=y&borrowers=${bp}`;
return new Promise(function(resolve, reject) {
$.get(url, function(rv){
resolve(rv);
});
});
}
function uploadNewBorrowerToEncompassTfSync(appid, tf) {
if (typeof appid === "undefined") appid = mar.ID;
let url = `/api/encompass/appHelpers/upload_new_borrowers?appid=${appid}&update=y&tf=${tf}`;
return new Promise(function(resolve, reject) {
$.get(url, function(rv){
resolve(rv);
});
});
}
async function app_check_diffs_assetsSync(appid, applicantid) {
if (typeof appid === "undefined") appid = mar.ID;
if (typeof applicantid === "undefined") applicantid = 0;
let isSynchedObj = await MAR.encompass.isSynchedSync(appid)
if (isSynchedObj.synched === false) {
return {
status : -1,
statusMsg : "not syched"
};
return;
}
if (isBorrowerInEncompass_rv === false) {
await isBorrowerInEncompass(appid);
}
let ssn = MAR.digits(getApplicant_sn(applicantid));
let bc = MAR.getOpt(isBorrowerInEncompass_rv, `en_ssns.${ssn}`,"");
if (bc === "") {
return {
status : -2,
statusMsg : "applicant not synched"
};
return;
}
return new Promise(function(resolve, reject) {
let url = `/api/encompass/appHelpers/has_anything_changed?appid=${appid}&type=borrower-${bc}.AS`;
$.get(url, function(rv){
if (rv.diffs.length > 0) {
resolve({
status : 0,
tf : rv.tf,
diffs : rv.diffs
});
}
});
});
}
function ui_display_lomenu() {
let $menu = $("#lo-hamburger");
let $icon = $("#lo-hamburger span");
$icon.addClass("animated");
$icon.css("color" , "unset");
$menu.removeClass("x-hide");
}
function are_there_changes() {
let $icon = $("#lo-hamburger span");
return ($icon.hasClass("animated"));
}
function ui_hide_lomenu() {
let $menu = $("#lo-hamburger");
let $icon = $("#lo-hamburger span");
$icon.removeClass("animated");
$icon.css("color" , "#00000033");
//animated
$menu.removeClass("x-hide");
// $menu.addClass("x-hide");
}
function ui_update_lomenu() {
let $menu = $("#lo-hamburger");
let are_diffs = false;
for (let x in current.borrowers) {
let b = current.borrowers[x];
if (typeof b !== "object") continue;
if (b === null) continue;
let diffs = MAR.getOpt(b,"diffs",[]);
if (diffs.length > 0) are_diffs = true;
}
if (are_diffs) {
ui_display_lomenu();
} else {
ui_hide_lomenu();
}
}
function ui_onebutton() {
$(".swal-modal").removeClass("middleInfoPopup");
$(".swal-modal").addClass("midelinfopopupOneButton");
$(".swal-footer .swal-button-container")[1].style.setProperty('display', 'none', 'important');
}
function ui_dualbutton() {
$(".swal-modal").addClass("middleInfoPopup");
$(".swal-modal").removeClass("midelinfopopupOneButton");
$($(".swal-footer .swal-button-container")[1]).css("display", "unset");
}
function ui_lomenu_click() {
let $chks = $(".x-sync-del-chk");
let chks = [];
for (let i=0; i < $chks.length; i++) {
let $chk = $($chks[i]);
if ($chk.prop("checked")) {
chks.push($chk);
$chk.parent().parent().css("opacity", "0.5")
} else {
$chk.parent().parent().css("opacity", "1.0")
}
if (chks.length > 0) {
$(".swal-button.swal-button--call").html("Delete");
} else {
$(".swal-button.swal-button--call").html("Upload");
}
}
return chks;
}
let tfs = [];
let urls = [];
let xs = [];
async function ui_lomenu_reload_fn() {
let enp = $(".swal-modal #en-progress");
let enc = $(".swal-modal #en-content");
let $but = $(".swal-button.swal-button--call");
$but.addClass("x-hide");
ui_onebutton();
enp.html("Rechecking synch");
enc.html("");
let h = "";
urls = [];
tfs = [];
xs = [];
let unproc = false;
current.borrowers = {};
for (let i=0; i < MAR.applicants.count(); i++) {
let rv = await app_check_diffs_borrower_profileSync(mar.ID, i, { deferred : false});
}
for (let x in current.borrowers) {
let b = current.borrowers[x];
if (typeof b !== "object") continue;
if (b === null) continue;
let diffs = MAR.getOpt(b,"diffs",[]);
let tf = MAR.getOpt(b,"tf","");
let _unproc = MAR.getOpt(b,"unproc",false);
if (_unproc) unproc = true;
if (diffs.length === 0) continue;
tfs.push(tf);
urls.push(b.url);
xs.push(x);
let borrower_label = ((x.endsWith("B")) ? "Borrower" : "Co borrower") + " " +(num(x.substring(0,1))+1);
h += `
${borrower_label}
`;
let G = false;
let U = false;
for (let i=0; i < diffs.length; i++) {
if (typeof diff === "string") {
let diff = diffs[i];
diff = diff.split(" ");
diff.shift();
diff = diff.join(" ").split("-");
let key = diff.shift();
h += `
${key}
S|${diff.join("-").trim()}
`;
} else {
let diff = diffs[i].t;
let g = MAR.getOpt(diffs[i], "g", G);
if (g !== G) {
G = g;
U = false;
h += `
Group: ${G}
`;
}
let u = MAR.getOpt(diffs[i], "u", U);
let hk = MAR.getOpt(diffs[i], "h", false);
if (u !== U) {
U = u;
// h += `
-- UID: ${U}
`;
}
let r = MAR.getOpt(diffs[i], "r", false);
let chk = (typeof r === "string") ? `` : "";
if (hk) {
h += `
${diff}
`;
} else {
h += `
${diff}
${chk}
`;
}
}
}
}
if (unproc) {
enp.html("")
enc.html("There are changes coming from Encompass that are not downloaded yet, you'll have to try again in a few minutes");
ui_onebutton();
}
else if (h === "") {
enp.html("")
enc.html("There are no changes to upload");
ui_onebutton();
} else {
let revealbut = `Show hidden elements`;
h = `
${revealbut}
${h}
`;
enp.html("There are changes in Elaine that need to be uploaded for this borrower. Can I proceed to upload?");
enc.html(h);
$but.html("Upload")
$but.removeClass("x-hide");
ui_dualbutton();
}
}
let ui_lomenu_obj = {};
async function ui_lomenu_fn(obj) {
let logo = `
`;
if (MAR.appnav.loanWasImportedAndNotVerified() === true) {
_swal({
msg : `${logo}
This application was created as a download from Encompass but you have not yet gone through the whole app. Until then you cannot upload the changes to Encompass.
The value is successfully updated in encompass and also in Elaine.
`);
for (let i=0; i < $elms.length; i++) {
let $elm0 = $($elms[i]);
let elmid = $elm0.data("elmid");
let $elm = $(`#${elmid}`);
let val = $elm0.val();
$elm.val(val);
}
await waitSync(2000);
mar.tmp_loi_update_enc_vals_cnt = 1;
mar.tmp_loi_update_enc_vals_success = true;
if ($panel2.length > 0) {
return;
}
swal.close();
await waitSync(500);
mar._clearfn("cleared-anyway");
}
};
mar.tmp_loi_update_enc_vals_checkvals = function() {
if (mar.tmp_loi_update_enc_disabled) {
return 0;
}
let $elms = $(".x-loi_ud_win_val");
let diffcnt = 0;
for (let i=0; i < $elms.length; i++) {
let $elm = $($elms[i]);
let val = $elm.val();
let tmpid = $elm.data("tmpid");
let enc_val = mar.tmp_loi_update_enc_vals_encvals[tmpid];
if (enc_val !== val) diffcnt++;
/**
* put the value back in the original form
*/
let elmid = $elm.data("elmid");
let $elm1 = $(`#${elmid}`);
$elm1.val(val).change();
}
let $but = $(".swal-modal .swal-button.swal-button--send");
if (diffcnt > 0) {
$but.html("Update");
} else {
$but.html("Continue");
}
return diffcnt;
}
mar.tmp_loi_update_enc_vals_encvals = {};
mar.tmp_loi_update_enc_vals_cnt = 0;
mar.tmp_loi_update_enc_disabled = false;
mar.tmp_loi_update_enc_vals = async function(fn){
if (mar.tmp_loi_update_enc_disabled) {
if (fn) fn();
return false;
}
let $panel2 = $(".x-clearing-encompass-panel");
if ($panel2.length > 0) {
$panel2.html("");
}
if (mar.tmp_loi_update_enc_vals_cnt > 0) {
mar.tmp_loi_update_enc_vals_cnt = 0; /* don't do it a 2nd time */
if (fn) fn();
return false;
}
mar.tmp_loi_update_enc_vals_encvals = {};
let h = "";
let $elms = $(".x-enc-link");
h += ``;
h += ``; // right align the popup
h += `
`;
h += `
`;
h += `
`;
h += `
`;
h += `
`;
h += `
This field is linked direct to encompass so changing this value will send the information to encompass. You must have the loan closed for this to work.
`;
h += `
`;
let getLowerOrUpper = function(da, fieldname, DEF) {
let val = MAR.getOpt(da, fieldname, null);
if (val !== null) return val;
let val1 = MAR.getOpt(da, fieldname[0].toLowerCase()+fieldname.substring(1), null);
if (val1 !== null) return val1;
return DEF;
}
let geturl = function(_url) {
return new Promise(function(resolve, reject) {
$.get(_url, function(da) {
if (da.status === 0 && "obj" in da && typeof da.obj === "object") {
resolve(da.obj);
} else {
resolve(false);
}
})
});
}
let _hh = "";
for (let i=0; i < $elms.length; i++) {
let $elm = $($elms[i]);
if ($elm.is(':visible') === false) continue; /* element is not visible */
let currentvalue = $elm.val();
let startvalue = $elm.data("startvalue");
//if (`${currentvalue}`.trim() === `${startvalue}`.trim()) continue; /* nothing changed */
let _fieldname = $elm.data("enc_fieldname");
let _fieldlabel = $elm.data("enc_fieldlabel");
let _encid = $elm.data("encid");
let _ssn = $elm.data("ssn");
let _enc_type = $elm.data("enc_type");
let _enc_fieldname = $elm.data("enc_fieldname");
let _enc_fieldlabel = $elm.data("enc_fieldlabel");
let _enc_data_type = $elm.data("enc_data_type");
let _enc_transform = $elm.data("enc_transform");
let _appid = $elm.data("appid");
let _val = $elm.val().trim();
let _tval = transform("elm2enc", _enc_transform,_val);
let currentvalueT = transform("elm2enc", _enc_transform,_val);
let currentvalueS = transform("elm2arr", _enc_transform,_val);
let elmid = transform("elmid", _enc_transform,$elm[0].id);
let url = `/api/encompass/getObjectFromEncompass?appid=${_appid}&ssn=${_ssn}&type=${_enc_type}&encid=${_encid}`;
let da = await geturl(url);
let _enc_fieldnames = _enc_fieldname.split("|");
let _enc_fieldlabels = _enc_fieldlabel.split("|");
if (typeof currentvalueT !== "object") {
currentvalueT = currentvalueT.split("|");
}
if (typeof currentvalueS !== "object") {
currentvalueS = currentvalueS.split("|");
}
let _enc_data_types = _enc_data_type.split("|");
let elmids = elmid.split("|");
for (let j=0; j < _enc_fieldnames.length; j++) {
if (typeof currentvalueT[j] === "string") {
currentvalueT[j] = currentvalueT[j].trim();
}
let _tmpid = `x-tmpval-${i}-${j}`;
let enc_update = "";
let html_val = "";
if (da !== false) {
let enc_val = getLowerOrUpper(da, _enc_fieldnames[j], null);
// _h += `
Encompass data : "${enc_val}" "${currentvalueT[j]}" (${_enc_fieldnames[j]})
`;
let $popupelm = $(`.ratequote_popup .topgrid`);
if ($popupelm.length > 0) {
// this only happens in pages.housingbudget
mar.tmp_febe_breakdown_close = function() {
$(`.ratequote_popup .topgrid-details`).html(``)
$(`.ratequote_popup .topgrid-details`).addClass(`x-hide-imp`)
}
h = `
`+
`
FE / BE Breakdown
`+
`${h}`+
`
Close
`+
`
`;
$(`.ratequote_popup .topgrid-details`).html(h)
$(`.ratequote_popup .topgrid-details`).removeClass(`x-hide-imp`)
return;
}
else {
// this is in the LOI and also in the APP
if (typeof window_febe === `object`) {
// we are in the LOI because there is a FE/BE window function
mar.tmp_febe_text = h;
window_febe.open(febe.appid)
return;
}
elaineui.swalprompt({
title : "Front End / Back End Ratios",
txt : `
${h}
`,
ok : `Close`
});
}
}
let _defaults = {
Item203KSupplementalOriginationFee:{qm:`Y`,apr:`Y`},
AmortizationFee:{qm:``,apr:`Y`},
ApplicationFee:{qm:`Y`,apr:`Y`},
AutomatedUnderwritingFee:{qm:``,apr:`Y`},
BankruptcyMonitoringFee:{qm:``,apr:``},
BondFee:{qm:``,apr:``},
BondReviewFee:{qm:``,apr:``},
CertificationFee:{qm:``,apr:``},
ChosenInterestRateCreditOrChargeTotal:{qm:`Y`,apr:`Y`},
CommitmentFee:{qm:`Y`,apr:`Y`},
LoanLevelPriceAdjustment:{qm:`Y`,apr:`Y`},
LoanOriginatorCompensation:{qm:`Y`,apr:`Y`},
ManualUnderwritingFee:{qm:`Y`,apr:`Y`},
MortgageBrokerFee:{qm:`Y`,apr:`Y`},
MortgageSurchargeCountyOrParish:{qm:``,apr:``},
MortgageSurchargeMunicipal:{qm:``,apr:``},
MortgageSurchargeState:{qm:``,apr:``},
NewLoanAdministrationFee:{qm:`Y`,apr:`Y`},
OurOriginationChargeTotal:{qm:`Y`,apr:`Y`},
PreclosingVerificationControlFee:{qm:``,apr:``},
ProcessingFee:{qm:`Y`,apr:`Y`},
RateLockFee:{qm:`Y`,apr:`Y`},
RedrawFee:{qm:``,apr:``},
TemporaryBuydownAdministrationFee:{qm:``,apr:`Y`},
UnderwritingFee:{qm:`Y`,apr:`Y`},
TemporaryBuydownPoints:{qm:``,apr:`Y`},
LifeOfLoan:{qm:``,apr:``},
LoanAmountDiscountPoints:{qm:`Y`,apr:`Y`},
//
Item203KArchitecturalAndEngineeringFee:{qm:``,apr:`N`},
Item203KConsultantFee:{qm:``,apr:`Y`},
Item203KDiscountOnRepairs:{qm:``,apr:``},
Item203KTitleUpdate:{qm:`N`,apr:`Y`},
AttorneyFee:{qm:``,apr:`Y`},
CourierFee:{qm:``,apr:`Y`},
CreditDisabilityInsurancePremium:{qm:``,apr:`N`},
CreditLifeInsurancePremium:{qm:``,apr:`N`},
CreditPropertyInsurancePremium:{qm:``,apr:`N`},
CreditUnemploymentInsurancePremium:{qm:``,apr:`N`},
DebtCancellationInsurancePremium:{qm:``,apr:`N`},
DeedPreparationFee:{qm:``,apr:`N`},
DocumentaryStampFee:{qm:``,apr:``},
DocumentPreparationFee:{qm:``,apr:`N`},
ElectronicDocumentDeliveryFee:{qm:`N`,apr:`Y`},
EscrowServiceFee:{qm:``,apr:``},
FilingFee:{qm:`N`,apr:`Y`},
GeneralCounselFee:{qm:``,apr:``},
HighCostMortgageCounselingFee:{qm:``,apr:``},
LendersAttorneyFee:{qm:``,apr:``},
NotaryFee:{qm:`N`,apr:`Y`},
PowerOfAttorneyPreparationFee:{qm:``,apr:`N`},
RecordingFeeForAssignment:{qm:`N`,apr:`Y`},
SigningAgentFee:{qm:`N`,apr:`Y`},
BuyAgentFee:{qm:``,apr:`N`},
StateTitleInsuranceFee:{qm:``,apr:`N`},
SurveyFee:{qm:``,apr:`N`},
TaxRelatedServiceFee:{qm:`N`,apr:`Y`},
TitleCertificationFee:{qm:`N`,apr:`Y`},
TitleClosingFee:{qm:`N`,apr:`Y`},
TitleClosingProtectionLetterFee:{qm:`N`,apr:`Y`},
TitleDocumentPreparationFee:{qm:``,apr:`N`},
TitleEndorsementFee:{qm:``,apr:`N`},
TitleExaminationFee:{qm:``,apr:`N`},
TitleFinalPolicyShortFormFee:{qm:``,apr:`N`},
TitleInsuranceBinderFee:{qm:``,apr:`N`},
TitleInsuranceFee:{qm:``,apr:`N`},
TitleNotaryFee:{qm:``,apr:`N`},
TitleOwnersCoveragePremium:{qm:``,apr:`N`},
TitleServicesFeeTotal:{qm:``,apr:``},
TitleServicesSalesTax:{qm:``,apr:``},
TitleUnderwritingIssueResolutionFee:{qm:``,apr:``},
//
Item203KArchitecturalAndEngineeringFee:{qm:``,apr:`N`},
Item203KConsultantFee:{qm:``,apr:`Y`},
Item203KDiscountOnRepairs:{qm:``,apr:``},
Item203KInspectionFee:{qm:``,apr:`Y`},
Item203KPermits:{qm:``,apr:`N`},
AppraisalDeskReviewFee:{qm:``,apr:`N`},
AppraisalFieldReviewFee:{qm:``,apr:`N`},
AppraisalManagementCompanyFee:{qm:`N`,apr:`Y`},
AutomatedUnderwritingFee:{qm:`Y`,apr:`Y`},
AVMFee:{qm:``,apr:`N`},
CLOAccessFee:{qm:`N`,apr:`Y`},
FloodCertification:{qm:`N`,apr:`Y`},
MERSRegistrationFee:{qm:`N`,apr:`Y`},
PreclosingVerificationControlFee:{qm:``,apr:``},
PropertyTaxStatusResearchFee:{qm:`N`,apr:`Y`},
RedrawFee:{qm:``,apr:`N`},
ReinspectionFee:{qm:``,apr:``},
TaxRelatedServiceFee:{qm:`N`,apr:`Y`},
VerificationOfAssetsFee:{qm:``,apr:`Y`},
VerificationOfEmploymentFee:{qm:``,apr:`Y`},
VerificationOfIncomeFee:{qm:``,apr:`Y`},
VerificationOfResidencyStatusFee:{qm:``,apr:`Y`},
VerificationOfTaxpayerIdentificationFee:{qm:``,apr:`Y`},
VerificationOfTaxReturnFee:{qm:``,apr:`Y`},
//
TaxStampForCityDeed:{qm:``,apr:`N`},
TaxStampForCityMortgage:{qm:``,apr:`N`},
RecordingFeeForAssignment:{qm:``,apr:`N`},
RecordingFeeForMunicipalLienCertificate:{qm:``,apr:`N`},
RecordingFeeForSubordination:{qm:``,apr:`N`},
PowerOfAttorneyRecordingFee:{qm:``,apr:`N`},
RecordingFeeForDeed:{qm:``,apr:`N`},
RecordingFeeForMortgage:{qm:``,apr:`N`},
TaxStampForCountyDeed:{qm:``,apr:`N`},
TaxStampForCountyMortgage:{qm:``,apr:`N`},
TaxStampForStateDeed:{qm:``,apr:`N`},
TaxStampForStateMortgage:{qm:``,apr:`N`},
Other:{qm:``,apr:``},
//
Item203KPermits:{qm:``,apr:`Y`},
AsbestosInspectionFee:{qm:``,apr:`N`},
CondominiumAssociationDues:{qm:``,apr:`N`},
CondominiumAssociationSpecialAssessment:{qm:``,apr:`N`},
CooperativeAssociationDues:{qm:``,apr:`N`},
CooperativeAssociationSpecialAssessment:{qm:``,apr:`N`},
CreditDisabilityInsurancePremium:{qm:``,apr:`N`},
CreditLifeInsurancePremium:{qm:``,apr:`N`},
CreditPropertyInsurancePremium:{qm:``,apr:`N`},
CreditUnemploymentInsurancePremium:{qm:``,apr:`N`},
DebtCancellationInsurancePremium:{qm:``,apr:`N`},
DryWallInspectionFee:{qm:``,apr:`N`},
ElectricalInspectionFee:{qm:``,apr:`N`},
EnvironmentalInspectionFee:{qm:``,apr:`N`},
HeatingCoolingInspectionFee:{qm:``,apr:`N`},
HomeInspectionFee:{qm:``,apr:`N`},
HomeownersAssociationDues:{qm:``,apr:`N`},
HomeownersAssociationSpecialAssessment:{qm:``,apr:`N`},
HomeWarrantyFee:{qm:``,apr:`N`},
LeadInspectionFee:{qm:``,apr:`N`},
PestInspectionFee:{qm:``,apr:`N`},
PlumbingInspectionFee:{qm:``,apr:`N`},
RadonInspectionFee:{qm:``,apr:`N`},
RealEstateCommissionBuyersBroker:{qm:``,apr:`N`},
RealEstateCommissionSellersBroker:{qm:``,apr:`N`},
RepairsFee:{qm:``,apr:`N`},
RoofInspectionFee:{qm:``,apr:`N`},
SepticInspectionFee:{qm:``,apr:`N`},
SmokeDetectorInspectionFee:{qm:``,apr:`N`},
WaterTestingFee:{qm:``,apr:`N`},
WellInspectionFee:{qm:``,apr:`N`}
};
function default_qm_apr_custom_costs(cost) {
return MAR.getOpt(_defaults, cost, {qm:``,apr:``});
}
function error_remove_duplicates(arr) {
let codes = [];
let rv = [];
for (let i=0; i < arr.length; i++) {
let str = arr[i];
let code = get_error_code_code(str);
codes.push(code);
/* -- ficalow is the same as llpa fico_adjustment -- */
if (code === `llpa100` && codes.indexOf(`ficolow`) > -1 && str.indexOf(`fico_adjustment`) > -1) {
continue;
}
if (code === `llpa100` && codes.indexOf(`loanlow`) > -1 && str.indexOf(`loan_size_adjustment`) > -1) {
continue;
}
/* -- used for R&T refis -- */
if (code === `dead-ignore`) {
continue;
}
rv.push(str);
}
return rv;
}
function get_error_code_code(str) {
if (typeof str !== `string`) return ``;
if (str.indexOf(`|`) < 0) return ``;
let code = str.split(`|`)[0];
return code;
}
function get_error_code(str) {
if (typeof str !== `string`) return str;
if (str.indexOf(`|`) < 0) return str;
let code = str.split(`|`)[0];
let txt = str.split(`|`)[1];
if (code === `c2clow`) {
return `Available cash There is not enough Cash to make this loan work. ${txt}`;
}
if (code === `ficolow`) {
return `FICO The FICO is too low and this program cannot provide a rate quote. ${txt}`;
}
if (code === `wrongprop`) {
return `Property type exclusion This property type is not allowed by thie program. ${txt}`;
}
if (code === `dead`) {
return `We cannot make an offer for this program. ${txt}`;
}
if (code === `llpa100`) {
return `LLPA limit One of the parameters of the loan excludes this from being calculated. ${txt}`;
}
if (code === `loanlow`) {
return `Loan value The loan value is under the minimum for this program. ${txt}`;
}
if (code === `ltvhigh`) {
return `LTV Limit The LTV is too high for this program. ${txt}`;
}
if (code === `loanlowlimit`) {
return `Loan Value Limit ${txt}`;
}
return str;
}
return {
breakdown : breakdown,
//
default_qm_apr_custom_costs : default_qm_apr_custom_costs,
//
get_error_code : get_error_code,
error_remove_duplicates : error_remove_duplicates,
//
___id : `rq_obj`
}
})();
/**
* contract
* @namespace MAR.contract
*/
var lockObj = (function(){
function explode_app(app) {
}
return {
___id : `lock object`
}
})();
/**
* contract
* @namespace MAR.contract
*/
var contractObj = function(){
let lockObj = {};
let contractObj = {};
let lockObj_base = {};
let contractObj_base = {};
/**
* set from the db object
*/
function load_from_obj(obj) {
if (typeof obj === "string") {
obj = jsn.parse(obj, {});
}
lockObj = MAR.getOpt(obj, "lock",{});
contractObj = MAR.getOpt(obj, "contract",{});
}
function baseline(){
lockObj_base = JSON.parse(JSON.stringify(lockObj));
contractObj_base = JSON.parse(JSON.stringify(contractObj));
}
/**
* set
*/
function set_lock(k,v) {
lockObj[k] = v;
}
function set_lock_from_encompass(en_pipeline) {
}
function set_lock_from_manual(obj) {
}
function set_lock_from_other(obj) {
}
function get_lock_string_for_pipeline() {
}
function is_different_from_baseline(){
}
function set_contract(k,v) {
contractObj[k] = v;
}
/**
* clear
*/
function clear() {
lockObj = {};
contractObj = {};
}
/**
* get_combined
*/
function get_combined(){
return {
lock : lockObj,
contract : contractObj
}
}
/**
* init
*/
function init() {
//createOpt
MAR.createObt(lockObj, `price` , 0);
MAR.createObt(lockObj, `status` , ``);
MAR.createObt(lockObj, `date` , ``);
MAR.createObt(lockObj, `date_expire` , ``);
MAR.createObt(lockObj, `rate` , 0);
MAR.createObt(lockObj, `days` , 0);
MAR.createObt(lockObj, `prog` , ``);
MAR.createObt(lockObj, `compensation_type` , ``);
MAR.createObt(lockObj, `compensation_factor` , ``);
MAR.createObt(lockObj, `compensation_value` , 0);
MAR.createObt(lockObj, `compensation_in_lo_fee` , `N`);
MAR.createObt(lockObj, `buyout_fee_yn` , `N`);
MAR.createObt(lockObj, `buyout_fee_value` , 0);
MAR.createObt(lockObj, `note` , ``);
}
let lock_statuses = {
none : { txt : `None` },
registered : { txt : `Registered` },
locked : { txt : `Locked` },
expired : { txt : `Expired` },
cancelled : { txt : `Cencelled` },
withdrawn : { txt : `Withdrawn` },
float : { txt : `Float` },
pending : { txt : `Lock Pending` },
registered_man : { txt : `Registered Manual` },
pending_man : { txt : `Lock Pending Manual` },
locked_man : { txt : `Locked Manual` }
}
return {
get_lockObj : function() { return lockObj; }, // get only the lock object
get_Lock : function() { return lockObj; }, // get only the lock object
get_contractObj : function() { return contractObj; }, // get only the contract object
get_Contract : function() { return contractObj; }, // get only the contract object
get_lock_statuses : function() { return lock_statuses; },
get_combined : get_combined, // get combined for saving
//
clear : clear, // empty the contents
init : init, // make any missing data
//
load_from_obj : load_from_obj, // populate from object
set_lock : set_lock, // set key in the lock object
set_l : set_lock,
set_contract : set_contract, // set a key in the contract object
set_c : set_contract,
//
set_lock_from_encompass : set_lock_from_encompass, // set from the encompass data
set_lock_from_manual : set_lock_from_manual, // manual
set_lock_from_other : set_lock_from_other, // other
//
baseline : baseline, // baseline
get_lock_string_for_pipeline : get_lock_string_for_pipeline, // get string summary
//
___id : `Contract object`
}
}
/**
* cpull
* @namespace MAR.cpull
*/
var cpullObj = (function(){
function is_too_old(date, return_days = false) {
if (date === null) return false;
if (date === "") return false;
let dat_diff = (new Date().getTime() - new Date(date).getTime());
dat_diff = dat_diff/1000; // secs
dat_diff = dat_diff/60; // mins
dat_diff = dat_diff/60; // hours
dat_diff = ~~(dat_diff/24); // days
if (return_days) {
return dat_diff;
}
if (dat_diff > 90) {
return true;
}
}
return {
is_too_old : is_too_old,
___id : `cpull object`
}
})();
/**
* liabilities
* @namespace MAR.liabilities
*/
var liabilitiesObj = (function(){
/**
* @memberof MAR.liabilities
*/
function init() {
}
/**
* @memberof MAR.liabilities
*/
function delByUUID(uuid) {
let idx = getByUUID(uuid,true);
if (idx !== false) {
del(idx);
}
}
/**
* @memberof MAR.liabilities
*/
function setByUUID(uuid, obj) {
let idx = getByUUID(uuid,true);
if (idx !== false) {
for (let x in obj) {
mar.answers.v2.liabilities[idx][x] = obj[x];
}
}
}
/**
* @memberof MAR.liabilities
*/
function getByUUID(uuid, returnindex) {
let _array = get();
for (let i=0; i < _array.length; i++) {
if ("uuid" in _array[i] && _array[i].uuid == uuid) {
if (arguments.length > 1 && returnindex === true) return i;
return _array[i];
}
}
return false;
}
/**
* @memberof MAR.liabilities
*/
function getBySIG(sig) {
let _array = get();
for (let i=0; i < _array.length; i++) {
if ("sig" in _array[i] && _array[i].sig == sig) return _array[i];
}
return false;
}
/**
* @memberof MAR.liabilities
*/
function getByEncId(enc_uuid) {
let _array = get();
for (let i=0; i < _array.length; i++) {
if ("enc_uuid" in _array[i] && _array[i].enc_uuid == enc_uuid) return {
i : i,
data : _array[i]
}
}
return false;
}
/**
* @memberof MAR.liabilities
*/
function setLoanLinkByUUID(loanlink , _REO_uuid) {
let loanlinks = loanlink.split(",");
loanlinks.filter(function(ll){
let index = getByUUID(ll, true);
if (typeof index === "number") mar.answers.v2.liabilities[index].reolink = _REO_uuid;
})
}
/**
* @memberof MAR.liabilities
*/
function delLoanLinkByUUID(loanlink) {
let loanlinks = loanlink.split(",");
loanlinks.filter(function(ll){
let index = getByUUID(ll, true);
if (typeof index === "number") mar.answers.v2.liabilities[index].reolink = ``;
})
}
/**
* @memberof MAR.liabilities
*/
function repair_uuids() {
let _array = get();
let rv = false;
for (let i=0; i < _array.length; i++) {
if ("uuid" in _array[i] === false) {
_array[i].uuid = uuidv4();
rv = true;
}
}
return rv;
}
/**
* @memberof MAR.liabilities
*/
function repair() {
let _array = get();
let rv = false;
for (let i=0; i < _array.length; i++) {
if ("enc_id" in _array[i] === false) {
_array[i].enc_id = getNextLiabilityEncId();
rv = true;
}
}
return rv;
}
/**
* @memberof MAR.liabilities
*/
function is_verified_item(applicantnum, type) {
let vapplicantnum = MAR.applicants.vid(applicantnum);
let items = get(type);
for (let i=0; i < items.length; i++) {
let item = items[i];
if (item.verified !== `Y`) continue;
return item;
}
return false
}
/**
* @memberof MAR.liabilities
*/
function getFirstAssignment(ino) {
for (var i=0; i < 8; i++) {
if ((ino & Math.pow(2,i)) == Math.pow(2,i)) return (i);
}
return -1;
}
/**
* @memberof MAR.liabilities
*/
function create(type, applicant, name){
let retval = {};
retval.type = type;
retval.name = name;
retval.inomask = Math.pow(2,applicant);
retval.balance = 0;
retval.monthly = 0;
retval.verified = "N";
return retval;
}
/**
* @memberof MAR.liabilities
*/
function ino_isin(ino, applicant) {
return (ino & Math.pow(2,applicant) == Math.pow(2,applicant))
}
/**
* @memberof MAR.liabilities
*/
function add_unverified_from_declarations() {
let number_of_applicants = MAR.applicants.count();
let opt = "";
let added = false;
for (let i= 0; i < number_of_applicants; i++) {
opt = MAR.declarations.get(i, "credit_obligated_to_pay_alimony_or_child", "");
if (opt === "Y") {
let _array = get("child");
let _found = false;
for (let j=0; j < _array.length; j++) {
let _item = _array[j];
if (ino_isin(_item.inomask, i)) _found = true;
}
if (_found == false) {
let item = create("child", i, "Child/Alimony from declarations");
item._auto_created = "Y";
MAR.liabilities.set("child", false, item);
added = true;
}
// let follow = MAR.declarations.get(i, "credit_obligated_to_pay_alimony_or_child_followup", "");
// if (follow == "alimony" || follow == "both") {
// let _array = get("alimony");
// let _found = false;
// for (let j=0; j < _array.length; j++) {
// let _item = _array[j];
// if (ino_isin(_item.inomask, i)) _found = true;
// }
// if (_found == false) {
// let item = create("alimony", i, "Alimony from declarations");
// MAR.liabilities.set("alimony", false, item);
//
// }
// }
// if (follow == "child" || follow == "both") {
// let _array = get("child");
// let _found = false;
// for (let j=0; j < _array.length; j++) {
// let _item = _array[j];
// if (ino_isin(_item.inomask, i)) _found = true;
// }
// if (_found == false) {
// let item = create("child", i, "Child from declarations");
// MAR.liabilities.set("child", false, item);
//
// }
// }
}
opt = MAR.declarations.get(i, "credit_delinquent_on_federal_debt", "");
if (opt === "Y") {
let follow = MAR.declarations.get(i, "credit_delinquent_on_federal_debt_type", "");
if (follow == "tax" || follow == "both") {
let _array = get("irstax");
let _found = false;
for (let j=0; j < _array.length; j++) {
let _item = _array[j];
if (ino_isin(_item.inomask, i)) _found = true;
}
if (_found == false) {
let item = create("irstax", i, "IRS Debt");
item.verified = "N";
item._auto_created = "Y";
MAR.liabilities.set("irstax", false, item);
added = true;
}
}
}
opt = MAR.declarations.get(i, "credit_irs_plan", "");
if (opt === "Y") {
let _array = get("irstax");
let _found = false;
for (let j=0; j < _array.length; j++) {
let _item = _array[j];
if (ino_isin(_item.inomask, i)) _found = true;
}
if (_found == false) {
let item = create("irstax", i, "IRS Debt");
item.verified = "N";
item._auto_created = "Y";
MAR.liabilities.set("irstax", false, item);
added = true;
}
}
opt = MAR.declarations.get(i, "credit_downpayment_borrowed", "");
if (opt === "Y") {
let _array = get("instalmentloan");
let _found = false;
for (let j=0; j < _array.length; j++) {
let _item = _array[j];
if (ino_isin(_item.inomask, i)) {
if (MAR.getOpt(_item, "_auto_bor_dp","") === "Y") {
_found = true;
}
}
}
if (_found == false) {
let item = create("instalmentloan", i, "Loan for borrowed ");
item.institution = `Borrowed downpayment`;
item.verified = "N";
item._auto_bor_dp = "Y";
item.balance = MAR.declarations.get(i, "credit_downpayment_borrowed_value", "");
MAR.liabilities.set("instalmentloan", false, item);
added = true;
}
}
opt = MAR.declarations.get(i, "additional_loan", "");
if (opt === "Y") {
let _array = get();
let _found = false;
for (let j=0; j < _array.length; j++) {
let _item = _array[j];
if (ino_isin(_item.inomask, i)) {
if (MAR.getOpt(_item, "_auto_newloan","") === "Y") {
_found = true;
}
}
}
if (_found == false) {
let item = create("instalmentloan", i, "New Loan");
item.institution = `New Loan`;
item.verified = "N";
item._auto_newloan = "Y";
MAR.liabilities.set("instalmentloan", false, item);
added = true;
}
}
}
return added;
}
let is_mortgage_attached = function(item) {
if (MAR.getOpt(item,"reolink","") === "") {
return false
}
return true;
}
let is_mortgage_manual = function(item) {
if (MAR.getOpt(item,"sig","") === "") {
return true;
}
return false;
}
/**
* @memberof MAR.liabilities
*/
function get_unattached_mortgages() {
let _array = get();
let rv = [];
for (let i=0; i < _array.length; i++) {
if (_array[i].type !== "mortgage" && _array[i].type !== "heloc") continue;
let is_attached = is_mortgage_attached(_array[i]);
if (is_attached === false) {
rv.push({
i : i,
item : _array[i]
});
}
}
return rv;
}
/**
* @memberof MAR.liabilities
*/
function get_manual_mortgages() {
let _array = get();
let rv = [];
for (let i=0; i < _array.length; i++) {
if (_array[i].type !== "mortgage") continue;
let is_manual = is_mortgage_manual(_array[i]);
if (is_manual === true) {
rv.push({
i : i,
item : _array[i]
});
}
}
return rv;
}
/**
* @memberof MAR.liabilities
*/
function get_replacement_manual_mortgages_advice() {
let unattached_mortgages = get_unattached_mortgages();
let manual_mortgages = get_manual_mortgages();
let rv = {};
rv.unattached_mortgages = unattached_mortgages;
rv.manual_mortgages = manual_mortgages;
rv.suggestions = [];
if (unattached_mortgages.length === 0) {
rv.status = 0;
return rv;
}
if (manual_mortgages.length === 0) {
rv.status = 0;
return rv;
}
for (let i=0; i < manual_mortgages.length; i++) {
let mm = manual_mortgages[i];
for (let j=0; j < unattached_mortgages.length; j++) {
let um = unattached_mortgages[i];
let mm_bal = num(mm.item.balance);
let um_bal = num(um.item.balance);
if (mm_bal === 0) continue;
if (um_bal === 0) continue;
let diff_perc = Math.abs(((mm_bal/ um_bal) -1)*100);
if (diff_perc > 10) continue;
rv.suggestions.push({
um : um,
mm : mm,
diff_perc : diff_perc
});
}
}
return rv;
}
/**
* @memberof MAR.liabilities
*/
function has_manual_items() {
let _array = get();
for (let i=0; i < _array.length; i++) {
if ("sig" in _array[i] == false) return true;
}
return false;
}
/**
* @memberof MAR.liabilities
*/
function has_unverified_items() {
let _array = get();
for (let i=0; i < _array.length; i++) {
if ("verified" in _array[i] == true && _array[i].verified === "N") return true;
}
return false;
}
/**
* @memberof MAR.liabilities
*/
function has_unverified_items_except_mortgages() {
let _array = get();
for (let i=0; i < _array.length; i++) {
if (_array[i].type === "mortgage") continue;
if (_array[i].type === "heloc") continue;
if ("verified" in _array[i] == true && _array[i].verified === "N") return true;
}
return false;
}
/**
* @memberof MAR.liabilities
*/
function getNextUnverifiedItem() {
let _array = get();
for (let i=0; i < _array.length; i++) {
if ("verified" in _array[i] == true && _array[i].verified === "N") {
return {
i : i,
uuid : _array[i].uuid
}
}
}
return false;
}
let pagenames = {
mortgage : "mortgage",
heloc : "heloc",
alimony : "alimony",
child : "child",
studentloan : "studentloan",
carloan : "carloan",
carlease : "carlease",
instalmentloan : "instalmentloan",
creditcard : "creditcard"
}
function make_link(item, i) {
let type = MAR.getOpt(item, `type`,``);
let pagename = MAR.getOpt(pagenames, type, ``);
if (pagename === ``) {
return false;
}
return `#liabilities-${pagename}.0.${i}`;
}
/**
* @memberof MAR.liabilities
*/
function getNextUnverifiedItem_except_mortgages() {
let _array = get();
for (let i=0; i < _array.length; i++) {
if (_array[i].type === "mortgage") continue;
if (_array[i].type === "heloc") continue;
if ("verified" in _array[i] == true && _array[i].verified === "N") {
return {
i : i,
uuid : _array[i].uuid,
link : make_link(_array[i],i)
}
}
}
return false;
}
/**
* @memberof MAR.liabilities
*/
function get(type, number) {
if ("answers" in mar == false) return false;
if ("v2" in mar.answers == false) return false;
if ("liabilities" in mar.answers.v2 == false) return false;
if (arguments.length == 0) { // return the array for one applicant
return mar.answers.v2.liabilities;
}
if (arguments.length == 1) { // return the array for one applicant
let retval = [];
for (let i=0; i < mar.answers.v2.liabilities.length; i++) {
if (mar.answers.v2.liabilities[i].type == type) {
mar.answers.v2.liabilities[i]._i = i;
retval.push(mar.answers.v2.liabilities[i])
}
}
return retval;
}
if (typeof number == "string") number = parseInt(number,10);
if (number < mar.answers.v2.liabilities.length) {
return mar.answers.v2.liabilities[number];
}
return false;
}
function getNextLiabilityEncId(){
if ("state" in mar.answers.v2 == false) mar.answers.v2.state = {};
if ("liability_encid" in mar.answers.v2.state == false) mar.answers.v2.state.liability_encid = 3;
if (num(mar.answers.v2.state.liability_encid) < 30) mar.answers.v2.state.liability_encid = 30;
let retval = mar.answers.v2.state.liability_encid;
mar.answers.v2.state.liability_encid++;
return retval;
}
/**
* @memberof MAR.liabilities
*/
function set_from_object(obj) {
let uuid = MAR.getOpt(obj, "uuid", "");
if ("answers" in mar == false) mar.answers = {};
if ("v2" in mar.answers == false) mar.answers.v2 = {};
if ("liabilities" in mar.answers.v2 == false) mar.answers.v2.liabilities = [];
if (Array.isArray(mar.answers.v2.liabilities) == false) mar.answers.v2.liabilities = [];
let itm = getByUUID(uuid);
if (itm === false) return;
for (let x in obj) {
itm[x] = obj[x];
}
}
/**
* @memberof MAR.liabilities
*/
function set(type, number, data) {
if (arguments.length >= 3) { // return the whole array
if ("answers" in mar == false) mar.answers = {};
if ("v2" in mar.answers == false) mar.answers.v2 = {};
if ("liabilities" in mar.answers.v2 == false) mar.answers.v2.liabilities = [];
if (Array.isArray(mar.answers.v2.liabilities) == false) mar.answers.v2.liabilities = [];
if (number === false) {
if ("uuid" in data == false) data.uuid = uuidv4();
data.enc_id = getNextLiabilityEncId();
mar.answers.v2.liabilities.push(data);
MAR.activity_log.add("liabilities", data.uuid);
return (mar.answers.v2.liabilities.length -1);
} else {
if (typeof number == "string") number = parseInt(number,10);
if (mar.answers.v2.liabilities.length > number) {
if ("uuid" in mar.answers.v2.liabilities[number] == false) {
if ("uuid" in data == false) data.uuid = uuidv4();
data.enc_id = getNextLiabilityEncId();
// } else {
// data.uuid = mar.answers.v2.assets.items[number].uuid;
}
if ("enc_id" in mar.answers.v2.liabilities[number] == false) {
if ("enc_id" in data == false) data.enc_id = getNextLiabilityEncId()
}
if ("enc_uuid" in mar.answers.v2.liabilities[number] == false) {
if ("enc_uuid" in data == false) data.enc_uuid = data.uuid;
}
for (x in data) {
/**
* update only , don't overwrite!
*/
mar.answers.v2.liabilities[number][x] = data[x];
}
MAR.activity_log.mod("liabilities", mar.answers.v2.liabilities[number].uuid);
// mar.answers.v2.assets.items[number] = data;
return number;
}
}
}
}
/**
* @memberof MAR.liabilities
*/
function del(number) {
if (arguments.length < 0) return false;
if ("answers" in mar == false) return false;
if ("v2" in mar.answers == false) return false;
if ("liabilities" in mar.answers.v2 == false) return false;
if (number >= mar.answers.v2.liabilities.length) return false;
MAR.activity_log.del("liabilities", mar.answers.v2.liabilities[number].uuid);
mar.answers.v2.liabilities.splice(number, 1);
return true;
}
/**
* @memberof MAR.liabilities
*/
function getShortDescription(type) {
if (type === "child") return "Alimony/Child";
return type;
}
let liabilities_reccomendation = (function(liabilities){
let _l = liabilities;
let _objs = [];
function init(){
_objs = [];
if (!_l) return;
for (let i=0; i < _l.length; i++) {
_objs.push({
i : i,
obj : MAR.xsd.lia_factory(_l[i])
});
}
}
function getForApplicant(n) {
return _objs.filter(function(item) {
return (item.obj.assigned().indexOf(n) > -1)
})
}
function getForApplicantType(n, t) {
return _objs.filter(function(item) {
return (item.obj.assigned().indexOf(n) > -1) && (item.obj.raw().type === t)
})
}
function getForApplicantTypeUnverified(n, t) {
return _objs.filter(function(item) {
return (item.obj.assigned().indexOf(n) > -1) && (item.obj.raw().type === t) && (MAR.getOpt(item.obj.raw(), "verified", "Y") === "N")
})
}
function getForApplicantTypeUnverifiedAndNotOmitted(n, t) {
return _objs.filter(function(item) {
if (item.obj.assigned().indexOf(n) === -1) return false;
if (item.obj.raw().type !== t) return false;
if (MAR.getOpt(item.obj.raw(), "_auto_created", "") === "Y") return false;
if (MAR.getOpt(item.obj.raw(), "_auto_bor_dp", "") === "Y") return false;
if (MAR.getOpt(item.obj.raw(), "_auto_newloan", "") === "Y") return false;
if (MAR.getOpt(item.obj.raw(), "verified", "") === "Y") return false;
if (MAR.getOpt(item.obj.raw(), "omit", "") === "Y") return false;
if (MAR.getOpt(item.obj.raw(), "cstatus", "") === "tofillin") return false;
return true;
})
}
function applicantHasAlimony(n) {
let items = getForApplicant(n);
for (let i=0; i < items.length; i++) {
let item = items[i];
if (item.obj.raw().type === "child") {
if (item.obj.alimony() > 0) return item;
}
}
return false;
}
function applicantHasChild(n) {
let items = getForApplicant(n);
for (let i=0; i < items.length; i++) {
let item = items[i];
if (item.obj.raw().type === "child") {
if (item.obj.child() > 0) return item;
}
}
return false;
}
function applicantHasIrs(n) {
let items = getForApplicant(n);
for (let i=0; i < items.length; i++) {
let item = items[i];
if (item.obj.raw().type === "irsdebt") {
if (item.obj.monthly() > 0) return item;
}
if (item.obj.raw().type === "jsr") {
if (item.obj.raw.name.toLowerCase().indexOf("tax") > -1) {
if (item.obj.monthly() > 0) return item;
}
}
}
return false;
}
let _r = {}
function reccommend() {
let number_of_applicants = MAR.applicants.count();
let opt = "";
let r = [];
let q = [];
let c = [];
_r.number_of_applicants = number_of_applicants;
_r.r = r;
_r.q = q;
_r.c = c;
for (let i= 0; i < number_of_applicants; i++) {
opt = MAR.declarations.get(i, "credit_obligated_to_pay_alimony_or_child", "");
if (opt === "Y") {
let follow = MAR.declarations.get(i, "credit_obligated_to_pay_alimony_or_child_followup", "");
if (follow == "alimony" || follow == "both") {
let hasLiability = applicantHasAlimony(i);
if (hasLiability === false) {
r.push("The client says that they have to pay alimony but there is no alimony in their credit")
}
}
if (follow == "child" || follow == "both") {
let hasLiability = applicantHasChild(i);
if (hasLiability === false) {
r.push("The client says that they have to pay child support but there is no alimony in their credit")
}
}
}
opt = MAR.declarations.get(i, "credit_irs_plan", "");
if (opt === "Y") {
let hasLiability = applicantHasIrs(i);
if (hasLiability === false) {
r.push("The client says that they have an IRS payment plan but there is none in their credit")
}
}
let ccard = getForApplicantTypeUnverifiedAndNotOmitted(i,"creditcard");
if (ccard.length > 0) {
// r.push("The client should be asked if they are not paying any of their creditcards")
q.push(["ask-creditcards",ccard,i]);
}
let carloan = getForApplicantTypeUnverifiedAndNotOmitted(i,"carloan");
if (carloan.length > 0) {
// r.push("The client should be asked if they are not paying any of their carloans")
q.push(["ask-carloans",carloan,i]);
}
let studentloan = getForApplicantTypeUnverifiedAndNotOmitted(i,"instalmentloan");
if (studentloan.length > 0) {
// r.push("The client should be asked if any of the instalment loans are student loans")
q.push(["ask-studentloans",studentloan,i]);
}
(function(){
let items = getForApplicantTypeUnverifiedAndNotOmitted(i,"instalmentloan");
if (items.length > 0) {
// r.push("The client should be asked if they are not paying any of their carloans")
q.push(["ask-instalmentloans",items,i]);
}
})();
let studentloan2 = getForApplicantType(i,"studentloan").filter(function(item){
return (item.obj.raw().cstatus === "tofillin")
})
if (studentloan2.length > 0) {
r.push("The client should be asked to fill in information about these student loans")
q.push(["ask-studentloan",studentloan2,i]);
}
(function(){
let studentloan3 = getForApplicantType(i,"studentloan").filter(function(item){
return (item.obj.raw().cstatus !== "tofillin")
})
for (let j=0; j < studentloan3.length; j++) {
let jj = studentloan3[j].i;
let paytype = studentloan3[j].obj.raw().paytype;
let monthly = studentloan3[j].obj.monthly();
let name = studentloan3[j].obj.raw().name;
r.push(`The client has indicated that liability ${jj} ${name} \$${monthly} pm is a student loan with the type "${paytype}" `)
}
})();
(function(){
let items = getForApplicantType(i,"child").filter(function(item){
let raw = item.obj.raw() ;
return (MAR.getOpt(item.obj.raw(), "cstatus", "") === "")
})
if (items.length > 0) {
// r.push("The client should be asked to fill in information about these Alimon/child suport")
q.push(["ask-child",items,i]);
}
})();
(function(){
let items = getForApplicantType(i,"irstax").filter(function(item){
return (MAR.getOpt(item.obj.raw(), "cstatus", "") === "")
})
if (items.length > 0) {
// r.push("The client should be asked to fill in information about these IRS debts")
q.push(["ask-irs",items,i]);
}
})();
(function(){
let items = getForApplicant(i);
for (let j=0; j < items.length; j++) {
let item = items[j].obj.raw();
if (MAR.getOpt(item, "verified","") !== "Y") {
if (MAR.getOpt(item, "_auto_newloan","") === "Y") q.push(["ask-newloan",[items[j]],i]);
if (MAR.getOpt(item, "_auto_bor_dp","") === "Y") q.push(["ask-borrowed",[items[j]],i]);
}
}
})();
(function(){
let items = getForApplicantType(i,"creditcard").filter(function(item){
return (item.obj.raw().cstatus === "coborrower")
})
for (let j=0; j < items.length; j++) {
let jj = items[j].i;
let paytype = items[j].obj.raw().paytype;
let monthly = items[j].obj.monthly();
let name = items[j].obj.raw().name;
r.push(`The client has indicated that on creditcard "${name}" \$${monthly} pm they are a co-signer, you may be able to exclude this liability `)
}
})();
(function(){
let items = getForApplicantType(i,"instalmentloan").filter(function(item){
return (item.obj.raw().cstatus === "coborrower")
})
for (let j=0; j < items.length; j++) {
let jj = items[j].i;
let paytype = items[j].obj.raw().paytype;
let monthly = items[j].obj.monthly();
let name = items[j].obj.raw().name;
r.push(`The client has indicated that on instalment loan "${name}" \$${monthly} pm they are a co-signer, you may be able to exclude this liability `)
}
})();
(function(){
let items = getForApplicantType(i,"child").filter(function(item){
return (item.obj.raw().cstatus === "ok")
})
for (let j=0; j < items.length; j++) {
let jj = items[j].i;
let monthly = items[j].obj.monthly();
let name = items[j].obj.raw().name;
let ch = items[j].obj.child();
let al = items[j].obj.alimony();
r.push(`The client has indicated that liability "${name}" \$${monthly} pm is a An alimony/child support with the folllowing split child \$${ch}, alimony \$${al}" `)
}
})();
(function(){
let items = getForApplicantType(i,"irstax").filter(function(item){
return (item.obj.raw().cstatus === "ok")
})
for (let j=0; j < items.length; j++) {
let jj = items[j].i;
let monthly = items[j].obj.monthly();
let name = items[j].obj.raw().name;
r.push(`The client has indicated that liability "${name}" \$${monthly} pm is a An IRS plan" `)
}
})();
// (function(){
// let items = getForApplicantType(i,"child").filter(function(item){
// return ("cstatus" in item.obj.raw() === false)
// })
// for (let j=0; j < items.length; j++) {
// let jj = items[j].i;
// let paytype = items[j].obj.raw().paytype;
// let monthly = items[j].obj.monthly();
// let name = items[j].obj.raw().name;
// r.push(`The client has indicated that on creditcard ${jj} ${name} \$${monthly} pm they are a co-signer, you may be able to exclude this liability `)
// }
//
// })();
}
}
return {
init : init,
getForApplicant : getForApplicant,
getForApplicantType : getForApplicantType,
getForApplicantTypeUnverified : getForApplicantTypeUnverified,
getForApplicantTypeUnverifiedAndNotOmitted : getForApplicantTypeUnverifiedAndNotOmitted,
applicantHasChild : applicantHasChild,
applicantHasAlimony : applicantHasAlimony,
applicantHasIrs : applicantHasIrs,
reccommend : reccommend,
reccommendations : _r,
___id : "liabilities reccomendations"
}
});
function get_payoff_omit_action(itm, def = "") {
if (!itm) return def;
let omit = MAR.getOpt(itm, "omit","");
let omit_opt = MAR.getOpt(itm, "omit_opt","");
let payoff = MAR.getOpt(itm, "payoff",false);
let paytype = MAR.getOpt(itm, "paytype","");
if (omit_opt !== "") {
if (omit_opt === "payoff") return `payoff`;
if (omit_opt === "less10pmts") return `omit_less10pmts`;
if (omit_opt === "paidoff") return `omit_paidoff`;
if (omit_opt === "notpaying") return `omit_notpaying`;
if (omit_opt === "before") return `payoff_before`;
if (omit_opt === "andclose") return `payoff_andclose`;
if (omit_opt === "and-cancel") return `payoff_and-cancel`;
if (omit_opt === "down-to-omit") return `payoff_down-to-omit`;
}
if (omit === "Y" && omit_opt !== "") {
return `omit_${omit_opt}`;
}
if (payoff === true && omit_opt === "") {
return `payoff`;
}
if (payoff === true && omit_opt !== "") {
return `payoff_${omit_opt}`;
}
if (omit === "Y") {
return `omit_notpaying`;
}
if (paytype === "def") {
return "stu_5pc";
}
if (paytype === "ibr") {
return "stu_5pc";
}
return def;
}
function set_payoff_omit_from_action(itm, act) {
if (act === "omit") {
itm.omit = "Y";
itm.omit_opt = "";
itm.payoff = false;
return;
}
if (act === "payoff") {
itm.omit = "N";
itm.omit_opt = "";
itm.payoff = true;
return;
}
if (act === "omit_less10pmts") {
itm.omit = "Y";
itm.omit_opt = "less10pmts";
itm.payoff = false;
return;
}
if (act === "omit_paidoff") {
itm.omit = "Y";
itm.omit_opt = "paidoff";
itm.payoff = false;
return;
}
if (act === "omit_notpaying") {
itm.omit = "Y";
itm.omit_opt = "notpaying";
itm.payoff = false;
return;
}
if (act === "payoff_before") {
itm.omit = "Y";
itm.omit_opt = "before";
itm.payoff = false;
}
if (act === "payoff_andclose") {
itm.omit = "N";
itm.omit_opt = "andclose";
itm.payoff = true;
return;
}
if (act === "payoff_and-cancel") {
itm.omit = "Y";
itm.omit_opt = "and-cancel";
itm.payoff = false;
return;
}
if (act === "payoff_down-to-omit") {
itm.omit = "Y";
itm.omit_opt = "down-to-omit";
itm.payoff = false;
return;
}
if (act === "" || act === "keep") {
itm.omit = "N";
itm.omit_opt = "";
itm.payoff = false;
itm.paytype = "";
}
if (act === "stu_5pc") {
itm.paytype = "def";
itm.omit = "N";
itm.omit_opt = "";
itm.payoff = false;
return
}
}
function redflag_description(s) {
if (s === "l90") return "There have been 90 day late payments on this account";
if (s === "l60") return "There have been 60 day late payments on this account";
if (s === "l30") return "There have been 30 day late payments on this account";
if (s === "pattern") return "There have issued detectedin the last 12 months";
// AsAgreed : Account is being paid on time and according to terms of the credit agreement.
if (s === "BankruptcyOrWageEarnerPlan") return "The exact type could not be determined.";
if (s === "ChargeOff") return "The account was not paid on a timely basis and the debt is being written off as uncollectible by the creditor.";
if (s === "Collection") return "Account has not been paid on a timely basis and is been turned over to an attorney or agency for collection.";
if (s === "CollectionOrChargeOff") return "The exact type could not be determined.";
if (s === "Foreclosure") return "Legal proceedings have been initiated to sell property to settle debt on an unpaid balance.";
if (s === "ForeclosureOrRepossession") return "The exact type could not be determined.";
if (s === "Late30Days") return "Account is between 30 and 59 days past due.";
if (s === "Late60Days") return "Account is between 60 and 89 days past due.";
if (s === "Late90Days") return "Account is betwen 90 and 119 days past due.";
if (s === "LateOver120Days") return "Account is 120 days or more past due.";
if (s === "NoDataAvailable") return "Status of the account is not known.";
if (s === "Repossession") return "Account has not been paid on a timely basis and proceedings have been initiated to repossess collateral property to partially of fully satisfy the debt.";
if (s === "TooNew") return "Account has been recently established and is too new to rate payment history.";
if (s === "WageEarnerPlan") return "Past due debt on an account is being paid according to terms established by a court or agreement with the creditor.";
return s;
}
function helper_make_shorter_name(itm_array /* from getbackend etccc */) {
let itms = itm_array.split(`:`);
let type = itms.shift();
let itm_desc = (function() {
if (type === `child`) return `${itms.join(":")}`;
if (type === `irstax`) return `${itms.join(":")}`;
if (itms.length > 0) {
for (let j=0; j < itms.length; j++) {
let itm_str = itms[j];
if (itm_str.startsWith(`Account`) && itm_str.length > 7) {
itms[j] = `Acc #..${itm_str.substring(7).slice(-4)}`;
}
}
}
return `${mar._txt(type)} - ${itms.join(":")}`;
})();
return itm_desc;
}
function helper_make_shorter_name_for_mismo(itm_str) {
let itms = itm_str.split(`:`);
let itm_desc = (function() {
if (itms.length > 0) {
for (let j=0; j < itms.length; j++) {
let itm_str = itms[j];
if (itm_str.startsWith(`Account`) && itm_str.length > 7) {
itms[j] = `Acc #..${itm_str.substring(7).slice(-4)}`;
}
}
}
return `${itms.join(":")}`;
})();
return itm_desc;
}
function over_is_diff(item) {
let ovr = MAR.getOpt(item , `over` , `N` );
let mo = MAR.getOptNum(item, `monthly` , 0 );
let movr = MAR.getOptNum(item, `over_monthly`, 0 );
let ba = MAR.getOptNum(item, `balance` , 0 );
let bovr = MAR.getOptNum(item, `over_balance`, 0 );
if (ovr !== `Y`) return false;
if (mo !== movr) return true;
if (ba !== bovr) return true;
return false;
}
return {
init : init,
getByUUID : getByUUID,
delByUUID : delByUUID,
setByUUID : setByUUID,
setLoanLinkByUUID : setLoanLinkByUUID,
delLoanLinkByUUID : delLoanLinkByUUID,
//
redflag_description : redflag_description,
//
over_is_diff : over_is_diff,
//
has_manual_items : has_manual_items,
has_unverified_items : has_unverified_items,
has_unverified_items_except_mortgages : has_unverified_items_except_mortgages,
//
get_unattached_mortgages : get_unattached_mortgages,
get_manual_mortgages : get_manual_mortgages,
get_replacement_manual_mortgages_advice : get_replacement_manual_mortgages_advice,
//
getNextUnverifiedItem : getNextUnverifiedItem,
getNextUnverifiedItem_except_mortgages : getNextUnverifiedItem_except_mortgages,
add_unverified_from_declarations : add_unverified_from_declarations,
//
getByEncId : getByEncId,
//
liabilities_reccomendation : liabilities_reccomendation,
//
getShortDescription : getShortDescription,
//
repair : repair,
repair_uuids : repair_uuids,
//
helper_make_shorter_name : helper_make_shorter_name,
helper_make_shorter_name_for_mismo : helper_make_shorter_name_for_mismo,
//
create : create,
//
pagenames : pagenames,
//
set_payoff_omit_from_action : set_payoff_omit_from_action,
get_payoff_omit_action : get_payoff_omit_action,
//
get : get,
set : set,
set_from_object : set_from_object,
del : del,
//
is_verified_item : is_verified_item, /* (applicantnum , type) */
//
___id : "liabilitiesObj"
}
})()
/**
* reo
* @namespace MAR.scenario
*/
var scenarioObj = (function(){
function cashout_ref_warning(LTV) {
if (MAR.is_refi() === false) return "";
let goal = getScenario_data("refi_goal" , false);
let value = getScenario_data("refi_current_value" , false);
let debt = getScenario_data("refi_current_debt" , false);
let options = getScenario_data("refi_options" , false);
let options_max = getScenario_data("refi_options_max" , false);
let ltv = (LTV) ? LTV : 0.85
if (goal === false) return "";
if (value === false) return "";
if (debt === false) return "";
if (ltv === false) return "";
if (options !== "cashout") return "";
let max = num(value) * num(ltv) - num(debt);
if (num(goal) > num(max) && MAR.isVaEligible() === false && options_max !== `Y`) {
return `You need more equity in the property to reach this goal, the max you can reach is ${MAR.format.format("cur",max)}`;
}
return "";
}
function assets_declared_too_low() {
if (MAR.is_refi() === true) return false;
let purchase_target = getScenario_data("purchase_target" , false);
let goals_target_downpayment_perc = getScenario_data("goals_target_downpayment_perc" , false);
let hb_liquid_assets = getScenario_data("hb_liquid_assets" , false);
if (purchase_target === false) return false;
if (goals_target_downpayment_perc === false) return false;
if (hb_liquid_assets === false) return false;
if (purchase_target > 0) {
let actualval = Math.round(num(purchase_target) * (num(goals_target_downpayment_perc)/100));
if (hb_liquid_assets < actualval) {
return true;
}
}
return false;
}
function check_is_cleared_mortgage_out_of_date() {
let da = getScenario_data(`cleared_mortgage_payoff_da`,``);
if (da === ``) return false;
let dat = moment(new Date(da));
let now = moment();
let diff_da = dat.diff(now, "days",true);
if (diff_da < 0) return diff_da;
return false;
}
function is_buying_agent() {
let da = getScenario_data(`buy_agent_yn`,``);
return (da === `Y`);
}
function set_mortgage_payoff_cleared_value(val, da = false, perdiem = false) {
/* -- put this in scenario -- */
setScenario_data(`refi_current_debt`,num(val));
setScenario_data(`cleared_mortgage_payoff_val`,num(val));
if (da !== false && da.trim().length > 0) {
setScenario_data(`cleared_mortgage_payoff_da`,da);
}
if (perdiem !== false && perdiem.trim().length > 0) {
setScenario_data(`cleared_mortgage_payoff_perdiem`,perdiem);
}
setScenario_data(`cleared_mortgage_payoff_ts`,new Date().getTime());
/* -- if refi , ignore -- */
if (MAR.is_refi() !== true) return false;
/* -- if there is no subject property return false -- */
let sp = MAR.reo.getSubjectProperty();
if (sp === false) return false;
/* -- if there is no linked loan , return -- */
if (sp.data.loanlinkA.length === 0) return false;
/* -- get the linked loan -- */
let loan = MAR.liabilities.getByUUID(sp.data.loanlinkA[0]);
if (loan === false || loan === null) return false;
if (num(loan.balance) !== num(val)) {
loan.balance_pre_cleared = loan.balance;
loan.balance = val;
return true;
}
return false;
}
return {
cashout_ref_warning : cashout_ref_warning,
assets_declared_too_low : assets_declared_too_low,
//
set_mortgage_payoff_cleared_value : set_mortgage_payoff_cleared_value,
check_is_cleared_mortgage_out_of_date : check_is_cleared_mortgage_out_of_date,
//
is_buying_agent : is_buying_agent,
//
___id : "scenario obj"
}
})();
/**
* reo
* @namespace MAR.reo
*/
var reoObj = (function(){
/**
* @memberof MAR.reo
*/
function init() {
if ("answers" in mar == false) mar.answers = {};
if ("v2" in mar.answers == false) mar.answers.v2 = {};
if ("reo" in mar.answers.v2 == false) mar.answers.v2.reo = [];
}
/**
* @memberof MAR.reo
*/
function explode_property_address(uuid) {
let property = getByUUID(uuid);
if (property === false) return false;
let zip = MAR.getOpt(addressFromString(property.address), "zip","");
if (zip === "") return false;
let da = MAR.zip2county_full(zip);
property.co_code = da.code;
property.co_name = da.name;
property.area = da.area;
return property;
}
/**
* @memberof MAR.reo
*/
function explode_property(property) {
let zip = MAR.getOpt(addressFromString(property.address), "zip","");
if (zip === "") return false;
let da = MAR.zip2county_full(zip);
property.co_code = da.code;
property.co_name = da.name;
property.area = da.area;
return property;
}
/**
* @memberof MAR.reo
*/
function explode_address(address) {
let property = {
address : address
};
let zip = MAR.getOpt(addressFromString(property.address), "zip","");
if (zip === "") return false;
let da = MAR.zip2county_full(zip);
property.co_code = da.code;
property.co_name = da.name;
property.area = da.area;
return property;
}
/**
* @memberof MAR.reo
*/
function set_scenario_county_from_address(uuid) {
let prop = explode_property_address(uuid);
if (prop === false) return;
let co_name_full = MAR.getOpt(prop, "co_name", "");
if (co_name_full === "") return;
setScenario_data("property_county", co_name_full);
}
/**
* @memberof MAR.reo
*/
function makePropertyTheSubjectUnverifiedSync() {
return new Promise(function(resolve, reject) {
makePropertyTheSubjectUnverified(function(rv){
resolve(rv);
})
});
}
/**
* @memberof MAR.reo
*/
function makePropertyTheSubjectUnverified(fn) {
let sp = getSubjectProperty();
if (sp === false) return;
if (typeof fs === "undefined") {
/**
* we are in the browser
*/
let adr = sp.data;
let _ad = addressFromString(adr.address);
mar.socket.send_and_receive("zip2county",{
zip : _ad.zip
}, function(retval){
let co_code = retval.data.code;
let co_name_full = retval.data.name;
let co_name = MAR.county_name(co_name_full);
let area = retval.data.area;
setScenario_data("property_county", co_name_full);
/**
* do not replace the property type for reverse webhook applications
*/
if (MAR.appnav.loanWasImportedAndNotVerified() !== true || getScenario_data("property_type","") === "") {
if (MAR.getOpt(adr, "property_type","") === "") {
setScenario_data("property_type", adr.property_type);
}
}
setScenario_data("property_details", {
streetAddress : _ad.address,
city : _ad.city,
state : _ad.state,
zip : _ad.zip,
countycode : co_code,
county : co_name
});
if (fn) fn();
});
return;
}
let adr = explode_property_address(sp.data.uuid);
let _ad = addressFromString(adr.address);
let co_code = adr.co_code;
let co_name_full = adr.co_name;
let co_name = MAR.county_name(co_name_full);
let area = adr.area;
setScenario_data("property_county", co_name_full);
if (MAR.getOpt(adr, "property_type","") === "") {
setScenario_data("property_type", adr.property_type);
}
setScenario_data("property_details", {
streetAddress : _ad.address,
city : _ad.city,
state : _ad.state,
zip : _ad.zip,
countycode : co_code,
county : co_name
});
if (fn) fn();
}
/**
* @memberof MAR.reo
*/
function makePropertyTheSubject() {
let sp = getSubjectProperty();
if (sp === false) return;
let adr = sp.data;
let verified = MAR.getOpt(adr, "verified","Y");
if (verified === "N") return;
if (MAR.getOpt(adr, "property_type","") === "") return;
if (MAR.getOpt(adr, "co_code","") === "") return;
if (MAR.getOpt(adr, "co_name","") === "") return;
let _ad = addressFromString(adr.address);
let co_code = adr.co_code;
let co_name_full = adr.co_name;
let co_name = MAR.county_name(co_name_full);
let area = adr.area;
console.log(adr);
debugger;
setScenario_data("property_county", co_name_full);
setScenario_data("property_type", adr.property_type);
// setScenarioData("build_period", "?");
// setScenarioData("property_type_community_options", "?");
// units getPropertyUnits_v2
// area
setScenario_data("property_details", {
streetAddress : _ad.address,
city : _ad.city,
state : _ad.state,
zip : _ad.zip,
countycode : co_code,
county : co_name
});
}
/**
* @memberof MAR.reo
*/
function getByUUID(uuid,ALSOID) {
let _array = get();
for (let i=0; i < _array.length; i++) {
if ("uuid" in _array[i] && _array[i].uuid == uuid) {
if (arguments.length > 1 && ALSOID === true) {
return {
i : i,
data : _array[i]
}
} else {
_array[i]._i = i;
return _array[i];
}
}
}
return false;
}
/**
* @memberof MAR.reo
*/
function setByUUID(uuid, obj) {
let ob = getByUUID(uuid);
if (ob !== false) {
for (let x in obj) {
ob[x] = obj[x]
}
MAR.activity_log.mod("reo", uuid);
}
}
/**
* @memberof MAR.reo
*/
function getBySIG(sig) {
let _array = this.get();
for (let i=0; i < _array.length; i++) {
if ("sig" in _array[i] && _array[i].sig == sig) return _array[i];
}
return false;
}
/**
* @memberof MAR.reo
*/
function getByREOID(reoid, ALSOID) {
let _array = this.get();
for (let i=0; i < _array.length; i++) {
if ("enc_reoid" in _array[i] && _array[i].enc_reoid == reoid) {
if (arguments.length > 1 && ALSOID === true) {
return {
i : i,
data : _array[i]
}
} else {
return _array[i];
}
}
}
return false;
}
/**
* @memberof MAR.reo
*/
function getByIndex(number) {
if ("answers" in mar == false) return false;
if ("v2" in mar.answers == false) return false;
if ("reo" in mar.answers.v2 == false) return false;
return mar.answers.v2.reo[number];
}
/**
* @memberof MAR.reo
*/
function get(number) {
if ("answers" in mar == false) return false;
if ("v2" in mar.answers == false) return false;
if ("reo" in mar.answers.v2 == false) return false;
if (arguments.length == 0) { // return the array for one applicant
return mar.answers.v2.reo;
}
if (typeof number == "string") number = parseInt(number,10);
if (number < mar.answers.v2.reo.length) {
return mar.answers.v2.reo[number];
}
return false;
}
/**
* @memberof MAR.reo
*/
function set(number, data) {
if (arguments.length >= 2) { // return the whole array
if ("answers" in mar == false) mar.answers = {};
if ("v2" in mar.answers == false) mar.answers.v2 = {};
if ("reo" in mar.answers.v2 == false) mar.answers.v2.assets = {};
if (number === false) {
if ("uuid" in data == false) data.uuid = uuidv4();
mar.answers.v2.reo.push(data);
MAR.activity_log.add("reo", data.uuid);
return (mar.answers.v2.reo.length -1);
} else {
if (typeof number == "string") number = parseInt(number,10);
if (mar.answers.v2.reo.length > number) {
if ("uuid" in mar.answers.v2.reo[number] == false) {
if ("uuid" in data == false) data.uuid = uuidv4();
// } else {
// data.uuid = mar.answers.v2.assets.items[number].uuid;
}
for (x in data) {
/**
* update only , don't overwrite!
*/
mar.answers.v2.reo[number][x] = data[x];
}
MAR.activity_log.mod("reo", mar.answers.v2.reo[number].uuid);
// mar.answers.v2.assets.items[number] = data;
return number;
}
}
}
}
/**
* @memberof MAR.reo
*/
function del(number) {
if (arguments.length < 0) return false;
if ("answers" in mar == false) return false;
if ("v2" in mar.answers == false) return false;
if ("reo" in mar.answers.v2 == false) return false;
if (number >= mar.answers.v2.reo.length) return false;
MAR.activity_log.del("reo", mar.answers.v2.reo[number].uuid);
mar.answers.v2.reo.splice(number, 1);
return true;
}
/**
* @memberof MAR.reo
*/
function getPropertiesByApplicant(n) {
init();
let reolist = mar.answers.v2.reo;
let reo_primary_index = false;
let rvlist = [];
for (let i=0; i < reolist.length; i++) {
if (MAR.getOpt(reolist[i],"whosname","").indexOf(`${n}`) > -1) {
reo_primary_index = i;
rvlist.push({
i : i,
data : reolist[i]
});
}
}
return rvlist;
}
/**
* @memberof MAR.reo
*/
function is_income_attached_to_property(uuid) {
init();
let reolist = mar.answers.v2.reo;
let properties = [];
for (let i=0; i < reolist.length; i++) {
let item = reolist[i];
let incomes = MAR.getOpt(item, `propertyinllc_incomes`,``).split(`,`);
if (MAR.getOpt(item,`propertyinllc`,``) === `Y`) {
let incomes = MAR.getOpt(item, `propertyinllc_incomes`,``).split(`,`);
if (incomes.indexOf(uuid) > -1) {
properties.push(reolist[i]);
}
}
}
return properties;
}
/**
* @memberof MAR.reo
*/
function getCurrentPrimary(n) {
init();
let reolist = mar.answers.v2.reo;
let reo_primary_index = false;
for (let i=0; i < reolist.length; i++) {
if (MAR.getOpt(reolist[i],"reo_use","") == "primary") {
if (MAR.getOpt(reolist[i],"whosname","").indexOf(`${n}`) > -1) {
reo_primary_index = i;
return {
i : i,
data : reolist[i]
}
}
}
}
return false;
}
/**
* @memberof MAR.reo
*/
function _set_reo_property_as_subject_if_matches_property_address() {
if (MAR.is_refi()) {
(function() {
let prop_addr_obj = MAR.getOpt(mar.answers, "v2.scenario.property_details", false);
if (prop_addr_obj === false) return; // no property in scenario
if (MAR.getOpt(prop_addr_obj,"zip", "") === "") return; // unlikely a proper addres if there is no ZIP code
let prop_addr_str = [
MAR.getOpt(prop_addr_obj,"streetAddress","").trim(),
MAR.getOpt(prop_addr_obj,"city","").trim(),
MAR.getOpt(prop_addr_obj,"state","").trim(),
MAR.getOpt(prop_addr_obj,"zip","").trim(),
MAR.getOpt(prop_addr_obj,"unit","").trim()
].join("|");
let reolist = mar.answers.v2.reo;
for (let i=0; i < reolist.length; i++) {
let item = reolist[i];
let addr_str = item.address;
if (typeof addr_str !== "string" || addr_str.trim().length === 0) continue; // exclude empty reo items
if (compareAddresses(addr_str,prop_addr_str)=== true) {
item.is_subject_property = "Y";
item._updated_by_1 = `_set_reo_property_as_subject_if_matches_property_address`;
}
}
})();
}
}
/**
* @memberof MAR.reo
*/
function getOrCreateSubjectProperty(n) {
_set_reo_property_as_subject_if_matches_property_address();
let sp = MAR.reo.getSubjectProperty();
// ensure there is a subject property
let refi = (getV2_data("loan_type","purchase") !== "purchase");
if (sp === false && refi === true) {
let reolist = mar.answers.v2.reo;
if (reolist.length > 0) {
sp = reolist[0];
sp.is_subject_property = "Y";
sp._updated_by = `getOrCreateSubjectProperty`;
} else {
sp = MAR.reo.create({});
sp.is_subject_property = "Y";
sp._created_by = `getOrCreateSubjectProperty`;
MAR.reo.set(false, sp);
}
sp = MAR.reo.getSubjectProperty();
}
return sp;
}
/**
* @memberof MAR.reo
*/
function getSubjectProperty(n) {
init();
let reolist = mar.answers.v2.reo;
for (let i=0; i < reolist.length; i++) {
if (MAR.getOpt(reolist[i],"is_subject_property","") == "Y") {
return {
i : i,
uuid : reolist[i].uuid,
data : reolist[i]
}
}
}
return false;
}
/**
* @memberof MAR.reo
*/
function isSubjectProperty(uuid) {
let sp = getSubjectProperty();
if (sp === false) return false;
if (uuid === sp.uuid) return true;
return false;
}
/**
* @memberof MAR.reo
*/
function getNextUnverifiedItem() {
let _array = get();
for (let i=0; i < _array.length; i++) {
if ("verified" in _array[i] == true && _array[i].verified === "N") {
return {
i : i,
uuid : _array[i].uuid
}
}
}
return false;
}
/**
* @memberof MAR.reo
*/
function isAnythingVerified() {
let _array = get();
for (let i=0; i < _array.length; i++) {
if ("verified" in _array[i] == true && _array[i].verified === "Y") {
return true;
}
}
return false;
}
/**
* @memberof MAR.reo
*/
function create(obj /*type, address, owner, verified */) {
let _newreo = {};
if ("address" in obj) {
if (typeof obj.address === "string") {
_newreo.address = obj.address;
} else {
_newreo.address = `${MAR.getOpt(obj.address,"address","")}|`+
`${MAR.getOpt(obj.address,"city","")}|`+
`${MAR.getOpt(obj.address,"state","")}|`+
`${MAR.getOpt(obj.address,"zip","")}|`+
``;
}
}
_newreo.reo_use = MAR.getOpt(obj , "type" , "primary");
_newreo.verified = MAR.getOpt(obj , "verified" , "N");
_newreo.whosname = `${MAR.getOpt(obj , "owner" ,"0")}`;
return _newreo;
}
/**
* @memberof MAR.reo
*/
function prop(n , data, def) {
init();
let reolist = mar.answers.v2.reo;
if (reolist.length <= n) return def
let item = reolist[n];
if (data == "tax") return num(MAR.getOpt(item, "loan_tax", def));
if (data == "hoi") return num(MAR.getOpt(item, "loan_insurance", def));
if (data == "hoa") {
if (MAR.getOpt(item, "loan_hoa", false) === false) {
return def;
}
let loan_hoa_freq = num(MAR.getOpt(item, "loan_hoa_freq", "1"));
let loan_hoa = num(MAR.getOpt(item, "loan_hoa", 0));
return (loan_hoa/loan_hoa_freq);
}
return def;
}
function will_display_list_item(item){
if (MAR.getOpt(item, "whosname","") === "") {
item.verified2 = "N";
item.syncnote = `Can you check the ownership on this property please.`;
item.syncsecs = "0";
}
if ("enc_maintenance_C" in item && "enc_maintenance_A" in item) {
if (typeof item.enc_maintenance_C !== "undefined") { // first time through B is undefined
if (num(item.enc_maintenance_A) != num(item.enc_maintenance_C)) {
item.verified2 = "N";
item.syncnote = `Can you check whether the hoa, insurance or tax are correct please.`;
item.syncsecs = "1";
}
}
}
}
function will_display_list(){
if ("reo" in mar.answers.v2 === false) mar.answers.v2.reo = []; // empty REO
let reolist = mar.answers.v2.reo;
for (let i=0; i < reolist.length; i++) {
let item = reolist[i];
will_display_list_item(item);
}
}
function reo_primary_index_fn(i) {
if ("reo" in mar.answers.v2 === false) mar.answers.v2.reo = []; // empty REO
let reolist = mar.answers.v2.reo;
let reo_primary_index = false;
let property_index = false;
for (let j=0; j < reolist.length; j++) {
if (MAR.getOpt(reolist[j],"reo_use","") == "primary") {
if (MAR.getOpt(reolist[j],"whosname","").indexOf(`${i}`) > -1) {
reo_primary_index = j;
property_index = j;
}
} else {
if (MAR.getOpt(reolist[j],"whosname","").indexOf(`${i}`) > -1) {
property_index = j;
}
}
}
// console.warn(`reo_primary_index ${reo_primary_index}`);
// console.warn(`MAR.ownsProperty(${i}) ${MAR.ownsProperty(0)}`);
return reo_primary_index;
}
function normalizeAddress(ad){
if (typeof ad !== "string") return "";
let parts = ad.split("|");
for (let i=0; i < parts.length; i++) {
parts[i] = parts[i].trim().toLowerCase()
}
while (parts.length < 5) {
parts.push("");
}
while (parts.length > 5) {
parts.pop();
}
return parts.join("|");
}
function compareAddresses(ad1,ad2) {
return (normalizeAddress(ad1) === normalizeAddress(ad2));
}
/* -- appnum is the applicant number ad it returns the uuid of the liability containing the mortgage */
function suggest_unconnected_mortgage(appnum) {
let sug = suggest();
for (let i=0; i < sug.length; i++) {
let _sug = sug[i];
if (MAR.getOpt(_sug, `applicant`, -1) !== appnum) continue; /* not the same applicant */
if (MAR.getOpt(_sug, `suggestion`, ``) !== `unconnectedmortgage`) continue; /* not an unconnected mortgage */
let mortgages = MAR.getOpt(_sug, `mortgages`,false); /* abc-123 : { ... json data ... } */
for (let x in mortgages) {
return x;
}
}
return false;
}
function suggest() {
/**
* returns ::
* borrower 0,
* sugestedprimary "address"
*/
let retval = [];
tidyUpReoMortgageLinks();
if ("reo" in mar.answers.v2 === false) mar.answers.v2.reo = []; // empty REO
let reolist = MAR.getOpt(mar.answers.v2, `reo`,[]);
// for (let j=0; j < reolist.length; j++) {
// let whosname = MAR.getOpt(reolist[j],"whosname","");
// if (whosname === "") {
// let ad = reolist[j].address;
// retval.push({
// applicant : 0,
// suggestion : "propertywithnoowner",
// ad : ad
// })
// }
// }
if (typeof mar.answers.v2.applicants === `undefined`) {
return retval;
}
for (let i=0; i < mar.answers.v2.applicants.length; i++) {
/**
* determine if there is a primary and end up with
*
* reo_primary_index - index of primary property
* property_index - same index but of any type of property
*/
let reo_primary_index = false;
let property_index = false;
let spouse = MAR.getApplicantsSpouse(i);
for (let j=0; j < reolist.length; j++) {
if (MAR.getOpt(reolist[j],"reo_use","") == "primary") {
if (MAR.getOpt(reolist[j],"whosname","").indexOf(`${i}`) > -1) {
reo_primary_index = j;
property_index = j;
} else if (spouse !== false) {
if (MAR.getOpt(reolist[j],"whosname","").indexOf(`${spouse}`) > -1) {
reo_primary_index = j;
property_index = j;
}
}
} else {
if (MAR.getOpt(reolist[j],"whosname","").indexOf(`${i}`) > -1) {
property_index = j;
} else if (spouse !== false) {
if (MAR.getOpt(reolist[j],"whosname","").indexOf(`${spouse}`) > -1) {
property_index = j;
}
}
}
}
// here also check for the spouse
//MAR.getApplicants_JointApplicant
// console.warn(`reo_primary_index ${reo_primary_index}`);
// console.warn(`MAR.ownsProperty(${i}) ${MAR.ownsProperty(0)}`);
if (reo_primary_index === false) { // we did not find a primary REO property
if (MAR.ownsPrimary(i) == true) { // if we current own realestate , create a new REO block
let a_current = MAR.getApplicantAddressCurrent(i);
if (a_current && a_current.length > 0) {
// retval.push({
// applicant : i,
// suggestion : "add",
// address : a_current[0].address
// })
(function add_to_reo(){
/**
* check for duplicates
*/
let address_to_add = a_current[0].address;
for (let j=0; j < reolist.length; j++) {
let item_address = MAR.getOpt(reolist[j], "address",false);
if (typeof item_address !== "string") {
item_address = MAR.getOpt(reolist[j], "address.address","");
}
if (item_address === address_to_add) {
address_to_add = false;
property_index = j;
break;
}
}
if (address_to_add === false) { /* this is a duplicate */
return;
}
/**
* Add property
*/
let newproperty = MAR.reo.create({
type : "primary",
owner : i,
address : {
address : a_current[0].address
},
verified : "N"
});
if (MAR.is_refi()) {
newproperty.reo_use = "primary";
newproperty.reo_use2 = "primary";
newproperty.property_type = mar.answers.v2.scenario.property_type;
newproperty.value = mar.answers.v2.scenario.refi_current_value;
newproperty.is_subject_property = (MAR.reo.getSubjectProperty() === false) ? "Y" : "N";
}
property_index = MAR.reo.set(false, newproperty);
})()
}
}
} else /* we have a primary */ {
if (MAR.ownsPrimary(i) == false) { // if we current own realestate
let a_current = MAR.getApplicantAddressCurrent(i);
if (a_current && a_current.length > 0) {
let ad1 = a_current[0].address;
let ad2 = reolist[reo_primary_index].address;
retval.push({
applicant : i,
suggestion : "check2",
ad1 : ad1,
ad2 : ad2,
reo_primary_index : reo_primary_index
})
}
} else {
let a_current = MAR.getApplicantAddressCurrent(i);
if (a_current && a_current.length > 0) {
let ad1 = a_current[0].address;
let ad2 = reolist[reo_primary_index].address;
if (compareAddresses(ad1,ad2) === false) {
retval.push({
applicant : i,
suggestion : "check",
ad1 : ad1,
ad2 : ad2,
reo_primary_index : reo_primary_index
})
}
}
}
/**
* now check is the primary is to sell and if this matched NPRF
*/
if (MAR.getOpt(reolist[reo_primary_index], "reo_use2","") === "sell") {
let asset = MAR.assets.get("nprf");
if (asset.length === MAR.zero("no assets")) {
if (MAR.getOpt(reolist[reo_primary_index], "reo_override_nprf","") !== "Y") {
let calculated_nprf = num(MAR.getOpt(reolist[reo_primary_index], "CALC_NPRF",0));
retval.push({
applicant : i,
suggestion : "no_nprf",
ad : reolist[reo_primary_index].address,
calculated_nprf : calculated_nprf,
reo_primary_index : reo_primary_index
})
}
}
if (asset.length > MAR.zero("we have assets")) {
if (MAR.getOpt(reolist[reo_primary_index], "reo_override_nprf","") !== "Y") {
let calculated_nprf = num(MAR.getOpt(reolist[reo_primary_index], "CALC_NPRF",0));
let entered_nprf = num(asset[0].val);
if (calculated_nprf != entered_nprf) {
let ad2 = reolist[reo_primary_index].address;
retval.push({
applicant : i,
suggestion : "diff_nprf",
ad : reolist[reo_primary_index].address,
salesprice : reolist[reo_primary_index].reo_expected_salesprice,
salesperc : reolist[reo_primary_index].reo_expected_salesperc,
loanbalance : reolist[reo_primary_index].LOANBALANCE,
calculated_nprf : calculated_nprf,
entered_nprf : entered_nprf,
assetIndex : asset[0]._i,
reo_primary_index : reo_primary_index
})
}
}
}
}
}
if (property_index === false) {
if (MAR.ownsProperty(i) == true) {
retval.push({
applicant : i,
suggestion : "noproperty"
})
}
}
}
if (MAR.getOpt(mar.answers.v2, "liabilities", null) === null) {
mar.answers.v2.liabilities = [];
}
mar.answers.v2.liabilities.filter(function(item){
if (item.type === "mortgage" || item.type === "heloc") {
if (MAR.getOpt(item,"reolink","") === "") {
if (MAR.getOpt(item, "attached_llc", "") === "Y") return;
let mi = {};
mi[item.uuid] = item;
retval.push({
applicant : 0,
suggestion : "unconnectedmortgage",
mortgages : mi
})
}
}
})
let sp = MAR.reo.getSubjectProperty();
if (sp !== false) {
let spd = sp.data;
if (MAR.getOpt(spd, "verified", "") === "N") {
if (MAR.is_refi()) {
MAR.ifOpt(mar, "answers.v2.scenario.refi_taxes", function(v){
MAR.reo.setByUUID(sp.uuid, { monthly_includes_taxes : MAR.getOpt(mar, "answers.v2.scenario.refi_current_pmt_includes","N")});
MAR.reo.setByUUID(sp.uuid, { loan_tax : num(v) });
});
MAR.ifOpt(mar, "answers.v2.scenario.refi_current_value", function(v){
MAR.reo.setByUUID(sp.uuid, { value : num(v) });
// MAR.reo.setByUUID(sp.uuid, { purchase_price : num(v) });
});
MAR.ifOpt(mar, "answers.v2.scenario.monthly_rent", function(v){
MAR.reo.setByUUID(sp.uuid, { reo_expected_rental : num(v) });
MAR.reo.setByUUID(sp.uuid, { reo_rental_pm : num(v) });
});
MAR.ifOpt(mar, "answers.v2.scenario.property_type", function(v){
MAR.reo.setByUUID(sp.uuid, { property_type : v });
});
MAR.ifOpt(mar, "answers.v2.scenario.hoa_estimate", function(v){
if (num(v) > 0) {
MAR.reo.setByUUID(sp.uuid, { loan_hoa : num(v)*12 });
MAR.reo.setByUUID(sp.uuid, { has_hoa : `Y` });
} else {
MAR.reo.setByUUID(sp.uuid, { has_hoa : `N` });
}
});
MAR.ifOpt(mar, "answers.v2.scenario.refi_home_insurance_cost", function(v){
MAR.reo.setByUUID(sp.uuid, { has_insurance : `Y` });
MAR.reo.setByUUID(sp.uuid, { monthly_includes_insurance : MAR.getOpt(mar, "answers.v2.scenario.refi_current_pmt_includes_ins","N") });
MAR.reo.setByUUID(sp.uuid, { loan_insurance : num(v) });
});
MAR.ifOpt(mar, "answers.v2.scenario.refi_current_debt_mdate", function(v){
MAR.reo.setByUUID(sp.uuid, { purchasedate : v });
});
// let refi_current_debt = getScenario_data("refi_current_debt","");
// let refi_current_value = getScenario_data("refi_current_value","");
// let refi_liquid_assets = getScenario_data("refi_liquid_assets","");
// let goals_target_budget = getScenario_data("goals_target_budget_old","");
// let refi_current_escrow = getScenario_data("refi_current_escrow","");
// let refi_current_debt_mdate = getScenario_data("refi_current_debt_mdate","");
// let refi_taxes = getScenario_data("refi_taxes","");
// let refi_home_insurance_cost= getScenario_data("refi_home_insurance_cost","");
// let hoa_estimate = getScenario_data("hoa_estimate","");
}
}
}
// let mortgagesIndexed = {};
//
// let mortgages = mar.answers.v2.liabilities.filter(function(item){
// if (item.type === "mortgage") {
// mortgagesIndexed[item.uuid] = item;
// return true;
// }
// return false;
// })
// for (let i=0; i < reolist.length; i++) {
// let loanlink = MAR.getOpt(reolist[i],"loanlink","");
// if (loanlink !== "") {
// if (loanlink in mortgagesIndexed) {
// delete mortgagesIndexed[loanlink];
// }
// }
// }
// if (Object.keys(mortgagesIndexed).length > 0) {
// retval.push({
// applicant : 0,
// suggestion : "unconnectedmortgage",
// mortgages : mortgagesIndexed
// })
// }
return retval;
}
function setMortgageOptionsFromReoLinks(ans = false) {
if (ans !== false) mar.answers = ans;
function getReoByUUID(ID) {
let reolist = MAR.getOpt(mar, "answers.v2.reo", []);
for (let i=0; i < reolist.length; i++) {
let item = reolist[i];
if (item.uuid === ID) return item;
}
}
let reo_array = {};
for (var i=0; i < mar.answers.v2.liabilities.length; i++) {
var item = mar.answers.v2.liabilities[i];
if (!item || item == null) continue;
if (item.type == "mortgage" || item.type == "heloc") {
if ("reolink" in item && item.reolink !== "") {
if (item.reolink in reo_array === false) {
reo_array[item.reolink] = [];
}
reo_array[item.reolink].push(item.uuid);
}
}
}
let reolist = MAR.getOpt(mar, "answers.v2.reo", []);
for (let i=0; i < reolist.length; i++) {
let item = reolist[i];
let _uuid = item.uuid;
if (_uuid in reo_array) {
item.mortgageoptions = reo_array[_uuid].join(",");
console.log(`JC setting mo to [${item.mortgageoptions}] on ${_uuid}`);
} else {
/* -- make sure we leave free and nl alone -- */
let mo = MAR.getOpt(item, `mortgageoptions`,``);
if (mo === `` || typeof mo !== `string` || mo.indexOf(`-`) > -1) {
item.mortgageoptions = ``;
console.log(`JC setting mo to [${item.mortgageoptions}] on ${_uuid}`);
}
}
}
// for (let x in reo_array) {
// let R = getReoByUUID(x);
// R.mortgageoptions = reo_array[x].join(",");
// }
}
function tidyOverrides() {
if (MAR.getOpt(mar, "answers.v2.liabilities", null) === null) return;
for (var i=0; i < mar.answers.v2.liabilities.length; i++) {
var item = mar.answers.v2.liabilities[i];
item._balance = item.balance;
item._monthly = item.monthly;
(function() {
let ovr = MAR.getOpt(item, `over`,``);
if (ovr === `Y`) {
item._balance = MAR.getOptNum(item, `over_balance`,item.balance);
item._monthly = MAR.getOptNum(item, `over_monthly`,item.monthly);
}
})();
}
}
function tidyUpReoMortgageLinks() {
tidyOverrides();
function getReoByLoanId(ID) {
let reolist = MAR.getOpt(mar, "answers.v2.reo", []);
for (let i=0; i < reolist.length; i++) {
let item = reolist[i];
if ("mortgageoptions" in item) {
if (typeof item.mortgageoptions === "string" && item.mortgageoptions !== "" && item.mortgageoptions !== "free" && item.mortgageoptions !== "nl") {
let mo = item.mortgageoptions.split(",");
item.loanlink = item.mortgageoptions;
item.loanlinkA = mo;
if (mo.indexOf(ID) > -1) return item.uuid;
} else {
item.loanlink = "";
item.loanlinkA = [];
}
}
}
return false;
}
if (MAR.getOpt(mar, "answers.v2.liabilities", null) === null) return;
for (var i=0; i < mar.answers.v2.liabilities.length; i++) {
var item = mar.answers.v2.liabilities[i];
if (!item || item == null) continue;
if (item.type == "mortgage" || item.type == "heloc") {
let reoitem = getReoByLoanId(item.uuid);
if (reoitem === false) {
item.reolink = ``;
// MAR.delOpt(item, "reolink");
} else {
item.reolink = reoitem;
}
}
}
}
/**
* @memberof MAR.reo
*/
function is_rent_roll_analysis_needed() {
let _array = get();
for (let i=0; i < _array.length; i++) {
let _reoitem = _array[i];
if ((MAR.getOpt(_reoitem,"skip_nodoc")===false) && (MAR.getOpt(_reoitem, "reo_rental_future_contract", "") === "N") && (MAR.getOpt(_reoitem, "reo_rental_future_contract_rentroll", "") ==="Y")) {
return true;
}
if ((MAR.getOpt(_reoitem,"skip_nodoc")===false) && (MAR.getOpt(_reoitem, "_vacating_primary", "") ==="Y")) {
return true;
}
}
return false;
}
function calc_income_from_1040(_reo) {
let reo_rental_income_on_tax_returns = MAR.getOpt(_reo, `reo_rental_income_on_tax_returns`, false);
if (reo_rental_income_on_tax_returns === false || reo_rental_income_on_tax_returns !== `Y`) {
return false;
}
let sche_opt = MAR.getOpt(_reo, `sche_opt`, false);
if (sche_opt === false) {
return false;
}
let sche_months = MAR.getOptNum(_reo, `sche_months`, 0);
if (sche_months === 0) {
return false;
}
if (_reo.sche_opt === `opt_1040`) {
let inc = MAR.getOptNum(_reo, `sche_income`, 0) +
MAR.getOptNum(_reo, `sche_royalties`, 0) +
MAR.getOptNum(_reo, `sche_ins`, 0) +
MAR.getOptNum(_reo, `sche_mint`, 0) +
MAR.getOptNum(_reo, `sche_oint`, 0) +
MAR.getOptNum(_reo, `sche_tax`, 0) +
MAR.getOptNum(_reo, `sche_depr`, 0) +
0;
let uinc = inc - MAR.getOptNum(_reo, `sche_total`, 0);
let m_uinc = uinc / sche_months;
return m_uinc;
}
if (_reo.sche_opt === `opt_est`) {
let inc = MAR.getOptNum(_reo, `sche_income`, 0);
let costs = 0;
costs += MAR.getOptNum(_reo, `sche_adv`, 0);
costs += MAR.getOptNum(_reo, `sche_auto`, 0);
costs += MAR.getOptNum(_reo, `sche_clean`, 0);
costs += MAR.getOptNum(_reo, `sche_comm`, 0);
costs += MAR.getOptNum(_reo, `sche_legal`, 0);
costs += MAR.getOptNum(_reo, `sche_man`, 0);
costs += MAR.getOptNum(_reo, `sche_rep`, 0);
costs += MAR.getOptNum(_reo, `sche_supp`, 0);
costs += MAR.getOptNum(_reo, `sche_util`, 0);
costs += MAR.getOptNum(_reo, `sche_other`, 0);
let uinc = inc - costs
let m_uinc = uinc / sche_months;
return m_uinc;
}
return false;
}
function calc_income_from_8825(_reo) {
let reo_rental_income_on_tax_returns = MAR.getOpt(_reo, `reo_rental_income_on_tax_returns`, false);
if (reo_rental_income_on_tax_returns === false || reo_rental_income_on_tax_returns !== `Y`) {
return false;
}
let f8825_opt = MAR.getOpt(_reo, `f8825_opt`, false);
if (f8825_opt === false) {
return false;
}
if (f8825_opt !== `opt_est`) {
return false;
}
return false;
let f8825_months = MAR.getOptNum(_reo, `f8825_months`, 0);
if (f8825_months === 0) {
return false;
}
if (_reo.f8825_opt === `opt_est`) {
let inc = MAR.getOptNum(_reo, `f8825_income`, 0);
let costs = 0;
costs += MAR.getOptNum(_reo, `f8825_other`, 0);
let uinc = inc - costs
let m_uinc = uinc / f8825_months;
return m_uinc;
}
return false;
}
return {
init : init,
getByUUID : getByUUID,
getByREOID : getByREOID,
getByIndex : getByIndex,
setMortgageOptionsFromReoLinks : setMortgageOptionsFromReoLinks,
setByUUID : setByUUID,
tidyUpReoMortgageLinks : tidyUpReoMortgageLinks,
tidyOverrides : tidyOverrides,
makePropertyTheSubject : makePropertyTheSubject,
makePropertyTheSubjectUnverified : makePropertyTheSubjectUnverified,
makePropertyTheSubjectUnverifiedSync : makePropertyTheSubjectUnverifiedSync,
//
explode_property_address : explode_property_address,
explode_property : explode_property,
explode_address : explode_address,
set_scenario_county_from_address : set_scenario_county_from_address,
//
compareAddresses : compareAddresses,
//
get : get,
set : set,
del : del,
suggest : suggest,
reo_primary_index_fn : reo_primary_index_fn,
will_display_list : will_display_list,
will_display_list_item : will_display_list_item,
create : create,
getCurrentPrimary : getCurrentPrimary,
getPropertiesByApplicant : getPropertiesByApplicant,
getSubjectProperty : getSubjectProperty,
getOrCreateSubjectProperty : getOrCreateSubjectProperty,
isSubjectProperty : isSubjectProperty,
getNextUnverifiedItem : getNextUnverifiedItem,
isAnythingVerified : isAnythingVerified,
is_rent_roll_analysis_needed : is_rent_roll_analysis_needed,
prop : prop,
// -- the 1040 --
calc_income_from_1040 : calc_income_from_1040,
calc_income_from_8825 : calc_income_from_8825,
//
is_income_attached_to_property : is_income_attached_to_property, /* is an income linked to a property, or properties */
//
// Helper for conditions
//
suggest_unconnected_mortgage : suggest_unconnected_mortgage,
//
___id : "reoObj"
}
})()
var permissionsObj = (function(){
let xsd = {
realtor_permission_loan_calcs_and_docs : "realtor_permission_loan_calcs_and_docs",
realtor_permission_direct_underwriting_report : "realtor_permission_direct_underwriting_report",
realtor_permission_appraisal_information : "realtor_permission_appraisal_information",
}
let pms = {};
let pm = "";
pm = "realtor_permission_loan_calcs_and_docs";
pms[pm] = {};
pms[pm].desc = {
Y : "The client GAVE permission to share calculations and loan documentation with the realtor ",
N : "The client DECLINED to give permissiont o share calculations and loan documentation with the realtor"
};
pm = "realtor_permission_direct_underwriting_report";
pms[pm] = {};
pms[pm].desc = {
Y : "The client GAVE permission to share direct underwriting reports with the realtor ",
N : "The client DECLINED to direct underwriting reports with the realtor"
};
pm = "realtor_permission_appraisal_information";
pms[pm] = {};
pms[pm].desc = {
Y : "The client GAVE permission to share appraisal information with the realtor ",
N : "The client DECLINEDm1 to give permission to share appraisal information with the realtor"
};
function _get(p,val) {
return MAR.getOpt(pms, `${p}.desc.${val}`,false)
}
function makePermsForSummary(ans) {
let perms = [];
let _plcd = MAR.getOpt(ans, "v2.scenario.realtor_permission_loan_calcs_and_docs","");
let _pdur = MAR.getOpt(ans, "v2.scenario.realtor_permission_direct_underwriting_report","");
let _pai = MAR.getOpt(ans, "v2.scenario.realtor_permission_appraisal_information","");
if (_plcd !== "") {
perms.push(MAR.perms.get("realtor_permission_loan_calcs_and_docs",_plcd));
}
if (_pdur !== "") {
perms.push(MAR.perms.get("realtor_permission_direct_underwriting_report",_pdur));
}
if (_pai !== "") {
perms.push(MAR.perms.get("realtor_permission_appraisal_information",_pai));
}
if (perms.length == 0) {
return "";
}
return "Realtor permissons :
" +perms.join("
") + "
";
}
return {
pms : pms,
xsd : xsd,
get : _get,
makePermsForSummary : makePermsForSummary,
___id : "permission"
}
})()
/**
* addresshist
* @namespace addresshist
*/
var addressObj = (function(){
/**
* @memberof addresshist
*/
function init(){
}
function set(i, item) {
console.log(`ADDRESSHIST_SET i[${i}] item[${JSON.stringify(item)}]`);
if (i < 0) return false;
if ("__pre_uuid" in item == true) {
item.uuid = item.__pre_uuid;
let bucketid = `/applicants/address/${i}/${item.uuid}`
item.bucketid = bucketid;
delete item.__pre_uuid;
}
if ("uuid" in item === false) {
let uuid = uuidv4();
let bucketid = `/applicants/address/${i}/${uuid}`
item.uuid = uuid;
item.bucketid = bucketid;
}
if ("addresses" in mar.answers.v2.applicants[i] === false) mar.answers.v2.applicants[i].addresses = [];
let idx = mar.answers.v2.applicants[i].addresses.indexOf(item.bucketid);
if (idx < 0) {
mar.answers.v2.applicants[i].addresses.push(item.bucketid);
}
if (item.bucketid in mar.answers.v2.buckets === false) mar.answers.v2.buckets[item.bucketid] = {};
let bucket = mar.answers.v2.buckets[item.bucketid];
for (x in item) {
bucket[x] = item[x];
}
return item;
}
function getByUUID(uuid) {
for (x in mar.answers.v2.buckets) {
// `/applicants/address/${i}/${uuid}`
if (x.startsWith(`/applicants/address/`) && x.endsWith(`/${uuid}`)) return mar.answers.v2.buckets[x]
}
return false;
}
function delByUUID(uuid) {
for (x in mar.answers.v2.buckets) {
// `/applicants/address/${i}/${uuid}`
if (x.startsWith(`/applicants/address/`) && x.endsWith(`/${uuid}`)) {
for (let i=0; i < mar.answers.v2.applicants.length; i++) {
let adresses = MAR.getOpt(mar.answers.v2.applicants[i], "addresses",[]);
let idx = adresses.indexOf(x);
if (idx > -1) mar.answers.v2.applicants[i].addresses.splice(idx,1);
}
}
}
}
return {
init : init,
set : set,
getByUUID : getByUUID,
delByUUID : delByUUID,
____id : "address object"
}
})()
/**
* assets
* @namespace MAR.assets
*/
var activity_logObj = (function(){
function add(type, uuid, e1, e2, e3) {
let role = (typeof __ROLE === "string") ? __ROLE : "norole";
if (role.length === 0) role = "norole";
if (arguments.length > 2) uuid = `${uuid} ${e1}`;
if (arguments.length > 3) uuid = `${uuid} ${e2}`;
if (arguments.length > 4) uuid = `${uuid} ${e3}`;
MAR.pushOpt(mar.answers, "_activity_log", `${role} ${type} add ${uuid}`);
}
function del(type, uuid, e1, e2, e3) {
let role = (typeof __ROLE === "string") ? __ROLE : "norole";
if (role.length === 0) role = "norole";
if (arguments.length > 2) uuid = `${uuid} ${e1}`;
if (arguments.length > 3) uuid = `${uuid} ${e2}`;
if (arguments.length > 4) uuid = `${uuid} ${e3}`;
MAR.pushOpt(mar.answers, "_activity_log", `${role} ${type} delete ${uuid}`);
}
function mod(type, uuid, e1, e2, e3) {
let role = (typeof __ROLE === "string") ? __ROLE : "norole";
if (role.length === 0) role = "norole";
if (arguments.length > 2) uuid = `${uuid} ${e1}`;
if (arguments.length > 3) uuid = `${uuid} ${e2}`;
if (arguments.length > 4) uuid = `${uuid} ${e3}`;
MAR.pushOpt(mar.answers, "_activity_log", `${role} ${type} modify ${uuid}`);
}
return {
add : add,
del : del,
mod : mod,
modify : mod,
update : mod,
___id : "activity log"
}
})();
/**
* supdata
* @namespace MAR.supdata
*/
var supdataObj = (function(){
function tp_from_code(code) {
if (code.indexOf("_TP.") > -1) {
let TP = code.substring(code.indexOf("_TP.")).split(" ")[0].split("/")[0];
if (TP !== "") {
return TP;
}
}
return "";
}
function Y(tp) { // _TP.24.12 (return 12)
if (typeof tp !== "string") return false;
let tps = tp.split(".");
if (tps.length < 3) return false;
return tps[1];
}
function M(tp) { // _TP.24.12 (return 24)
if (typeof tp !== "string") return false;
let tps = tp.split(".");
if (tps.length < 3) return false;
return tps[2];
}
/**
* return false / or Object
* {
* decr = decrement;
* period_end_day = period_end_day;
* dom = dom;
* rv.y = y;
* rv.m = m;
* rv.dec_m = dec_m;
* rv.sd = `20${start_y}-${dp2(start_m)}-${dp2(num(_period_end_day(start_m,period_end_day)))}`;
* rv.sd = moment(rv.sd).add(1,"day").format("YYYY-MM-DD");
* rv.ed = `20${end_y}-${dp2(end_m)}-${dp2(num(_period_end_day(end_m,period_end_day)))}`;
*
* parameters
* ----------
* tp = _TP.24.12 -- TP string
* days = 30 -- Number of days of history needed
* period_end_day = 31 -- Works out if that day has passed compared to today
* PERIOD = `monthly` -- Normal
* `quarterly` -- Jan-Mar / Apr-Jun / Jul-Sep / Oct-Dec
*
*
*/
function range(tp, days=30 , period_end_day = 31, PERIOD = "monthly") {
let y = Y(tp);
let m = M(tp);
if (y === false || m === false) {
return false;
}
let Moment = (typeof context === "object") ? context.global.moment : moment;
/**
* y 24
* m 12
*/
let dp2 = function(n) {
if (n < 10) return `0${n}`;
return `${n}`;
}
let _period_end_day = function(m , d) {
let rv = d;
if (num(d) > 31) rv = 31;
if (num(m) === 4 && rv > 30) return 30;
if (num(m) === 6 && rv > 30) return 30;
if (num(m) === 9 && rv > 30) return 30;
if (num(m) === 11 && rv > 30) return 30;
if (num(m) === 2 && rv > 28) return 28;
return rv;
}
let dom = new Date().getDate(); // todays day of month
let dow = new Date().getDay(); // 0 = Sunday, 1 = Monday, 2 = Tuesday etc..
let week_nr = num(Moment().format(`W`));
let rv = {};
if (PERIOD === "weekly") {
if (dow === 0) {
weekly_period_end_day = dom;
} else {
weekly_period_end_day = dom - dow;
}
if (weekly_period_end_day < 0) {
if (m === 1) {
period_end_day = 31 + weekly_period_end_day;
} else {
period_end_day = _period_end_day(m-1, 40) + weekly_period_end_day;
}
} else {
period_end_day = weekly_period_end_day;
}
// let weekly_period_end_day = (~~(dom/3) * 3); // 0 , 7 , 14, 21, 28
//
// if (weekly_period_end_day === 0) {
// period_end_day = 31;
// } else {
// period_end_day = weekly_period_end_day;
// }
}
if (PERIOD === "biweekly") {
if (dow === 0) {
weekly_period_end_day = dom;
} else {
weekly_period_end_day = dom - dow;
}
if (week_nr%2 === 0) {
weekly_period_end_day -= 7;
}
if (weekly_period_end_day < 0) {
if (m === 1) {
period_end_day = 31 + weekly_period_end_day;
} else {
period_end_day = _period_end_day(m-1, 40) + weekly_period_end_day;
}
} else {
period_end_day = weekly_period_end_day;
}
}
if (PERIOD === "semimonthly") {
if (dom < 15) {
period_end_day = 31;
} else {
period_end_day = 15;
}
}
let decrement = 0;
if (num(period_end_day) > dom) { // if period_end_day = 15 and day = 12, decrement = 1 (Last Month)
decrement = 1;
}
let end_m = num(m) - decrement; // Either this month, or last month (If we did not hit the period end day)
let end_y = num(y);
if (end_m < 1) {
end_y--;
end_m+=12;
}
if (PERIOD === "quarterly") {
if (num(m) % 3 !== 1) { // if NOT 1 , 4 , 7, 10
end_m = Math.floor((num(m)-1)/3)*3; // 2 = (2-1) = 1 / 3 = 0.3 floor = 0 * 3 = 0
// 3 = (3-1) = 2 / 3 = 0.6 floor = 0 * 3 = 0
if (end_m < 1) {
end_y--;
end_m+=12;
}
}
}
let dec_m = (~~(days/30)); // 60 = 2 , 750 = 24
if (dec_m === 0) dec_m = 1; // at least 1
if (PERIOD === "quarterly") {
dec_m = 3;
period_end_day = 31;
}
let start_m = num(end_m) - dec_m; // startm = (end_m=11) - 2 = 9 or =24 = -
let start_y = num(end_y);
rv.start_m_1 = start_m;
rv.start_y_1 = start_y;
if (start_m < -37) {
start_y--;
start_m+=12;
start_y--;
start_m+=12;
start_y--;
start_m+=12;
start_y--;
start_m+=12;
}
else if (start_m < -25) {
start_y--;
start_m+=12;
start_y--;
start_m+=12;
start_y--;
start_m+=12;
}
else if (start_m < -13) {
start_y--;
start_m+=12;
start_y--;
start_m+=12;
}
else if (start_m < 1) {
start_y--;
start_m+=12;
}
rv.start_m_2 = start_m;
rv.start_y_2 = start_y;
rv.decr = decrement;
rv.period_end_day = period_end_day;
rv.dom = dom;
rv.y = y;
rv.m = m;
rv.dec_m = dec_m;
rv.sd = `20${start_y}-${dp2(start_m)}-${dp2(num(_period_end_day(start_m,period_end_day)))}`;
rv.sd = moment(rv.sd).add(1,"day").format("YYYY-MM-DD"); /* add 1 day */
rv.ed = `20${end_y}-${dp2(end_m)}-${dp2(num(_period_end_day(end_m,period_end_day)))}`;
return rv;
}
function tp_disp_from_code_hidden(code) {
let rv = tp_disp_from_code(code);
if (rv !== "") {
return ``;
} else {
return ``;
}
}
function tp_disp_from_code(code) {
if (code.indexOf("_TP.") > -1) {
let YM = code.substring(code.indexOf("_TP.")+2).split("_")[0].split(".");
var Y = (YM.length > 1) ? YM[1] : "";
var M = (YM.length > 2) ? YM[2] : "";
if (Y !== "") {
return ` Up to ${Y}-${M}`;
}
}
return "";
}
let months = [
`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`
];
function tp_disp_from_code_short(code,prefix = "") {
if (code.indexOf("_TP.") > -1) {
let YM = code.substring(code.indexOf("_TP.")+2).split("_")[0].split(".");
var Y = (YM.length > 1) ? YM[1] : "";
var M = (YM.length > 2) ? YM[2] : "";
if (Y !== "") {
return `${prefix}${months[num(M)-1]}`;
}
}
return "";
}
let tputils = (function(){
/**
* is this condition cleared based on the cleared data
*/
let isCleared = function(tp, cleared_items, stars) {
for (let i=0; i < cleared_items.length; i++) {
if (arguments.length === 2) {
if (cleared_items[i].full_id.endsWith(`${tp}`)) {
return true;
}
} else {
if (cleared_items[i].full_id.endsWith(`${tp}/${stars}`)) {
return true;
}
}
}
return false;
}
/**
* make a map range with
* ** : 0
* *** : 1
* **** : 2
* ***** : 3
*/
function map_range_to_cleared_data(tp, cleared_items) {
let map_range = {};
let map_i = 0;
for (let i=0; i < 5; i++) {
let k = "*******".substring(0,i+2); /* ** or *** or **** */
if (isCleared(tp, cleared_items, k)) continue;
map_range[k] = map_i;
map_i++;
}
return map_range;
}
return {
isCleared : isCleared,
//
map_range_to_cleared_data : map_range_to_cleared_data,
//
___id : "clear data utils"
}
})();
let clearingutils = (function() {
// thanks to https://stackoverflow.com/questions/39113692/moment-js-how-do-you-get-the-current-quarter-and-previous-three-quarters-along-w?rq=1
function lastq_end() {
return moment().quarter(moment().quarter()).subtract(1, 'Q').endOf('quarter').format("YYYY-MM-DD");
}
function lastq_start() {
return moment().quarter(moment().quarter()).subtract(1, 'Q').startOf('quarter').format("YYYY-MM-DD");
}
// months
function lastm_1_end() {
return moment().month(moment().month()).subtract(1, 'months').endOf('month').format("YYYY-MM-DD");
}
function lastm_1_start() {
return moment().month(moment().month()).subtract(1, 'months').startOf('month').format("YYYY-MM-DD");
}
function lastm_2_end() {
return moment().month(moment().month()).subtract(2, 'months').endOf('month').format("YYYY-MM-DD");
}
function lastm_2_start() {
return moment().month(moment().month()).subtract(2, 'months').startOf('month').format("YYYY-MM-DD");
}
return {
// quarters
lastq_start : lastq_start,
lastq_end : lastq_end,
// weeks
lastm_start : lastm_1_start,
lastm_end : lastm_1_end,
lastm_1_start : lastm_1_start,
lastm_1_end : lastm_1_end,
lastm_2_start : lastm_2_start,
lastm_2_end : lastm_2_end
}
})();
let utils = (function(){
let aname = function(needsidArray,n){
if (getApplicantsNames_v2().length < 2) return "";
var applicantid = (typeof needsidArray === "number") ? needsidArray : MAR.applicants.id(needsidArray[n]);
var applicant_name = getApplicantsNames_v2(Number(applicantid)).Names;
return applicant_name;
}
let AAname = function(needsidArray,n){
var applicantid = (typeof needsidArray === "number") ? needsidArray : MAR.applicants.id(needsidArray[n]);
var applicant_name = getApplicantsNames_v2(Number(applicantid)).Name;
return applicant_name;
}
let Aname = function(needsidArray,n){
if (getApplicantsNames_v2().length < 2) return "";
var applicantid = (typeof needsidArray === "number") ? needsidArray : MAR.applicants.id(needsidArray[n]);
var applicant_name = getApplicantsNames_v2(Number(applicantid)).Name;
return applicant_name;
}
let aname6 = function(needsidArray,n){
if (getApplicantsNames_v2().length < 2) return "";
var applicantid = (typeof needsidArray === "number") ? needsidArray : MAR.applicants.id(needsidArray[n]);
var applicant_name = getApplicantsNames_v2(Number(applicantid)).Name;
return C6(applicant_name);
}
let bname = function(needsidArray,n){
if (getApplicantsNames_v2().length < 2) return "";
var applicantid = (typeof needsidArray === "number") ? needsidArray : MAR.applicants.id(needsidArray[n]);
var applicant_name = getApplicantsNames_v2(Number(applicantid)).Name;
return applicant_name;
}
let _aname = function(needsidArray,n){
return dash(aname(needsidArray,n));
}
let _Aname = function(needsidArray,n){
return dash(Aname(needsidArray,n));
}
let Aname_ = function(needsidArray,n){
return dash_end(Aname(needsidArray,n));
}
let _aname6 = function(needsidArray,n){
return dash(aname6(needsidArray,n));
}
let aname6_ = function(needsidArray,n){
return dash_end(aname6(needsidArray,n));
}
let _bname = function(needsidArray,n){
return dash(bname(needsidArray,n));
}
let bname_ = function(needsidArray,n){
return dash_end(bname(needsidArray,n));
}
let dash = function(S) {
if (!S || S.trim().length === 0) return "";
return `${S.capitalize()} - `;
return ` - ${S}`;
}
let dash_end = function(S) {
if (!S || S.trim().length === 0) return "";
return `${S.capitalize()} - `;
}
let comma = function(S,S1,S2,S3) {
if (arguments.length < 4) S3 = "";
if (!S || S.trim().length === 0) return `${S2}${S3}`;
return `${S}${S1}${S3}`;
}
return {
aname : aname,
//
AAname : AAname,
Aname : Aname,
//
aname6 : aname6,
_aname6 : _aname6,
aname6_ : aname6_,
//
bname : bname,
_bname : _bname,
bname_ : bname_,
//
_aname : _aname,
_Aname : _Aname,
Aname_ : Aname_,
//
dash : dash,
dash_end : dash_end,
comma : comma,
//
___id : "supdata utils"
}
})();
return {
tp_from_code : tp_from_code,
tp_disp_from_code : tp_disp_from_code,
tp_disp_from_code_short : tp_disp_from_code_short,
tp_disp_from_code_hidden : tp_disp_from_code_hidden,
Y : Y,
M : M,
range : range,
//
tputils : tputils,
cleardatautils : tputils,
//
clearingutils : clearingutils,
//
utils : utils,
___id : "supdata"
}
})();
/**
* devops
* @namespace MAR.devops
*/
var devopsObj = (function(){
let errorcodes = {
"cpull-noresponse" : {
client : `There is no response from the credit agency - chck that the SSN is valid`
},
"cpull-locked" : {
client : `File is locked at the request of the client`
},
"cpull-frozenbc" : {
client : `File is frozen at the request of the client`
},
"cpull-frozen" : {
client : `File is frozen, no report is available`
},
"cpull-invalidssn" : {
client : `One of the SSNs is invalid or missing`
},
"cpull-loginerror" : {
client : `There is a log error pulling credit, check your password in the sttings menu (top right)`
}
}
function errorcode(code) {
if (arguments.length === 0) {
return errocodes;
}
let rv = MAR.getOpt(errorcodes, code, false);
return rv;
}
return {
errorcode : errorcode,
___id : "devops obj"
}
})();
/**
* assets
* @namespace MAR.assets
*/
var assetsObj = (function(){
/**
* @memberof MAR.assets
*/
function init(){
if ("answers" in mar == false) mar.answers = {};
if ("v2" in mar.answers == false) mar.answers.v2 = {};
if ("assets" in mar.answers.v2 == false) mar.answers.v2.assets = {};
if ("items" in mar.answers.v2.assets == false) {
mar.answers.v2.assets.items = []
}
}
/**
* @memberof MAR.assets
*/
function type_to_editor(TYP) {
if (TYP =="checking") TYP = "bank";
if (TYP =="savings") TYP = "savings";
if (TYP =="proceedsfromsale") TYP = "nprf";
return TYP;
}
/**
* @memberof MAR.assets
*/
function recalculate() {
}
/**
* @memberof MAR.assets
*/
function summary() {
}
/**
* @memberof MAR.assets
*/
function getLast4sItems() {
let _array = get();
let retval = [];
for (let i=0; i < _array.length; i++) {
if (MAR.getOpt(_array[i], "__deleted", "") === "Y") continue;
if (_array[i].type == "emd") continue;
if (_array[i].type != "bank" && _array[i].type != "savings") continue;
retval.push({
uuid : _array[i].uuid,
type : _array[i].type,
bank : _array[i].institution_name,
balance : _array[i].balance,
last4digits : MAR.getOpt(_array[i], "last4digits",""),
item : _array[i]
})
}
return retval;
}
/**
* @memberof MAR.assets
*/
function getLast4s() {
let _array = get();
let retval = [];
for (let i=0; i < _array.length; i++) {
if (MAR.getOpt(_array[i], "__deleted", "") === "Y") continue;
if (_array[i].type == "emd") continue;
if ("last4digits" in _array[i]) {
let last4digits = _array[i].last4digits;
if (last4digits.trim().length > 0) {
if (retval.indexOf(last4digits) < 0) {
retval.push(last4digits)
}
}
}
}
return retval;
}
/**
* @memberof MAR.assets
* To cater for either
* abc_1 = abc
* abc = abc
* _abc_1 = _abc
* _abc = _abc
*/
function matchingPart(S) {
if (typeof S !== "string") return S;
if (S.startsWith("_")) {
return `_${S.substring(1).split("_")[0]}`
}
return S.split("_")[0];
}
/**
* @memberof MAR.assets
*/
function getByUUID(uuid,ALSOID) {
let _array = get();
for (let i=0; i < _array.length; i++) {
if (MAR.getOpt(_array[i], "__deleted", "") === "Y") continue;
if ("uuid" in _array[i] && _array[i].uuid == matchingPart(uuid)) {
if (arguments.length > 1 && ALSOID === true) {
return {
i : i,
data : _array[i]
}
} else {
return _array[i];
}
}
}
return false;
}
/**
* @memberof MAR.assets
*/
function getByUUID_full(uuid,ALSOID) {
let _array = get();
for (let i=0; i < _array.length; i++) {
if (MAR.getOpt(_array[i], "__deleted", "") === "Y") continue;
if ("uuid" in _array[i] && _array[i].uuid == uuid) {
if (arguments.length > 1 && ALSOID === true) {
return {
i : i,
data : _array[i]
}
} else {
return _array[i];
}
}
}
return false;
}
/**
* @memberof MAR.assets
*/
function getByGID(gid) {
let _array = get();
let _items = [];
for (let i=0; i < _array.length; i++) {
if (MAR.getOpt(_array[i], "__deleted", "") === "Y") continue;
if ("gid" in _array[i] && _array[i].gid === matchingPart(gid)) {
_items.push(_array[i]);
}
}
return _items;
}
/**
* @memberof MAR.assets
*/
function setAnyEmptyBankStatements() {
let _array = get();
let _items = [];
for (let i=0; i < _array.length; i++) {
if (MAR.getOpt(_array[i], "__deleted", "") === "Y") continue;
if (_array[i] === false) continue;
if ("gid" in _array[i] && _array[i].gid !== "") {
let bs = ("bank_statement" in _array[i]) ? _array[i].bank_statement : "";
let ba = ("business_account" in _array[i]) ? _array[i].business_account : "";
let wn = ("whose_name" in _array[i]) ? _array[i].whose_name : "";
let key = "auto";
key += (ba === "Y") ? "-BUS-" : "-PRI-";
//console.log(`FOCUS wn ${wn} ${typeof wn}`)
key += `${wn}`.split(",").join("-")
if (bs === "" || bs.startsWith("auto")) {
_array[i].bank_statement = key;
}
}
}
}
/**
* @memberof MAR.assets
*/
function getByGIDandStatement(gid) {
let _array = get();
let _items = [];
for (let i=0; i < _array.length; i++) {
if (MAR.getOpt(_array[i], "__deleted", "") === "Y") continue;
if (_array[i] === false) continue;
if ("gid" in _array[i] && _array[i].gid == matchingPart(gid)) {
let bs = ("bank_statement" in _array[i]) ? _array[i].bank_statement : "";
if (gid.substring(1).split("_").length === 1 && bs === "") {
_array[i].__editi = i;
_items.push(_array[i]);
} else if (bs === gid.substring(1).split("_")[1]) {
_array[i].__editi = i;
_items.push(_array[i]);
}
}
}
return _items;
}
/**
* @memberof MAR.assets
*/
function setByUUID(uuid, obj) {
let ob = getByUUID(uuid);
if (ob !== false) {
for (let x in obj) {
if (obj[x] === null) {
MAR.delOpt(ob, x)
} else {
ob[x] = obj[x];
}
MAR.activity_log.modify("assets", uuid);
}
}
}
/**
* @memberof MAR.assets
*/
let bank_account_types = ["bank", "savings"];
/**
* @memberof MAR.assets
*/
function getBankAccounts() {
let _array = get();
let _items = {};
for (let i=0; i < _array.length; i++) {
if (MAR.getOpt(_array[i], "__deleted", "") === "Y") continue;
let gid = MAR.getOpt(_array[i], "gid", false);
let type = MAR.getOpt(_array[i], "type", false);
let name = MAR.getOpt(_array[i], "institution_name", false);
if (gid === false || gid === "") continue;
if (type === false || type === "") continue;
if (name === false || name === "") continue;
if (bank_account_types.indexOf(type) < 0) continue;
if (gid in _items === true) continue;
_items[gid] = { name : name, type : type };
}
return _items;
}
/**
* @memberof MAR.assets
*/
function getByENCID(encid) {
let _encid = encid.split("/");
let gid = _encid[0];
let gidindex = _encid[1];
let _array = get();
for (let i=0; i < _array.length; i++) {
if (MAR.getOpt(_array[i], "__deleted", "") === "Y") continue;
if ("gid" in _array[i] && _array[i].gid == gid) {
if ("gidindex" in _array[i] && num(_array[i].gidindex) == num(gidindex)) {
return {
i : i,
data : _array[i]
};
}
}
}
return false;
}
/**
* @memberof MAR.assets
* get all the logins for automaticly linked assets
*/
function getNextUnverifiedItem() {
let _array = this.get();
for (let i=0; i < _array.length; i++) {
if (MAR.getOpt(_array[i], "__deleted", "") === "Y") continue;
if ("verified" in _array[i] && _array[i].verified === "N") {
return {
i : i,
uuid : _array[i].uuid
}
}
}
return false;
}
/**
* @memberof MAR.assets
* get all the logins for automaticly linked assets
*/
function getLogins() {
let retval = [];
let _array = this.get();
for (let i=0; i < _array.length; i++) {
if (MAR.getOpt(_array[i], "__deleted", "") === "Y") continue;
if ("sys" in _array[i] && _array[i].sys && typeof _array[i].sys == "string" && _array[i].sys.trim().length > 0) {
retval.push({
i : i,
uuid : _array[i].uuid,
sys : _array[i].sys
})
}
}
return retval;
}
/**
* @memberof MAR.assets
*/
function addGidsToItems(items) {
let gids = {}
for (let i=0; i < items.length; i++) {
if (MAR.getOpt(items[i], "__deleted", "") === "Y") continue;
if (items[i] === false) continue;
if ("gid" in items[i] == false) {
items[i].gid = items[i].uuid;
}
if (items[i].gid in gids == false) {
gids[items[i].gid] = [items[i].uuid]
} else {
gids[items[i].gid].push(items[i].uuid);
}
}
for (let i=0; i < items.length; i++) {
items[i].gids = gids[items[i].gid]
}
}
/**
* @memberof MAR.assets
*/
function isThereAGift() {
let items = get("gift");
if (items == false) return false;
if (items.length > 0) return true;
return false;
}
/**
* @memberof MAR.assets
*/
function get(type, number) {
if ("answers" in mar == false) return false;
if ("v2" in mar.answers == false) return false;
if ("assets" in mar.answers.v2 == false) return false;
if ("items" in mar.answers.v2.assets == false) mar.answers.v2.assets.items = []
addGidsToItems(mar.answers.v2.assets.items);
if (arguments.length == 0) { // return the array for one applicant
return mar.answers.v2.assets.items;
}
if (arguments.length == 1) { // return the array for one applicant
let retval = [];
for (let i=0; i < mar.answers.v2.assets.items.length; i++) {
let ass = mar.answers.v2.assets.items[i];
if (MAR.getOpt(ass, "__deleted", "") === "Y") continue;
if (mar.answers.v2.assets.items[i].type == type) {
mar.answers.v2.assets.items[i]._i = i;
retval.push(mar.answers.v2.assets.items[i])
}
}
return retval;
}
if (typeof number == "string") number = parseInt(number,10);
if (number < mar.answers.v2.assets.items.length) {
return mar.answers.v2.assets.items[number];
}
return false;
}
function getNextAssetEncId(){
if ("state" in mar.answers.v2 == false) mar.answers.v2.state = {};
if ("asset_encid" in mar.answers.v2.state == false) mar.answers.v2.state.asset_encid = 18;
let retval = mar.answers.v2.state.asset_encid;
mar.answers.v2.state.asset_encid++;
return retval;
}
function repairGroups2() {
let itms = mar.answers.v2.assets.items;
for (let i=0; i < itms.length; i++) {
let itm = itms[i];
if (MAR.getOpt(itm, "__deleted", "") === "Y") continue;
// if ("gids" in itm && "gid" in itm && itm.gid !== itm.uuid && "gidindex" in itm && itm.gidindex == 0) {
// itm.gidindex = itm.gids.indexOf(itm.uuid);
// }
if (itm === false) continue;
if ("gids" in itm && "gid" in itm && itm.gid !== itm.uuid && "gidindex" in itm && itm.gidindex !== itm.gids.indexOf(itm.uuid)) {
itm.gidindex = itm.gids.indexOf(itm.uuid);
}
if ("gids" in itm && "gid" in itm && itm.gid !== itm.uuid && "gidindex" in itm && "enc_id" in itm && typeof itm.enc_id === "string" && itm.enc_id.endsWith(`/${itm.gidindex}`) === false) {
itm.enc_id = itm.enc_id.split("/")[0] + `/${itm.gidindex}`
}
}
}
function repairGroups() {
let itms = mar.answers.v2.assets.items;
let gids = {};
for (let i=0; i < itms.length; i++) {
let itm = itms[i];
if (MAR.getOpt(itm, "__deleted", "") === "Y") continue;
if ("gid" in itm) {
if (itm.gid in gids == false) {
gids[itm.gid] = [false,false,false,false,false,false,false,false];
}
if ("gidindex" in itm === true) {
gids[itm.gid][itm.gidindex] = itm.uuid;
}
}
}
for (let i=0; i < itms.length; i++) {
let itm = itms[i];
if (MAR.getOpt(itm, "__deleted", "") === "Y") continue;
if ("gidindex" in itm === false) {
for (let j=0; j < gids[itm.gid].length; j++) {
if (gids[itm.gid][j] === false) {
gids[itm.gid][j] = itm.uuid;
itm.gidindex = j;
break;
}
}
}
}
}
/**
* @memberof MAR.assets
*/
function set(type, number, data) {
if (arguments.length >= 3) { // return the whole array
if ("answers" in mar == false) mar.answers = {};
if ("v2" in mar.answers == false) mar.answers.v2 = {};
if ("assets" in mar.answers.v2 == false) mar.answers.v2.assets = {};
if ("items" in mar.answers.v2.assets == false) {
mar.answers.v2.assets.items = []
}
if (number === false) {
if ("__pre_uuid" in data == true) {
data.uuid = data.__pre_uuid;
delete data.__pre_uuid;
}
if ("uuid" in data == false) data.uuid = uuidv4();
if ("gid" in data == false) {
data.gid = data.uuid;
if ("gidindex" in data == false) {
data.gidindex = 0;
}
}
data.enc_id = getNextAssetEncId() // non mutable encompass id number
mar.answers.v2.assets.items.push(data);
MAR.activity_log.add("assets", data.uuid);
repairGroups();
repairGroups2();
return (mar.answers.v2.assets.items.length -1);
} else {
if (typeof number == "string") number = parseInt(number,10);
let obj_uuid = MAR.getOpt(data, `uuid`, null);
if (obj_uuid !== null) {
for (let i=0; i < mar.answers.v2.assets.items.length; i++) {
if (mar.answers.v2.assets.items[i].uuid === obj_uuid) {
number = i;
}
}
}
if (mar.answers.v2.assets.items.length > number) {
if ("uuid" in mar.answers.v2.assets.items[number] == false) {
if ("__pre_uuid" in data == true) {
data.uuid = data.__pre_uuid;
delete data.__pre_uuid;
}
if ("uuid" in data == false) data.uuid = uuidv4();
data.enc_id = getNextAssetEncId()
}
if ("gid" in mar.answers.v2.assets.items[number] == false) {
if ("gid" in data == false) {
data.gid = data.uuid;
if ("gidindex" in data == false) {
data.gidindex = 0;
}
}
}
if ("enc_id" in mar.answers.v2.assets.items[number] == false) {
if ("enc_id" in data == false) data.enc_id = getNextAssetEncId()
}
for (x in data) {
/**
* update only , don't overwrite!
*/
if (x.startsWith("__")) continue;
mar.answers.v2.assets.items[number][x] = data[x];
if (data[x] === null) {
delete mar.answers.v2.assets.items[number][x];
}
}
MAR.activity_log.modify("assets", mar.answers.v2.assets.items[number].uuid);
// mar.answers.v2.assets.items[number] = data;
repairGroups();
repairGroups2();
return number;
}
}
}
}
/**
* @memberof MAR.assets
*/
function deleteByUUID(uuid) {
console.log(`DELETING asset uuid [${uuid}]`);
let index = getByUUID(uuid,true);
console.log(`DELETING asset index`,index);
if (index !== false) {
console.log(`DELETING asset index .i ${index.i}`);
let dr = del(index.i)
console.log(`DELETED asset index .i ${index.i} dr ${dr}`);
}
}
/**
* @memberof MAR.assets
*/
function deleteByENCID(uuid) {
console.log(`DELETING asset uuid [${uuid}]`);
let index = getByENCID(uuid,true);
console.log(`DELETING asset index`,index);
if (index !== false) {
console.log(`DELETING asset index .i ${index.i}`);
let dr = del(index.i)
console.log(`DELETED asset index .i ${index.i} dr ${dr}`);
}
}
/**
* @memberof MAR.assets
*/
function del(number) {
if (arguments.length < 0) return false;
if ("answers" in mar == false) return false;
if ("v2" in mar.answers == false) return false;
if ("assets" in mar.answers.v2 == false) return false;
if ("items" in mar.answers.v2.assets == false) return false;
console.log(`DELETED asset number ${number}, arr length [${mar.answers.v2.assets.items.length}] `);
if (number >= mar.answers.v2.assets.items.length) return false;
console.log(`DELETED asset number ${number} PRE`);
MAR.activity_log.del("assets",mar.answers.v2.assets.items[number].uuid);
mar.answers.v2.assets.items[number].__deleted = "Y";
// mar.answers.v2.assets.items.splice(number, 1);
console.log(`DELETED asset number ${number} POST`);
return true;
}
/**
* @memberof MAR.assets
*/
let othertypes = [
{
"value": "MutualFund",
"text": "Mutual Funds"
},
{
"value": "CertificateOfDepositTimeDeposit",
"text": "Certificate Of Deposit"
},
{
"value": "OtherLiquidAssets",
"text": "Other Liquid Assets"
},
{
"value": "OtherNonLiquidAssets",
"text": "Other Non Liquid Assets"
},
{
"value": "MoneyMarketFund",
"text": "Money Market Fund"
},
{
"value": "TrustAccount",
"text": "Trust Account"
},
{
"value": "GiftOfEquity",
"text": "Gift Of Equity"
},
{
"value": "CashOnHand",
"text": "Cash On Hand"
},
{
"value": "LotEquity",
"text": "Lot Equity"
},
{
"value": "BridgeLoanNotDeposited",
"text": "Bridge Loan Not Deposited"
},
{
"value": "SecuredBorrowedFundsNotDeposited",
"text": "Secured Borrowed Funds Not Deposited"
},
{
"value": "CashDepositOnSalesContract",
"text": "Cash Deposit On Sales Contract"
},
{
"value": "NetWorthOfBusinessOwned",
"text": "Net Worth Of Business Owned"
},
{
"value": "NetEquity",
"text": "Net Equity"
},
{
"value": "Other",
"text": "Other"
},
{
"value": "StockOptions",
"text": "Stock Options"
},
{
"value": "Bond",
"text": "Bond"
},
{
"value": "IndividualDevelopmentAccount",
"text": "Individual Development Account"
},
{
"value": "LifeInsurance",
"text": "Life Insurance"
},
{
"value": "Annuity",
"text": "Annuity"
},
{
"value": "Automobile",
"text": "Automobile"
},
{
"value": "Boat",
"text": "Boat"
},
{
"value": "BorrowerPrimaryHome",
"text": "Borrower Primary Home"
},
{
"value": "EmployerAssistedHousing",
"text": "Employer Assisted Housing"
},
{
"value": "LeasePurchaseFund",
"text": "Lease Purchase Fund"
},
{
"value": "ProceedsFromSecuredLoan",
"text": "Proceeds From Secured Loan"
},
{
"value": "ProceedsFromUnsecuredLoan",
"text": "Proceeds From Unsecured Loan"
},
{
"value": "PendingNetSaleProceedsFromRealEstateAssets",
"text": "Pending Net Sale Proceeds From Real Estate Assets"
},
{
"value": "ProceedsFromSaleOfNonRealEstateAsset",
"text": "Proceeds From Sale Of Non Real Estate Asset"
},
{
"value": "LeasePurchaseCredit",
"text": "Lease Purchase Credit"
},
{
"value": "RecreationalVehicle",
"text": "Recreational Vehicle"
},
{
"value": "RelocationFunds",
"text": "Relocation Funds"
},
{
"value": "SavingsBond",
"text": "Savings Bond (FHA/VA)"
},
{
"value": "SeverancePackage",
"text": "Severance Package"
},
{
"value": "SweatEquity",
"text": "Sweat Equity"
},
{
"value": "TradeEquityFromPropertySwap",
"text": "TradeEquity From Property Swap"
}
];
function getOtherTypeByVal(val, def) {
for (let i=0; i < othertypes.length;i++) {
if (othertypes[i].value == val) return othertypes[i].text;
}
return def;
}
function getOtherTypeByText(val, def) {
for (let i=0; i < othertypes.length;i++) {
if (othertypes[i].text == val) return othertypes[i].value;
}
return def;
}
let getOtherTypesAsArray = function() {
let retval = [];
for (let i=0; i < othertypes.length;i++) {
retval.push(othertypes[i].text)
}
return retval;
}
function suggest() {
/**
* returns ::
* borrower 0,
* sugestedprimary "address"
*/
let retval = [];
let itms = mar.answers.v2.assets.items;
for (let i=0; i < itms.length; i++) {
let itm = itms[i];
if (MAR.getOpt(itm, "__deleted", "") === "Y") continue;
if (itm.type ==="tbd") {
retval.push({
applicant : 0,
suggestion : "notype",
index : i,
item : itm
})
}
}
return retval;
}
let fields = {
uuid : "uuid",
institution_name : "Text",
can_take_freely : "Y/N",
dont_pay_taxes : "Y/N",
whose_name : "[0,1] array",
balance : "dollars"
};
return {
/**
* utility functions
*/
init : init, // initialize
recalculate : recalculate,
repairGroups : repairGroups, // repair gidindexes
repairGroups2 : repairGroups2, // repair gidindexes
/**
* fields
*/
FIELDS : fields,
/**
* type conversion
*/
getOtherTypeByVal : getOtherTypeByVal,
getOtherTypeByText : getOtherTypeByText,
getOtherTypesAsArray : getOtherTypesAsArray,
/**
* getters and setters
*/
addGidsToItems : addGidsToItems, // addGidsToItems
get : get, // get (applicant, type, num)
getByUUID : getByUUID, // get by uuid
getByUUID_full : getByUUID_full, // get by uuid including _1
deleteByUUID : deleteByUUID, // delete by uuid
deleteByENCID : deleteByENCID, // delete by encompass id
getByGID : getByGID, // get item(s) by gid
getByGIDandStatement
: getByGIDandStatement, // get by gid_statement
setAnyEmptyBankStatements
: setAnyEmptyBankStatements,
getByENCID : getByENCID, // get by encid with is gid/0,1,2,3
getBankAccounts : getBankAccounts, // get all bank accounts
set : set, // set (applicant, type, num)
setByUUID : setByUUID, // partial set by uuid
del : del, // del (num)
/**
* misc
*/
suggest : suggest, // suggest
/**
* UI
*/
type_to_editor : type_to_editor, // editor types
/**
* report sand summary
*/
getLast4s : getLast4s, // get an array of the last4 digits
getLast4sItems : getLast4sItems, // as above but with the details o the items
summary : summary,
getLogins : getLogins, // get the list of "sys" logins on assets
getNextUnverifiedItem
: getNextUnverifiedItem, // get next un-verified item
isThereAGift : isThereAGift, // is there a gift as an asset
/**
* object id
*/
__id : "income"
}
})()
let testObj = (function(){
function lia_scenario1() {
for (let i=0; i < mar.answers.v2.liabilities.length; i++) {
let lia = mar.answers.v2.liabilities[i];
lia.verified = "N";
lia.cstatus = "";
if (lia.type === "studentloan") {
lia.type = "instalmentloan";
}
}
}
return {
lia_scenario1 : lia_scenario1, /* rest all to unverified, and studentloans to instalmentloans */
___id : "Test object"
}
})();
/**
* @namespace MAR.master_router
*/
var master_router = (function(){
/**
* @memberof MAR.master_router
*/
let routes = {
"0100" : false,
"0200" : false,
"0300" : false,
"0400" : false,
"0500" : false,
"0600" : false,
"0700" : false,
"0800" : false,
"1000" : false,
"1100" : false,
"1200" : false,
"1300" : false,
"2000" : false,
"2100" : false,
"2200" : false,
"2300" : false,
"2150" : false,
"2350" : false,
"3000" : false,
"3100" : false,
"3200" : false,
"3300" : false,
"4000" : false,
"4100" : false,
"4200" : false,
"5000" : false,
"5100" : false,
"5200" : false,
"6000" : false,
"6100" : false,
"6200" : false,
"7000" : false,
"7100" : false,
"9999" : false
}
/**
* @memberof MAR.master_router
*/
let states = {
NO : 0,
REACHED : 1,
PASSED : 2
}
/**
* @memberof MAR.master_router
*/
function addroutestoapp(ans) {
if ("v2" in ans == false) return false;
if ("scenario" in ans.v2 == false) return false;
let retval = false;
/**
* create routes id not there
*/
if ("routes" in ans.v2.scenario == false) {
ans.v2.scenario.routes = {};
retval = true;
}
/**
* fill in any empty items
*/
for (x in routes) {
if (x in ans.v2.scenario.routes == false) {
ans.v2.scenario.routes[x] = states.NO;
retval = true;
}
}
return retval;
}
/**
* @memberof MAR.master_router
*/
function passed(ans, sec, val) {
if (arguments.length == 2) {
if (sec in ans.v2.scenario.routes) {
return ans.v2.scenario.routes[sec];
}
return false;
}
if (arguments.length == 3) {
if (sec in ans.v2.scenario.routes) {
if (ans.v2.scenario.routes[sec] != val) {
ans.v2.scenario.routes[sec] = val;
return true;
}
} else {
ans.v2.scenario.routes[sec] = val;
return true;
}
return false;
}
}
/**
* @memberof MAR.master_router
*/
function wherearewe() {
}
/**
* @memberof MAR.master_router
*/
function decision_pt1() {
}
let pages = (function(){
let pgobj = {
"scenario_nav": "",
"scenario-loantype": "Loan Tyope",
"scenario-timeframe": "Timeframe",
"scenario-location": "Location",
"scenario-creditscore": "Credit score",
"scenario-property": "Property type",
"scenario-mcc": "MCC",
"scenario-occupancy1": "Occupancy",
"scenario-occupancy": "Occupancy",
"scenario-summary": "",
"scenario-borrowers": "Borrowers",
"scenario-borrower": "Borrower",
"scenario-legalstatus": "Legal Status",
"scenario-veteran": "Veteran",
"scenario-ratequote": "Rate quote",
"scenario-pastproperty": "Past ownership",
"scenario-hoi": "HOI",
"scenario-hoa": "HOA",
"scenario-tax": "TAX",
"makepopup": "",
"scenario-mortgageyes3": "Mortgage",
"scenario-mortgage": "Mortgage",
"scenario-magic2": "",
"scenario-magic3": "",
"scenario-magic1": "",
"scenario-crossroads": "",
"calcs": "",
"scenario-housingbudget": "Housing budget",
"upmy": "",
"scenario-c2c": "",
"scenario-purchaseprice": "",
"scenario-budget": "",
"scenario-budget1": "",
"lox-thanks": "",
"lox": "Homework",
"income-how": "",
"income-summary": "",
"income-w2": "Income - W2",
"income-w2manual": "Income - W2",
"income-DD1099": "Income 1099",
"income-w2-previous": "Income previous",
"income-employer": "Income employer",
"income-llc": "Income LLC",
"income-k1": "Income K1",
"income-rental": "Income Rental",
"income-disability": "Income Disability",
"income-child-support": "Income Child support",
"income-alimony": "Income Alimony",
"income-social-security": "Income Social Security",
"income-pension": "Income Pension",
"income-other": "Income Other",
"assets-choice": "",
"assets-suggestion": "",
"assets-checkings": "Assets Bank",
"assets-bankconnect": "",
"assets-importedaccounts": "",
"assets-bank": "Assets Bank",
"assets-savings": "Assets Savings",
"assets-k401": "Assets 401k",
"assets-ira": "Assets IRA",
"assets-stock": "Assets Stock",
"assets-cash": "Assets Cash",
"assets-gifts": "Assets Gifts",
"assets-emd": "Assets EMD",
"assets-nprf": "Assets NPRF",
"assets-other": "Assets Other",
"assets-summary": "Assets Summary",
"assets-bankOld": "",
"scenario-personaldata": "Personal Data",
"scenario-personaldata1": "Personal Data P2",
"scenario-personaldata2": "Personal Data P3",
"scenario-addresshistory": "Address History",
"scenario-checkpersonaldatac1": "",
"authorizations-credit-ed": "",
"liabilities-home-old": "",
"liabilities-home": "Liabilities - Home",
"liabilities-item": "Liabilities - item",
"liabilities-choice": "Liabilities - Choice",
"liabilities-report": "Liabilities - Report",
"liabilities-child": "Liabilities - Child",
"liabilities-jre": "Liabilities - JRE",
"liabilities-irstax": "Liabilities - IRS Tax",
"liabilities-creditcard": "Liabilities - Creditcard",
"liabilities-studentloan": "Liabilities - StudentLoan",
"liabilities-carloan": "Liabilities - Car Loan",
"liabilities-carlease": "Liabilities - Car Lease",
"liabilities-instalmentloan": "Liabilities - instalment Loan",
"liabilities-installmentloan": "Liabilities - installment Loan",
"liabilities-childsupport": "Liabilities - Child Support",
"liabilities-alimony": "Liabilities - Alimony",
"liabilities-irstax1": "Liabilities - IRS Tax 1",
"liabilities-other": "Liabilities - Other",
"liabilities-summary": "Liabilities - Summary",
"up-next-employmentinfo": "",
"up-next": "",
"up-next-wishlist": "",
"up-next-income-inbetween": "",
"up-next-income": "",
"up-next-liabilities": "",
"up-next-homework": "",
"up-next-prescan": "",
"up-next-personalinfo": "",
"up-next-personalinfonext": "",
"up-next-expect": "",
"up-next-assets": "",
"up-next-lox": "",
"logged-out": "",
"declarations-p1": "Declarations 1",
"declarations-p2": "Declarations 2",
"declarations-p3": "Declarations 3",
"scenario-realtor": "Realtor",
"scenario-realtorinfo": "realtor Info",
"videointro2": "",
"licenses": "",
"privacy": "",
"legal": "",
"nmls": "",
"scenario-end": "",
"evaluate-section": "",
"ext-checkings": "",
"review": "",
"scenario-mortgageyes": "",
"scenario-mortgageyes2": "",
"makeNewpopup": "",
"makeC2Cpopup": "",
"loanofficer": "Loan Officer",
"realtor": "Realtor",
"intro-2fa": "",
"scenario-whatsapp": "Whatsapp",
"loanproposal-home": "",
"general-aboutus": "",
"general-route": "",
"general-comments": "",
"general-faq": "",
"general-comms": "",
"reo-home": "REO Home",
"reo-suggestion": "",
"reo-property": "REO property",
"reo-property-connectedloan": "",
"import-encompass-intro": "",
"import-encompass-upnext-submit": "",
"submit": "",
"import-encompass-unverfied-income-change": "",
"import-encompass": "",
"update-encompass": "",
"flow-confirmtakeover": "",
"flow-reconfirm": "",
"flow-reconfirm-assets": "",
"flow-reconfirm-personaldata": "",
"flow-reconfirm-income": "",
"flow-reconfirm-applicnatconfirmed": "",
"flow-test": "",
"flow-flex": "",
"scenario-subjectproperty": "Subject Property",
"copilot_custom_listener": ""
};
function name(code) {
if (code.startsWith("#")) code = code.substring(1);
let i = -1;
for (let x in pgobj) {
i++;
if (code.startsWith(`${x}`)) {
let txt = pgobj[x];
if (txt.length === 0) return {i : i, txt : code};
return {i : i, txt : txt};
}
}
return {i : -1, txt : code};
}
return {
name : name,
___id : "pages object"
};
})();
return {
routes : routes,
addroutestoapp : addroutestoapp, // add route to answers, returns true if any changes were made
addroutestoanswers : addroutestoapp,
passed : passed,
states : states,
pages : pages,
___id : "master_routes"
}
})();
function resetroute(R) {
if (arguments.length == 0 || R == "income") {
delScenario_data("__income_passed");
delScenario_data("__income_passed_0");
delScenario_data("__income_passed_1");
delScenario_data("__income_passed_2");
delScenario_data("__income_unin_passed_0");
delScenario_data("__income_unin_passed_1");
delScenario_data("__income_unin_passed_2");
}
}
/**
* @namespace MAR.loxBuilder
*/
var loxBuilder = (function() {
/**
* @memberof MAR.loxBuilder
*/
var lox = {};
/**
* @memberof MAR.loxBuilder
*/
function init() {
lox = {
questions : []
};
}
/**
* @memberof MAR.loxBuilder
*/
function setTo(email, tel, name) {
let _sendarray = [];
if (email) _sendarray.push("e:"+email);
if (tel) _sendarray.push("t:"+tel);
if (name) _sendarray.push("n:"+name);
lox.sendto = _sendarray.join(",");
}
/**
* @memberof MAR.loxBuilder
*/
function setSign(email, tel, name) {
let _sendarray = [];
if (email) _sendarray.push("e:"+email);
if (tel) _sendarray.push("t:"+tel);
if (name) _sendarray.push("n:"+name);
lox.signby = _sendarray.join(",");
}
/**
* @memberof MAR.loxBuilder
*/
function setNeed(s) {
lox.need = s;
}
/**
* @memberof MAR.loxBuilder
*/
function setFilename(s) {
lox.filename = s;
}
/**
* @memberof MAR.loxBuilder
*/
function setAppid(s) {
lox.appid = s;
}
/**
* @memberof MAR.loxBuilder
*/
function addQuestion(type,merge,data,name,question,html,admin,hide) {
let q = {};
q.type = (type) ? type : "text";
q.merge = (merge) ? merge : "";
q.data = (data) ? data : "";
q.name = (name) ? name : "";
q.question = (question) ? question : "";
if (q.type == "text") {
""
} else {
""
}
q.admin = (admin) ? admin : "N";
q.hide = (hide) ? hide : "N";
lox.questions.push(q);
}
/**
* @memberof MAR.loxBuilder
*/
function addQuestionSimple(q,a) {
lox.questions.push({
question : q,
answerset : "simple",
data : a
})
}
/**
* @memberof MAR.loxBuilder
*/
function render() {
if ("signby" in lox == false) {
lox.signby = lox.sendto
}
if ("ids" in lox == false) lox.ids = "";
if ("type" in lox == false) lox.type = "";
return lox;
}
/**
* @memberof MAR.loxBuilder
*/
function renderRequest() {
/**
* ids : id number of fragments to combine
*
* appid : application id
*
* send_to : list of people to send to in the format
* e:email,t:smsnumber,n:Jonathan Carter
*
* Sign_by : list of people to sign the evential doc
* e:email,n:J carter|e:email,n:S Carter
*
* filename : the filename to put this into for signing
*
* type : the type (t4506 , fragment, econsent)
*
* questions : if there are questions then the ids are not necessary and this is one time submit
*
*/
return {
ids : "",
appid : lox.appid,
send_to : lox.sendto,
sign_by : ("signby" in lox) ? lox.signby : lox.sendto,
filename : lox.filename,
type : ("type" in lox) ? lox.signby : "fragment",
questions : questions
}
}
return {
init : init,
setTo : setTo,
setSign : setSign,
setNeed : setNeed,
setAppid : setAppid,
setFilename : setFilename,
addQuestion : addQuestion,
addQuestionSimple : addQuestionSimple,
render : render,
renderRequest : renderRequest,
___id : "lox builder"
}
})();
let mortgageNavigator = (function() {
function ic_getMortgagesFromRates(ic_rates) {
let retval = [];
let cnt_total = 0;
let cnt_total1 = [];
let cnt_matched = 0;
for (let i=0; i < ic_rates.length; i++) {
let rate = ic_rates[i];
let xrate = rate.rate; // 3.75
let xrow = rate.row; // r0
if ("master" in rate == false) continue;
if ("MI" in rate.master == false) continue;
for (x in rate.master.MI) {
let addMortgage = function(xmortgage,alt,key) {
if (xmortgage == false) return;
cnt_total += xmortgage.total_loans_calculated;
if (xmortgage.filters._qmpass == false) return;
//if (xmortgage.filters.apr > (xmortgage.pricing_apor + 1.5)) return;
if (xmortgage.filters.rate > (xmortgage.pricing_apor + 1.5)) return;
// rebuttleable consumption
//xmortgage.filters.__apr = `${xmortgage.pricing_apor} - ${xmortgage.filters.apr} = ${xmortgage.pricing_apor - xmortgage.filters.apr}`;
let uuid = `${xrow}_${x}_${key}`;
xmortgage.filters.uuid = uuid;
xmortgage.filters.programme = xmortgage.input_scenario.scenario.programme;
xmortgage.filters.MI = x;
xmortgage.filters.mmi = xmortgage.final_mi;
xmortgage.filters.mmip = xmortgage.final_mi_py;
xmortgage.filters.ufmip = xmortgage.final_ufmi_py;
xmortgage.filters.abdr = xmortgage.bd_price_inc_llpa;
xmortgage.filters.mi_audit = xmortgage.mi_audit;
xmortgage.filters.m_pay = xmortgage.final_monthly_payment;
xmortgage.filters.m_tax = xmortgage.final_monthly_tax;
xmortgage.filters.m_hoa = xmortgage.final_hoa;
xmortgage.filters.m_hoi = xmortgage.final_hoi;
xmortgage.filters.m_flood = xmortgage.final_flood;
// h += mar._txt(mortgage.input_scenario.v2.programme);
// h += elaineui.format("cur", mortgage.filters.downpayment);
// h += elaineui.format("cur", mortgage.filters.max_loan);
// h += elaineui.format("perc2", mortgage.final_ltv);
// h += mortgage.credit_score;
// h += elaineui.format("perc2",mortgage.final_ufmi_py);
// h += elaineui.format("cur",mortgage.final_ufmi);
cnt_matched++;
retval.push({
uuid : uuid,
master_type : xmortgage.master_type,
rate : xrate,
frate : xmortgage.filters.rate,
xrate : xmortgage.filters.xrate,
//loitab : xmortgage.loitab,
alt : alt,
row : xrow,
mi : x,
mortgage : xmortgage,
filters : xmortgage.filters
});
}
let xxmortgage = ("master_return" in rate.master.MI[x] != false) ? rate.master.MI[x].master_return : false;
addMortgage(xxmortgage,false,"max");
if ("master_return_scenario" in rate.master.MI[x]) {
addMortgage(rate.master.MI[x].master_return_scenario,false,"sce");
}
if ("master_return_alt" in rate.master.MI[x]) {
for (let j=0; j < rate.master.MI[x].master_return_alt.length; j++) {
addMortgage(rate.master.MI[x].master_return_alt[j],true,`alt${j}`);
}
}
if ("master_return_alt1" in rate.master.MI[x]) {
for (let j=0; j < rate.master.MI[x].master_return_alt1.length; j++) {
addMortgage(rate.master.MI[x].master_return_alt1[j],true,`alt_1_${j}`);
}
}
}
}
return {
items : retval,
cnt_total1 : cnt_total1,
cnt_total : cnt_total,
cnt_matched : cnt_matched
}
}
function ic_getMortgages(ic) {
if (!ic) return [];
if ("mar" in ic == false) return [];
if ("rates" in ic.mar == false) return [];
let mgs = ic_getMortgagesFromRates(ic_rates);
return mgs.items;
}
function list(ic) {
let mgs = ic_getMortgagesFromRates(ic_rates);
let list = mgs.items;
return list;
}
function list_from_rates(ic_rates) {
let mgs = ic_getMortgagesFromRates(ic_rates);
let list = mgs.items;
return list;
}
function tonear10(N) {
return Math.round(N/10) *10
}
function tonear100(N) {
return Math.round(N/100) *100
}
function tonear1000(N) {
return Math.round(N/100) *1000
}
function mortgage_from_rates(ic_rates, n) {
let mgs = ic_getMortgagesFromRates(ic_rates);
let list = mgs.items;
return list[n].mortgage;
}
function filters_from_rates(ic_rates) {
let mgs = ic_getMortgagesFromRates(ic_rates);
let list = mgs.items;
let _l = list.length;
let xl = ` len ${_l}`;
let aprs = [];
let pps = [];
let c2cs = [];
let budgets = [];
let buydowns = [];
for (let i=0; i < list.length; i++) {
delete list[i].mortgage;
aprs.push( { apr : list[i].filters.apr, i : i});
pps.push( { pp : list[i].filters.purchase_price, i : i, apr : list[i].filters.apr });
c2cs.push( { c2c : list[i].filters.c2c, i : i, apr : list[i].filters.apr });
budgets.push({ budget : list[i].filters.budget, i : i, apr : list[i].filters.apr });
buydowns.push({ buydown : Math.abs(list[i].filters.buydown), i : i, apr : list[i].filters.apr });
}
aprs.sort(function(a, b) {
return a.apr < b.apr ? -1 : 1;
});
pps.sort(function(a, b) {
if (tonear1000(a.pp) == tonear1000(b.pp)) {
return a.apr < b.apr ? -1 : 1;
}
return a.pp > b.pp ? -1 : 1;
});
c2cs.sort(function(a, b) {
if (tonear100(a.c2c) == tonear100(b.c2c)) {
return a.apr < b.apr ? -1 : 1;
}
return a.c2c < b.c2c ? -1 : 1;
});
budgets.sort(function(a, b) {
if (tonear10(a.budget) == tonear10(b.budget)) {
return a.apr < b.apr ? -1 : 1;
}
return a.budget < b.budget ? -1 : 1;
});
buydowns.sort(function(a, b) {
if (a.buydown == b.buydown) {
return a.apr < b.apr ? -1 : 1;
}
return a.buydown < b.buydown ? -1 : 1;
});
return {
xl : xl,
apr : aprs,
pp : pps,
c2c : c2cs,
budget : budgets,
buydown : buydowns,
cnt_total : mgs.cnt_total,
cnt_total1 : mgs.cnt_total1,
cnt_matched : mgs.cnt_matched,
list : list
}
}
function filters_from_rates_full(ic_rates) {
let mgs = ic_getMortgagesFromRates(ic_rates);
let list = mgs.items;
let _l = list.length;
let xl = ` len ${_l}`;
let aprs = [];
let pps = [];
let c2cs = [];
let budgets = [];
let buydowns = [];
for (let i=0; i < list.length; i++) {
aprs.push( { apr : list[i].filters.apr, i : i});
pps.push( { pp : list[i].filters.purchase_price, i : i, apr : list[i].filters.apr });
c2cs.push( { c2c : list[i].filters.c2c, i : i, apr : list[i].filters.apr });
budgets.push({ budget : list[i].filters.budget, i : i, apr : list[i].filters.apr });
buydowns.push({ buydown : Math.abs(list[i].filters.buydown), i : i, apr : list[i].filters.apr });
}
aprs.sort(function(a, b) {
return a.apr < b.apr ? -1 : 1;
});
pps.sort(function(a, b) {
if (tonear1000(a.pp) == tonear1000(b.pp)) {
return a.apr < b.apr ? -1 : 1;
}
return a.pp > b.pp ? -1 : 1;
});
c2cs.sort(function(a, b) {
if (tonear100(a.c2c) == tonear100(b.c2c)) {
return a.apr < b.apr ? -1 : 1;
}
return a.c2c < b.c2c ? -1 : 1;
});
budgets.sort(function(a, b) {
if (tonear10(a.budget) == tonear10(b.budget)) {
return a.apr < b.apr ? -1 : 1;
}
return a.budget < b.budget ? -1 : 1;
});
buydowns.sort(function(a, b) {
if (a.buydown == b.buydown) {
return a.apr < b.apr ? -1 : 1;
}
return a.buydown < b.buydown ? -1 : 1;
});
return {
xl : xl,
apr : aprs,
pp : pps,
c2c : c2cs,
budget : budgets,
buydown : buydowns,
cnt_total : mgs.cnt_total,
cnt_total1 : mgs.cnt_total1,
cnt_matched : mgs.cnt_matched,
list : list
}
}
return {
list : list,
list_from_rates : list_from_rates,
filters_from_rates : filters_from_rates,
filters_from_rates_full : filters_from_rates_full,
mortgage_from_rates : mortgage_from_rates,
___id : "mortgagenav"
}
})();
let abbreviateAddress = function(S) {
try {
let parts = S.split(" ");
for (let i=0; i < parts.length; i++) {
let p = parts[i].toLowerCase();
if (p === "drive") parts[i] = "Dr";
if (p === "lane") parts[i] = "Ln";
if (p === "road") parts[i] = "Rd";
if (p === "place") parts[i] = "Pl";
if (p === "terrace") parts[i] = "Ter";
if (p === "court") parts[i] = "Crt";
if (p === "boulevard") parts[i] = "Blvd";
if (p === "avenue") parts[i] = "Av";
if (p === "causeway") parts[i] = "CSW";
if (p === "southwest") parts[i] = "SW";
if (p === "southeast") parts[i] = "SE";
if (p === "northwest") parts[i] = "NW";
if (p === "northeast") parts[i] = "NE";
if (p === "plaza") parts[i] = "Plz";
if (p === "highway") parts[i] = "Hwy";
if (p === "interstate") parts[i] = "I";
if (p === "turnpike") parts[i] = "Tpke";
if (p === "freeway") parts[i] = "Fwy";
if (p === "parkway") parts[i] = "Pkwy";
if (p === "beltway") parts[i] = "Bltwy";
if (p === "crescent") parts[i] = "Cres";
if (p === "alley") parts[i] = "Aly";
if (p === "esplanade") parts[i] = "Esp";
}
return parts.join(" ");
} catch(E) {
return S;
}
}
let xsd = (function(){
function reo(itm) {
let _itm = itm;
function addr1() {
if (MAR.getOpt(_itm, "address", "") === ``) return ``;
return abbreviateAddress(MAR.getOpt(_itm, "address", "").split("|")[0])+", "+ MAR.getOpt(_itm, "address", "").split("|")[1];
}
function addr1_raw() {
return MAR.getOpt(_itm, "address", "").split("|")[0];
}
function addr() {
return MAR.getOpt(_itm, "address", "");
}
function addr1_html() {
var ad = MAR.getOpt(_itm, "address", "");
var rv = "
"+addressToString(ad)+"
";
return rv;
}
function ins() {
return MAR.getOpt(_itm, "loan_insurance", "");
}
function subject_property() {
return MAR.getOpt(_itm, "is_subject_property", "");
}
function mortgages(n) {
let item = _itm;
if (item.mortgageoptions == "free") {
return [];
}
let mos = (typeof item.mortgageoptions === "string") ? item.mortgageoptions.split(",") : [];
mos.filter(function(mo,idx){
let loan = MAR.liabilities.getByUUID(mo);
mos[idx] = {
mo : mo,
loan : loan
};
if (loan === false) return;
mos[idx].name = loan.name;
mos[idx].balance = loan.balance;
mos[idx].monthly = loan.monthly;
mos[idx].balanceF = MAR.format.format("cur",loan.balance);
mos[idx].monthlyF = MAR.format.format("cur",loan.monthly);
mos[idx].typeF = "Mortgage";
if (loan.m_type === "heloc") {
mos[idx].typeF = "HELOC";
}
});
if (typeof n !== "number") return mos;
if (n < mos.length) return mos[n];
return false;
}
function summary() {
let item = _itm;
let h = "";
if (item.verified2 === "N") {
h += `Needs Verfification !`;
} else {
if (item.mortgageoptions == "free") {
h += "Mortgage free";
} else {
h += "Property is mortgaged";
let bal = 0;
let mth = 0;
// console.log("item",item)
// console.log("item.mortgageoptions",item.mortgageoptions)
// console.log("item.mortgageoptions type",typeof item.mortgageoptions)
let mos = (typeof item.mortgageoptions === "string") ? item.mortgageoptions.split(",") : [];
mos.filter(function(mo){
let loan = MAR.liabilities.getByUUID(mo);
if (loan === false) return;
bal += loan.balance;
mth += loan.monthly;
});
h += `, Bal: ${MAR.format.format("cur",bal)}, Pmt: ${MAR.format.format("cur",mth)}`;
}
if (item.mortgageoptions !== "free" && item.loantype === "fha") {
h += `, FHA : Yes`;
}
if (MAR.getOpt(item, "is_subject_property","") === "Y") {
let new_monthly = getScenario_data(`goals_target_budget_high`,false);
let new_loanvalue = getScenario_data(`off_loanvalue`,false);
if (new_monthly !== false) {
h += `, subject property - New loan values are pmt:${MAR.format.format("cur",new_monthly)} bal:${MAR.format.format("cur",new_loanvalue)}.`;
} else {
h += `, subject property - the loan values will replace any current mortgage amounts.`;
}
}
// if (item.mortgageoptions == "free") {
// if (num(txt("#reo_free_loan_tax")) > 0) {
// h += "
";
}
if (item.mortgageoptions == mar.MORTGAGEFREE) {
D = "mortgage free";
}
var monthly_mortgage = 0;
item.LOANMONTHLY = 0;
item.LOAN = [];
item.LOAN2 = "N";
item.LOANBALANCE = 0;
item.LOANNAMES = "";
item.CALC_NPRF = 0;
if ("loanlink" in item && item.loanlink != "") {
try {
// var loanitem = mar.answers.v2.liabilities[num(item.loanlink)]; /* LLINK, change to UUID */
let loanlinkA = item.loanlink.split(",")
D = "mortgage "+item.loanlink;
for (let ii=0; ii < loanlinkA.length; ii++) {
var loanitem = MAR.liabilities.getByUUID(loanlinkA[ii]);
monthly_mortgage = (loanitem) ? loanitem.monthly : 0;
item.LOANMONTHLY += num(loanitem._monthly);
item.LOANBALANCE += num(loanitem._balance);
item.LOANNAMES += MAR.getOpt(loanitem, "name","")+" ";
item.LOAN.push(loanitem);
if (loanitem) item.LOAN2 = "Y";
}
} catch (E) {
console.error("cfc-link",E)
}
}
item._use_rq_for_monthly = false;
if (MAR.getOpt(item,"is_subject_property","") === "Y" && MAR.getOpt(item,"is_current_primary",false) === false) {
/**
* subject property is not the primary
* Therefore replace the LOAN with the offer
*/
let rq_base = getScenario_data(`_ratequote_base`, false);
let rq_monthly_total = getScenario_data(`goals_target_budget_high`);
if (rq_base !== false) {
item._use_rq_for_monthly = true;
item.RQ_LOANMONTHLY = rq_monthly_total;
item.RQ_BASE = rq_base;
}
}
item.rental = 0;
item.current_rental = 0;
item.expected_rental = 0;
item.useable_rent = 0;
item.rent_dec_reason = "";
item.rent_dec_reasons = [];
item.rent_dec_perc = 0;
monthly_mortgage = item.LOANMONTHLY;
item.monthly_mortgage = monthly_mortgage;
/**
* make sure we have the entered values for ins tax etc..
*/
var ins = 0;
var tax = 0;
var hoa = 0;
var enc_ins = 0;
var enc_tax = 0;
var enc_hoa = 0;
item.o_monthly_mortgage = monthly_mortgage;
item.o_tax = 0;
item.o_ins = 0;
N += "[COSTS :
mortgage:"+monthly_mortgage;
if (item.mortgageoptions == mar.MORTGAGEFREE || item.monthly_includes_taxes !== mar.YES) {
tax = Math.floor(float(item.loan_tax)/12);
item.o_tax = tax;
N += "
tax:"+tax;
} else if (item.monthly_includes_taxes === mar.YES) {
tax = Math.floor(float(item.loan_tax)/12);
item.o_tax = `Included`;
monthly_mortgage -= tax;
N += "
tax:"+tax;
} else {
N += "
tax Included";
}
if (item.monthly_includes_taxes !== mar.YES) {
enc_tax = tax;
}
if (item.mortgageoptions == mar.MORTGAGEFREE || item.monthly_includes_insurance !== mar.YES) {
if (item.has_insurance == mar.YES) {
ins = Math.floor(float(item.loan_insurance)/12);
item.o_ins = ins;
N += ",ins:"+ins;
}
} else if (item.monthly_includes_insurance === mar.YES) {
if (item.has_insurance == mar.YES) {
ins = Math.floor(float(item.loan_insurance)/12);
item.o_ins = `Included`;
monthly_mortgage -= ins;
N += ",ins:"+ins;
}
} else {
N += "
ins Included";
}
if (item.monthly_includes_taxes !== mar.YES) {
enc_ins = ins;
}
if (item.has_hoa == mar.YES) {
hoa = float(item.loan_hoa);
var freq = float(item.loan_hoa_freq);
hoa = hoa / freq;
N += ",hoa:"+hoa;
} else {
N += "
noHOA";
}
var monthly = (float(monthly_mortgage) + float(ins) + float(tax) + float(hoa));
N += "
monthly:"+monthly;
N += "]";
if (item._use_rq_for_monthly === true) {
/* -- FEBE RULE 2 -- */
monthly = num(item.RQ_LOANMONTHLY);
N += `
monthly from offer:${monthly}]`;
}
item.monthlybreakdown = {
mortgage : float(monthly_mortgage),
insurance : float(ins),
tax : float(tax),
hoa : float(hoa),
monthly : monthly,
o_mortgage : item.o_monthly_mortgage,
o_tax : item.o_tax,
o_ins : item.o_ins
};
item.enc_maintenance_A = float(enc_ins) + float(enc_tax) + float(hoa);
item.enc_maintenance_C = float(enc_ins) + float(enc_tax) + float(hoa);
/**
* Accumulate
* retval -> breakdown -> [mortgage, insurance, tax, hoa, monthly]
*/
for (let x in item.monthlybreakdown) {
retval.breakdown[x] += item.monthlybreakdown[x];
}
/**
* If this is the primary Accumulate
* retval -> breakdown_primary -> [mortgage, insurance, tax, hoa, monthly]
*/
item.is_current_primary = false;
if (item.reo_use == "primary" && MAR.getOpt(item, "whosname","").includes("0") && retval.currentPrimaryIndex === false) {
retval.currentPrimaryIndex = i;
item.is_current_primary = true;
for (let x in item.monthlybreakdown) {
retval.breakdown_primary[x] += item.monthlybreakdown[x];
}
}
item.rentalA = item.rental;
item.rentalC = false;
item.rentalE = false;
item.rentalF = false;
item.gross_rental = false;
item.rental_income_capped_zero = false;
if (item.reo_use == "investment") {
var last = ("reo_rental_2015" in item) ? float(item.reo_rental_2015,10) : 0;
var prev = ("reo_rental_2016" in item) ? float(item.reo_rental_2016,10) : 0;
var pm = ("reo_rental_pm" in item) ? float(item.reo_rental_pm,10) : false;
var reo_rental_future_contract = MAR.getOpt(item, "reo_rental_future_contract" , "N");
if (pm !== false) {
item.rental = pm
} else {
item.rental = (((prev+last)/2)/12);
}
let m_uinc = MAR.reo.calc_income_from_1040(item);
if (m_uinc !== false) {
item.rental_1040 = m_uinc;
item.rental = m_uinc;
}
var deduction = false;
if (PROG === "va" && item.experience_2y === false) {
item.rental = 0;
item.rent_dec_reason = "0% VA not on tax for 2 years";
item.rent_dec_reasons = ["Zero usable rent because the program is VA and it is not on the tax returns for at least 2 years"];
item.rent_dec_reasons = ["Rental income not on taxes. Elaine expects 0% of rent to be allowed as income."];
deduction = true;
}
if (PROG === "fha" && item.experience_1y === false) {
item.rental = 0;
item.rent_dec_reason = "0% FHA not on tax for 1 year";
item.rent_dec_reasons = ["Zero usable rent because the program is FHA and it is not on the tax returns for at least 1 years"];
item.rent_dec_reasons = ["Rental income not on taxes. Elaine expects 0% of rent to be allowed as income."]
deduction = true;
}
item.rentalB = item.rental;
item.useable_rent = item.rental;
// var reo_rental_income_continuous_for_2_years = item.reo_rental_income_continuous_for_2_years;
// if (reo_rental_income_continuous_for_2_years == mar.NO) {
// if (!deduction) {
// item.rental = float(item.rental) * 0.75;
// item.rentalB = item.rental;
// N += "[CUR
non continuous - deduct 25%:"+item.rental;
//
// deduction = true;
// }
//
// var reo_rental_start_date = item.reo_rental_start_date;
// var reo_rental_start_date_D = new Date(reo_rental_start_date);
//
// N += "
" + reo_rental_start_date;
// N += "
" + reo_rental_start_date_D;
//
// }
item.rentalC = false;
var reo_rental_income_on_tax_returns = item.reo_rental_income_on_tax_returns;
let reo_rental_future_contract_rentroll = MAR.getOpt(item,`reo_rental_future_contract_rentroll`,``);
if (reo_rental_income_on_tax_returns == mar.NO) {
if (reo_rental_future_contract !== "Y" && reo_rental_future_contract_rentroll !== "Y") {
if (!deduction) {
// item.rental = float(item.rental) * 0.75;
// item.rentalC = item.rental;
//
// N += "[CUR
not on tax returns - deduct 25%:"+item.rental;
//
// deduction = true;
item.rental = 0;
item.rentalC = item.rental;
item.useable_rent = item.rental;
N += "[CUR
not on tax returns - deduct 100%:"+item.rental;
deduction = true;
item.rent_dec_reason = "0% Inv->not on tax->No future contract";
item.rent_dec_reasons = ["Zero usable rent because this Investment property does not appear on tax returns and has no future contract or rent roll analysis"];
}
} else {
if (!deduction) {
item.rental = float(item.rental) * 0.75;
item.useable_rent = item.rental;
item.rentalC = item.rental;
N += "[CUR
not on tax retunns with 12 month contract - deduct 25%:"+item.rental;
deduction = true;
item.rent_dec_reason = "75% Inv->not on tax->Has future contract";
if (reo_rental_future_contract === "Y") {
item.rent_dec_reasons = ["Rental income not on taxes. Elaine expects 75% of rental contract"];
} else {
item.rent_dec_reasons = ["Rental income not on taxes. Elaine expects 75% of rent roll analysis"];
}
}
}
} else {
// var reo_rental_income_on_tax_returns_100 = item.reo_rental_income_on_tax_returns_100;
// if (reo_rental_income_on_tax_returns_100 == mar.NO) {
//
// if (!deduction) {
// item.rental = float(item.rental) * 0.75;
// item.rentalD = item.rental;
//
// N += "[CUR
not on tax 100 returns - deduct 25%:"+item.rental;
// deduction = true;
// }
// }
}
if (item.rental > 0 && retval.experience_1y === false) {
item.rental_income_capped_zero = true;
item.rent_dec_reason += "Capped at zero (no experience)";
item.rent_dec_reasons.push(", however never more than $ 0 income, due to lack of experience.");
}
N += `
invchk2 : rent_dec_reason ${item.rent_dec_reason}`;
var reo_rental_future_contract = item.reo_rental_future_contract;
if (item.rental > 0 && item.rent_dec_reason === "") {
item.rent_dec_reason = "100% rental income";
item.rent_dec_reasons = [];
}
if (PROG == "other" && item.rent_dec_reasons.length > 0) {
item.rent_dec_reasons.push(". Elaine expects the Rental income partially usable in NonQM according to lender guidelines. It may be possible to use higher amounts of rental income when advising a Non-QM loan. Check guidelines.");
} else {
item.rent_dec_reasons.push(". Elaine expects the Rental income usable according to lender guidelines. Check guidelines.");
}
N += "[CUR
net-rental:"+item.rental;
N += "]";
item.current_rental = item.rental;
}
var loan_hoa = float(item.loan_hoa,10);
var loan_hoa_freq = ("loan_hoa_freq" in item) ? float(item.loan_hoa,10) : 12; // per 1 , 3 , 12 months
loan_hoa = loan_hoa / loan_hoa_freq;
item.expected_rentalA = item.expected_rental;
if (item.reo_use == "primary") {
/**
* primary -> investment
*/
if (item.reo_use2 == "investment") {
item.expected_rental = 0;
item.useable_rent = item.expected_rental;
item._vacating_primary = `Y`;
item.expected_rentalB = item.expected_rental;
if ("reo_expected_rental" in item) {
item.expected_rental = float(item.reo_expected_rental);
item.useable_rent = item.expected_rental;
N += "[EXP rental:"+item.expected_rental;
item.expected_rentalC = item.expected_rental;
}
if ("reo_expected_rental_have_contract" in item && item.reo_expected_rental_have_contract != mar.YES) {
expected_rental = 0;
item.useable_rent = item.expected_rental;
item.expected_rentalD = item.expected_rental;
N += "
We cant use it because there is no contract";
N += "
net-rental:"+item.expected_rental;
item.rent_dec_reason = "0% No Contract";
item.rent_dec_reasons = ["Zero usable rent because this Investment property does not have a contract for the expected rental"];
}
/**
* fha does not allow any expected income from the conversion of a property
*/
if (PROG == "fha" && item.expected_rental > 0) {
var reo_type = item.loantype; /* this is the loan type e.g. fha */
var reo_more_100_miles = item.reo_more_100_miles; /* is fha more than 100 miles away */
if (reo_more_100_miles == mar.YES) {
N += "
net-rental:"+item.expected_rental;
item.rent_dec_reason = "0% FHA 100 mi";
item.rent_dec_reasons = ["Zero usable rent because this Investment property is less than 100 miles away and this is not allowed under FHA rules"];
}
}
if (PROG == "va" && item.expected_rental > 0) { // of the vacating property //
expected_rental = 0;
item.useable_rent = item.expected_rental;
item.expected_rentalD = item.expected_rental;
item.rent_dec_reason = "0% VA";
item.rent_dec_reasons = ["Zero usable rent because this Investment property is not allowed under VA rules"];
}
N += `
invchk :${float(item.expected_rental)} ${(float(item.expected_rental) > 0)}`;
N += `
less 25% :"+item.expected_rental;
item.rent_dec_reason = "x75% Prim -> invest";
item.rent_dec_reasons = ["75% usable rent because this Investment property is flipping from a primary"];
}
N += `
invchk1 : rent_dec_reason ${item.rent_dec_reason}`;
if (item.expected_rental > 0 && retval.experience_1y === false) {
item.rental_income_capped_zero = true;
item.rent_dec_reason += "Capped at zero (no experience)";
item.rent_dec_reasons.push(", however never more than $ 0 income, due to lack of experience.");
// item.rent_dec_reasons.push("Rent is capped at zero due to lack of experience");
}
N += `
invchk2 : rent_dec_reason ${item.rent_dec_reason}`;
if (PROG == "other" && item.rent_dec_reasons.length > 0) {
item.rent_dec_reasons.push(". Elaine expects the Rental income partially usable in NonQM according to lender guidelines. lender guidelines. It may be possible to use higher amounts of rental income when advising a Non-QM loan. Check guidelines.");
} else {
item.rent_dec_reasons.push(". Elaine expects the Rental income usable in NonQM according to lender guidelines. lender guidelines. It may be possible to use higher amounts of rental income when advising a Non-QM loan. Check guidelines.");
}
//item.expected_rental -= float(monthly);
item.expected_rentalF = item.expected_rental;
N += "
less costs of:"+monthly;
N += "
net-rental:"+item.expected_rental;
N += "]";
item.rental += item.expected_rental
item.rental0A = item.rental;
} else {
var pm = ("reo_rental_pm" in item) ? float(item.reo_rental_pm,10) : false;
if (pm !== false) {
N += "Use existing rental";
item.rental += pm;
}
}
}
if (item.reo_use == "investment" || item.reo_use2 == "investment") {
if (MAR.is_current_address_rented_and_will_continue() !== false) {
if (PROG == "other") {
item.rent_dec_reasons.push("
** Check QM guidelines if buying or refinancing an Investment Property is allowed when no primary property is owned.
");
}
}
}
/* over ride rental with company result here */
item.rental_income_from_company = false;
item.rental_income_from_company_t = ``;
if (item.propertyinllc === `Y`) {
let f8825_opt = MAR.getOpt(item, `f8825_opt`);
if (f8825_opt === `opt_8825` || f8825_opt === `opt_est`) {
let incs = getIncome_v2(`web`,{}, true);
let incomes = MAR.getOpt(item, `propertyinllc_incomes`,``).split(`,`);
let total = 0;
for (let i=1; i < incs.detailmatrix.length -1; i++) {
let inc = incs.detailmatrix[i];
if (inc.length < 3) continue;
let uuid = MAR.getOpt(inc,`10`,``);
if (uuid === ``) continue;
if (incomes.indexOf(uuid) > -1) {
let inc_tot = MAR.getOptNum(inc,`7`,0);
total += inc_tot;
}
}
item.rental = total;
item.rental_income_from_company = true;
item.rental_income_from_company_t = `8825`;
if (f8825_opt === `opt_est`) {
item.rental_income_from_company_t = `8825_est`;
// set mortgages as omittable
} else {
// set mortgages as omittable WITH business bank account conditions
}
}
// else if (f8825_opt === `opt_est`) {
// let m_uinc_f8825 = MAR.reo.calc_income_from_8825(item);
// item.rental = m_uinc_f8825;
// item.rental_income_from_company = true;
// item.rent_dec_reasons.push("
** Estimates were used which will need to be verified with business bank statements.