@@ -386,9 +386,17 @@ section.mi .row input[type=checkbox] { | |||
} | |||
section.estimates .entry { | |||
margin: 10px 0; | |||
padding: 10px 3px; | |||
border: 2px solid var(--outline); | |||
border-radius: 3px; | |||
} | |||
section.estimates .entry:hover { | |||
cursor: pointer; | |||
} | |||
section.estimates .details { | |||
display: flex; | |||
flex-flow: column; | |||
gap: 10px; | |||
} |
@@ -34,14 +34,21 @@ | |||
<div class="entry" v-for="e in estimates" v-if="!estimate"> | |||
<span @click="() => estimate = e"> | |||
{{e.id}} - {{e.property}} - ${{e.price/100}} | |||
{{e.id}} - {{e.property}} - ${{(e.price/100).toLocaleString()}} | |||
</span> | |||
</div> | |||
<div class="details" v-if="estimate"> | |||
{{estimate}} | |||
<label>{{estimate.id}} - {{estimate.property}} - ${{estimate.price / 100}}</label> | |||
<button @click="summarize">test</button> | |||
<label> | |||
#{{estimate.id}} - | |||
{{estimate.transaction}} - | |||
{{estimate.property}} - | |||
${{(estimate.price / 100).toLocaleString()}} | |||
</label> | |||
<label>Borrowers: {{estimate.borrower.num}}</label> | |||
<label>Credit: {{estimate.borrower.credit}}</label> | |||
<label>Income: {{(estimate.borrower.income/100).toLocaleString()}}</label> | |||
<button @click="() => estimate = null">Cancel</button> | |||
</div> | |||
</section> | |||
@@ -101,7 +108,7 @@ function summarize() { | |||
if (response.ok) { return response.json() } else { | |||
response.text().then(t => console.log(t)) | |||
} | |||
}).then (result => { | |||
}).then(result => { | |||
if (!result || !result.length) return // Exit if token is invalid or no fees are saved | |||
console.log('done', result) | |||
}) | |||
@@ -105,6 +105,7 @@ function validate() { | |||
} | |||
function create() { | |||
saved.value = true | |||
fetch(`/api/estimate`, | |||
{method: 'POST', | |||
body: JSON.stringify(props.estimate), | |||
@@ -114,13 +115,13 @@ function create() { | |||
}, | |||
}).then(resp => { | |||
if (resp.ok && resp.status == 200) { | |||
console.log('saved') | |||
saved.value = true | |||
return | |||
} else { | |||
// resp.text().then(t => this.errors = [t]) | |||
// window.location.hash = 'new' | |||
resp.text().then(t => console.log(t)) | |||
saved.value = false | |||
} | |||
}) | |||
@@ -89,7 +89,8 @@ CREATE TABLE loan ( | |||
interest FLOAT(5, 2) DEFAULT 0, | |||
ltv FLOAT(5, 2) DEFAULT 0, | |||
dti FLOAT(5, 2) DEFAULT 1, | |||
hoi INT DEFAULT 0, /* Hazard insurance annual payments */ | |||
hoi INT DEFAULT 0, /* Home owner's insurance annual payments */ | |||
hazard INT DEFAULT 0, /* Hazard insurance annual payments */ | |||
tax INT DEFAULT 0, /* Real estate taxes */ | |||
name VARCHAR(30) DEFAULT '', | |||
PRIMARY KEY (`id`), | |||
@@ -125,8 +125,6 @@ type Result struct { | |||
Fees int `json:"fees"` | |||
Credits int `json:"credits"` | |||
CashToClose int `json:"cashToClose"` | |||
Zip string `json:"zip"` | |||
Pud bool `json:"pud"` | |||
} | |||
type Estimate struct { | |||
@@ -140,6 +138,7 @@ type Estimate struct { | |||
Zip string `json:"zip"` | |||
Pud bool `json:"pud"` | |||
Loans []Loan `json:"loans"` | |||
Result []Result `json:"result"` | |||
} | |||
var ( | |||
@@ -221,27 +220,35 @@ func summarize(w http.ResponseWriter, db *sql.DB, r *http.Request) { | |||
exp := math.Pow(1+rate, periods) | |||
return int(principle * rate * exp / (exp - 1)) | |||
} | |||
loan := estimate.Loans[0] | |||
result.LoanPayment = amortize(float64(loan.Amount), | |||
for _, loan := range estimate.Loans { | |||
// Monthly payments use amortized loan payment formula plus monthly MI, | |||
// plus all other recurring fees | |||
result.LoanPayment = amortize(float64(loan.Amount), | |||
float64(loan.Interest / 100 / 12), | |||
float64(loan.Term * 12)) | |||
result.TotalMonthly = result.LoanPayment + loan.Hoi + loan.Tax + loan.Hazard | |||
if loan.Mi.Monthly { | |||
result.TotalMonthly = result.TotalMonthly + | |||
int(loan.Mi.Rate/100*float32(loan.Amount)) | |||
} | |||
result.TotalMonthly = result.LoanPayment + loan.Hoi + loan.Tax + loan.Hazard | |||
if loan.Mi.Monthly { | |||
result.TotalMonthly = result.TotalMonthly + | |||
int(loan.Mi.Rate/100*float32(loan.Amount)) | |||
} | |||
for i := range loan.Fees { | |||
if loan.Fees[i].Amount > 0 { | |||
result.Fees = result.Fees + loan.Fees[i].Amount | |||
} else { | |||
result.Credits = result.Credits + loan.Fees[i].Amount | |||
for i := range loan.Fees { | |||
if loan.Fees[i].Amount > 0 { | |||
result.Fees = result.Fees + loan.Fees[i].Amount | |||
} else { | |||
result.Credits = result.Credits + loan.Fees[i].Amount | |||
} | |||
} | |||
result.CashToClose = | |||
result.Fees + result.Credits + (estimate.Price - loan.Amount) | |||
} | |||
result.CashToClose = | |||
result.Fees + result.Credits + (estimate.Price - loan.Amount) | |||
loan := estimate.Loans[0] | |||
json.NewEncoder(w).Encode(result) | |||
} | |||