@@ -386,9 +386,17 @@ section.mi .row input[type=checkbox] { | |||||
} | } | ||||
section.estimates .entry { | section.estimates .entry { | ||||
margin: 10px 0; | |||||
padding: 10px 3px; | |||||
border: 2px solid var(--outline); | |||||
border-radius: 3px; | |||||
} | } | ||||
section.estimates .entry:hover { | section.estimates .entry:hover { | ||||
cursor: pointer; | 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"> | <div class="entry" v-for="e in estimates" v-if="!estimate"> | ||||
<span @click="() => estimate = e"> | <span @click="() => estimate = e"> | ||||
{{e.id}} - {{e.property}} - ${{e.price/100}} | |||||
{{e.id}} - {{e.property}} - ${{(e.price/100).toLocaleString()}} | |||||
</span> | </span> | ||||
</div> | </div> | ||||
<div class="details" v-if="estimate"> | <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> | </div> | ||||
</section> | </section> | ||||
@@ -101,7 +108,7 @@ function summarize() { | |||||
if (response.ok) { return response.json() } else { | if (response.ok) { return response.json() } else { | ||||
response.text().then(t => console.log(t)) | 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 | if (!result || !result.length) return // Exit if token is invalid or no fees are saved | ||||
console.log('done', result) | console.log('done', result) | ||||
}) | }) | ||||
@@ -105,6 +105,7 @@ function validate() { | |||||
} | } | ||||
function create() { | function create() { | ||||
saved.value = true | |||||
fetch(`/api/estimate`, | fetch(`/api/estimate`, | ||||
{method: 'POST', | {method: 'POST', | ||||
body: JSON.stringify(props.estimate), | body: JSON.stringify(props.estimate), | ||||
@@ -114,13 +115,13 @@ function create() { | |||||
}, | }, | ||||
}).then(resp => { | }).then(resp => { | ||||
if (resp.ok && resp.status == 200) { | if (resp.ok && resp.status == 200) { | ||||
console.log('saved') | |||||
saved.value = true | saved.value = true | ||||
return | return | ||||
} else { | } else { | ||||
// resp.text().then(t => this.errors = [t]) | // resp.text().then(t => this.errors = [t]) | ||||
// window.location.hash = 'new' | // window.location.hash = 'new' | ||||
resp.text().then(t => console.log(t)) | resp.text().then(t => console.log(t)) | ||||
saved.value = false | |||||
} | } | ||||
}) | }) | ||||
@@ -89,7 +89,8 @@ CREATE TABLE loan ( | |||||
interest FLOAT(5, 2) DEFAULT 0, | interest FLOAT(5, 2) DEFAULT 0, | ||||
ltv FLOAT(5, 2) DEFAULT 0, | ltv FLOAT(5, 2) DEFAULT 0, | ||||
dti FLOAT(5, 2) DEFAULT 1, | 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 */ | tax INT DEFAULT 0, /* Real estate taxes */ | ||||
name VARCHAR(30) DEFAULT '', | name VARCHAR(30) DEFAULT '', | ||||
PRIMARY KEY (`id`), | PRIMARY KEY (`id`), | ||||
@@ -125,8 +125,6 @@ type Result struct { | |||||
Fees int `json:"fees"` | Fees int `json:"fees"` | ||||
Credits int `json:"credits"` | Credits int `json:"credits"` | ||||
CashToClose int `json:"cashToClose"` | CashToClose int `json:"cashToClose"` | ||||
Zip string `json:"zip"` | |||||
Pud bool `json:"pud"` | |||||
} | } | ||||
type Estimate struct { | type Estimate struct { | ||||
@@ -140,6 +138,7 @@ type Estimate struct { | |||||
Zip string `json:"zip"` | Zip string `json:"zip"` | ||||
Pud bool `json:"pud"` | Pud bool `json:"pud"` | ||||
Loans []Loan `json:"loans"` | Loans []Loan `json:"loans"` | ||||
Result []Result `json:"result"` | |||||
} | } | ||||
var ( | var ( | ||||
@@ -221,27 +220,35 @@ func summarize(w http.ResponseWriter, db *sql.DB, r *http.Request) { | |||||
exp := math.Pow(1+rate, periods) | exp := math.Pow(1+rate, periods) | ||||
return int(principle * rate * exp / (exp - 1)) | 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.Interest / 100 / 12), | ||||
float64(loan.Term * 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) | json.NewEncoder(w).Encode(result) | ||||
} | } | ||||