@@ -20,14 +20,14 @@ | |||||
<h3>Borrower</h3> | <h3>Borrower</h3> | ||||
<label>Number of Borrowers</label> | <label>Number of Borrowers</label> | ||||
<input :value="estimate.borrowers" | |||||
@input="(e) => $emit('update:borrowers', stripInt(e))"> | |||||
<input :value="estimate.borrower.num" | |||||
@input="(e) => $emit('update:borrowerNum', stripInt(e))"> | |||||
<label>Credit Score</label> | <label>Credit Score</label> | ||||
<input :value="estimate.creditScore" | |||||
@input="(e) => $emit('update:creditScore', stripInt(e))"> | |||||
<input :value="estimate.borrower.credit" | |||||
@input="(e) => $emit('update:borrowerCredit', stripInt(e))"> | |||||
<label>Monthly Income ($)</label> | <label>Monthly Income ($)</label> | ||||
<input :value="estimate.mIncome" | |||||
@input="(e) => $emit('update:mIncome', strip(e))"> | |||||
<input :value="estimate.borrower.income" | |||||
@input="(e) => $emit('update:borrowerIncome', strip(e))"> | |||||
</section> | </section> | ||||
@@ -64,26 +64,27 @@ | |||||
<h3>Loan Type</h3> | <h3>Loan Type</h3> | ||||
<input type="radio" | <input type="radio" | ||||
name="loan_type" | name="loan_type" | ||||
value="conv" | |||||
:checked="loan.type.id == 1" | |||||
value="1" | |||||
@change="(e) => $emit('update:loanType', e.target.value)" | @change="(e) => $emit('update:loanType', e.target.value)" | ||||
> | > | ||||
<label>Conventional</label> | <label>Conventional</label> | ||||
<input type="radio" | <input type="radio" | ||||
name="loan_type" | name="loan_type" | ||||
value="fha" | |||||
:checked="loan.type == 'fha'" | |||||
value="2" | |||||
:checked="loan.type.id == 2" | |||||
@change="(e) => $emit('update:loanType', e.target.value)"> | @change="(e) => $emit('update:loanType', e.target.value)"> | ||||
<label>FHA</label> | <label>FHA</label> | ||||
<input type="radio" | <input type="radio" | ||||
name="loan_type" | name="loan_type" | ||||
value="va" | |||||
:checked="loan.type == 'va'" | |||||
value="3" | |||||
:checked="loan.type.id == 3" | |||||
@change="(e) => $emit('update:loanType', e.target.value)"> | @change="(e) => $emit('update:loanType', e.target.value)"> | ||||
<label>VA</label> | <label>VA</label> | ||||
<input type="radio" | <input type="radio" | ||||
name="loan_type" | name="loan_type" | ||||
value="usda" | |||||
:checked="loan.type == 'usda'" | |||||
value="4" | |||||
:checked="loan.type.id == 4" | |||||
@change="(e) => $emit('update:loanType', e.target.value)"> | @change="(e) => $emit('update:loanType', e.target.value)"> | ||||
<label>USDA</label> | <label>USDA</label> | ||||
</section> | </section> | ||||
@@ -217,55 +218,16 @@ function validate() { | |||||
"Accept": "application/json", | "Accept": "application/json", | ||||
"Authorization": `Bearer ${this.token}`, | "Authorization": `Bearer ${this.token}`, | ||||
}, | }, | ||||
}).then(response => { | |||||
if (response.ok) { return response.json() } | |||||
response.text().then(t => this.errors = [t]) | |||||
}).then(result => { | |||||
if (result) this.$emit('continue', result) | |||||
}) | |||||
/* | |||||
let errors = [] | |||||
const estimate = this.estimate | |||||
// Alternative attribute names for error messages | |||||
const names = { | |||||
term: "loan term", | |||||
ltv: "loan to value", | |||||
hazard: "hazard insurance", | |||||
hazardEscrow: "hazard insurance escrow", | |||||
} | |||||
if (!estimate.property) { | |||||
errors.push("Missing property type.") | |||||
} else if (!estimate.price) { | |||||
errors.push("Missing property price.") | |||||
} else if (!estimate.borrowers) { | |||||
errors.push("Missing number of borrowers.") | |||||
} else if (!estimate.creditScore) { | |||||
errors.push("Missing credit score.") | |||||
} else if (!estimate.mIncome) { | |||||
errors.push("Missing monthly income.") | |||||
} | |||||
estimate.loans.forEach(l => { | |||||
if (errors.length) return | |||||
if (!l.amount) { | |||||
errors.push(`${l.title} Loan amount cannot be zero`) | |||||
} else if (!l.interest) { | |||||
errors.push(`${l.title} Interest rate cannot be zero`) | |||||
} else if (!l.term) { | |||||
errors.push(`${l.title} Loan term cannot be zero`) | |||||
}).then(resp => { | |||||
if (resp.ok && resp.status == 200) { | |||||
this.errors = [] | |||||
this.$emit('continue') | |||||
return | |||||
} else { | |||||
resp.text().then(t => this.errors = [t]) | |||||
} | } | ||||
}) | }) | ||||
if (errors.length) { | |||||
this.errors = errors | |||||
return false | |||||
} | |||||
return true | |||||
*/ | |||||
} | } | ||||
function generate() { | function generate() { | ||||
@@ -288,9 +250,9 @@ export default { | |||||
emits: [ | emits: [ | ||||
'del', | 'del', | ||||
'update:name', | 'update:name', | ||||
'update:borrowers', | |||||
'update:creditScore', | |||||
'update:mIncome', | |||||
'update:borrowerNum', | |||||
'update:borrowerCredit', | |||||
'update:borrowerIncome', | |||||
'update:transaction', | 'update:transaction', | ||||
'update:price', | 'update:price', | ||||
'update:property', | 'update:property', | ||||
@@ -29,9 +29,9 @@ class="bi bi-plus" viewBox="0 0 16 16"> <path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 | |||||
@update:name="(name) => loans[sel].title = name" | @update:name="(name) => loans[sel].title = name" | ||||
@del="del" | @del="del" | ||||
@update:borrowers="(b) => estimate.borrowers = b" | |||||
@update:creditScore="(c) => estimate.creditScore = c" | |||||
@update:mIncome="(m) => estimate.mIncome = m" | |||||
@update:borrowerNum="(b) => estimate.borrower.num = b" | |||||
@update:borrowerCredit="(c) => estimate.borrower.credit = c" | |||||
@update:borrowerIncome="(m) => estimate.borrower.income = m" | |||||
@update:transaction="(t) => estimate.transaction = t" | @update:transaction="(t) => estimate.transaction = t" | ||||
@update:price="setPrice" | @update:price="setPrice" | ||||
@update:property="(p) => estimate.property = p" | @update:property="(p) => estimate.property = p" | ||||
@@ -94,7 +94,7 @@ const loans = [ | |||||
Object.assign({}, example,), | Object.assign({}, example,), | ||||
Object.assign( | Object.assign( | ||||
Object.assign({}, example), | Object.assign({}, example), | ||||
{title: "Another One", mi: {rate: 0}} | |||||
{title: "Another One", mi: {rate: 0}, type: {}} | |||||
), | ), | ||||
] | ] | ||||
@@ -103,9 +103,7 @@ const estimate = { | |||||
property: "", | property: "", | ||||
transaction: 0, | transaction: 0, | ||||
price: 0, | price: 0, | ||||
borrowers: 0, | |||||
creditScore: 0, | |||||
mIncome: 0, | |||||
borrower: {num: 0, credit: 0, income: 0}, | |||||
loans: loans, | loans: loans, | ||||
} | } | ||||
@@ -116,7 +114,10 @@ function loan() { | |||||
// Clone loan from initial example as a new loan | // Clone loan from initial example as a new loan | ||||
function create() { | function create() { | ||||
this.estimate.loans.push( | this.estimate.loans.push( | ||||
Object.assign({}, example, {fees: this.createFees()}) | |||||
Object.assign( | |||||
{}, | |||||
example, {fees: this.createFees()} | |||||
) | |||||
) | ) | ||||
} | } | ||||
@@ -153,7 +154,8 @@ function setLtv(e) { | |||||
if (ltv < 0) ltv = 0 | if (ltv < 0) ltv = 0 | ||||
this.loan.ltv = ltv | this.loan.ltv = ltv | ||||
this.loan.amount = (ltv / 100 * this.estimate.price).toFixed(2) | |||||
let num = ltv / 100 * this.estimate.price | |||||
this.loan.amount = Math.round(num*100) / 100 | |||||
} | } | ||||
// Changes loan.amount\'s <input> and data() values, then syncs with data.ltv | // Changes loan.amount\'s <input> and data() values, then syncs with data.ltv | ||||
@@ -165,7 +167,8 @@ function setAmount(e) { | |||||
if (amount < 0) amount = 0 | if (amount < 0) amount = 0 | ||||
this.loan.amount = amount | this.loan.amount = amount | ||||
this.loan.ltv = (amount / this.estimate.price * 100).toFixed(2) | |||||
let num = amount / this.estimate.price * 100 | |||||
this.loan.ltv = Math.round(num*100) / 100 | |||||
} | } | ||||
function setDti(e) { | function setDti(e) { | ||||
@@ -88,8 +88,8 @@ type Loan struct { | |||||
Id int `json:id` | Id int `json:id` | ||||
EstimateId int `json:estimate_id` | EstimateId int `json:estimate_id` | ||||
Type LoanType `json:"loanType"` | Type LoanType `json:"loanType"` | ||||
Amount int `json:"loanAmount"` | |||||
Amortization string `json:"loanAmount"` | |||||
Amount int `json:"amount"` | |||||
Amortization string `json:"amortization"` | |||||
Term int `json:"term"` | Term int `json:"term"` | ||||
Ltv float32 `json:"ltv"` | Ltv float32 `json:"ltv"` | ||||
Dti float32 `json:"dti"` | Dti float32 `json:"dti"` | ||||
@@ -928,12 +928,15 @@ func checkFHA(l Loan, b Borrower) error { | |||||
func checkEstimate(e Estimate) error { | func checkEstimate(e Estimate) error { | ||||
if e.Property == "" { return errors.New("Empty property type") } | if e.Property == "" { return errors.New("Empty property type") } | ||||
if e.Price == 0 { return errors.New("Empty property price") } | if e.Price == 0 { return errors.New("Empty property price") } | ||||
if e.Borrower.Num == 0 { | if e.Borrower.Num == 0 { | ||||
return errors.New("Missing number of borrowers") | return errors.New("Missing number of borrowers") | ||||
} | } | ||||
if e.Borrower.Credit == 0 { | if e.Borrower.Credit == 0 { | ||||
return errors.New("Missing borrower credit score") | return errors.New("Missing borrower credit score") | ||||
} | } | ||||
if e.Borrower.Income == 0 { | if e.Borrower.Income == 0 { | ||||
return errors.New("Missing borrower credit income") | return errors.New("Missing borrower credit income") | ||||
} | } | ||||
@@ -965,7 +968,6 @@ func checkEstimate(e Estimate) error { | |||||
if err != nil { return err } | if err != nil { return err } | ||||
} | } | ||||
println("done") | |||||
return nil | return nil | ||||
} | } | ||||