diff --git a/components/new/details.vue b/components/new/details.vue index 760da35..019d257 100644 --- a/components/new/details.vue +++ b/components/new/details.vue @@ -48,7 +48,7 @@ <section class="form inputs"> <h3>Property Details</h3> <label>Price ($)</label> -<input :value="estimate.price" @input="(e) => $emit('update:price', strip(e))"> +<input :value="estimate.price/100" @input="(e) => $emit('update:price', strip(e))"> <label>Type</label> <select id="" name="" :value="estimate.property" @@ -113,7 +113,7 @@ <label>Total DTI (%) - Optional</label> <input :value="loan.dti" @input="(e) => $emit('update:dti', e)"> <label>Home Owner's Association ($/month)</label> -<input :value="loan.hoa" +<input :value="loan.hoa / 100" @input="(e) => { $emit('update:hoa', strip(e)) }"> <label>Interest Rate (%)</label> @@ -127,14 +127,14 @@ <input :value="loan.hazardEscrow" @input="(e) => { $emit('update:hazardEscrow', stripInt(e)) }"> <label>Hazard Insurance ($/month)</label> -<input :value="loan.hazard" +<input :value="loan.hazard / 100" @input="(e) => $emit('update:hazard', strip(e))"> <label>Real Estate Tax Escrow (months)</label> <input :value="loan.taxEscrow" @input="e => $emit('update:taxEscrow', stripInt(e))"> <label>Real Estate Tax ($/month)</label> -<input :value="loan.tax" +<input :value="loan.tax/100" @input="(e) => $emit('update:tax', strip(e))"> </section> @@ -144,7 +144,8 @@ :key="fee.name + indx" class="fee" > <label> - ${{fee.amount}}{{ fee.perc ? ` ${fee.perc}%` : ''}} - {{fee.name}}<br> + ${{(fee.amount / 100).toFixed(2)}} + {{ fee.perc ? ` ${fee.perc}%` : ''}} - {{fee.name}}<br> {{fee.type}} </label> <img width="21" height="21" src="/assets/image/icon/x-red.svg" diff --git a/components/new/new.vue b/components/new/new.vue index c79ef08..2024a90 100644 --- a/components/new/new.vue +++ b/components/new/new.vue @@ -37,26 +37,26 @@ class="bi bi-plus" viewBox="0 0 16 16"> <path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 @update:property="(p) => estimate.property = p" @update:loanType="(lt) => loan.type.id = lt" - @update:term="(lt) => loans[sel].term = lt" + @update:term="(lt) => loan.term = lt" @update:program="(p) => loans[sel].program = p" @update:ltv="setLtv" @update:amount="setAmount" @update:housingDti="setHousingDti" @update:dti="setDti" - @update:hoa="(hoa) => loans[sel].hoa = hoa" - @update:interest="(i) => loans[sel].interest = i" + @update:hoa="(hoa) => loan.hoa = hoa*100" + @update:interest="(i) => loan.interest = i" @update:interestDays="(d) => loans[sel].interestDays = d" @update:hazardEscrow="(h) => loans[sel].hazardEscrow = h" - @update:hazard="(h) => loans[sel].hazard = h" + @update:hazard="(h) => loan.hazard = h * 100" @update:taxEscrow="(t) => loans[sel].taxEscrow = t" - @update:tax="(t) => loans[sel].tax = t" - @update:manualMI="perc => loans[sel].mi.rate = perc" + @update:tax="(t) => loan.tax = t*100" + @update:manualMI="perc => loan.mi.rate = perc" @toggle:manualMIMonthly= "() => loans[sel].mi.monthly = !loans[sel].mi.monthly" @continue="generate" /> <loan-summary v-if="hash == '#new/summary'" - :loan="loan" :downpayment="estimate.price - loan.amount" :token="token" :estimate="estimate"/> + :loan="loan" :downpayment="estimate.price - loan.amount" :token="token" :estimate="estimate"/> </div> </template> @@ -81,7 +81,7 @@ const example = { hazardEscrow: 0, // Hazard insurance escrow in months (0 is none) tax: 0, // Real Estate taxes monthly payment taxEscrow: 0, // Months to escrow (0 is none) - hoa: 100, // Home owner's association monthly fee + hoa: 10000, // Home owner's association monthly fee program: "", pud: true, // Property under development zip: '', @@ -133,7 +133,7 @@ function del() { // Updates the property price for all loans and their fee amounts. function setPrice(value) { - this.estimate.price = value + this.estimate.price = Math.round(value*100) this.estimate.loans[this.sel].fees.forEach(fee => { if (fee.perc) fee.amount = (fee.perc / 100 * value).toFixed(2) }) @@ -151,21 +151,21 @@ function setLtv(e) { this.loan.ltv = ltv let num = ltv / 100 * this.estimate.price - this.loan.amount = Math.round(num*100) + this.loan.amount = Math.round(num) } // Changes loan.amount\'s <input> and data() values, then syncs with data.ltv // Loan amount is in cents but LTV is in decimals so some rounding needs to be done. function setAmount(e) { - let amount = strip(e) + let amount = strip(e) * 100 if (!this.estimate.price) return - if (amount > this.loan.price) amount = this.loan.price + if (amount > this.estimate.price) amount = this.estimate.price if (amount < 0) amount = 0 - this.loan.amount = Math.round(amount * 100) - let num = amount / this.estimate.price * 100 - this.loan.ltv = Math.round(num*100) / 100 + this.loan.amount = Math.round(amount) + let num = amount / this.estimate.price + this.loan.ltv = Math.round(num*100) } function setDti(e) { diff --git a/components/new/summary.vue b/components/new/summary.vue index 83e3db7..594bb99 100644 --- a/components/new/summary.vue +++ b/components/new/summary.vue @@ -1,22 +1,23 @@ <template> -<div v-if="downpayment && totalMonthly > 0"> +<div v-if="valid"> <section class="form inputs"> -<h3>Monthly Payment - ${{totalMonthly}}</h3> -<label>Loan payment: ${{loanPayment.toFixed(2)}}</label> +<h3>Monthly Payment - ${{format(totalMonthly)}}</h3> +<label>Loan payment: ${{format(loanPayment)}}</label> <label v-if="loan.mi.monthly"> - Mortgage insurance: ${{(loan.amount*loan.mi.rate/100/12).toFixed(2)}} + Mortgage insurance: ${{format(loan.amount*loan.mi.rate/100/12)}} </label> -<label>Property taxes: ${{loan.tax}}</label> +<label>Property taxes: ${{format(loan.tax)}}</label> +<label>Homeowner's Insurance: ${{format(loan.hoa)}}</label> </section> <section class="form inputs"> -<h3>Cash to Close - ${{totalMonthly}}</h3> -<label>Closing costs: ${{fees}}</label> +<h3>Cash to Close - ${{format(cashToClose)}}</h3> +<label>Closing costs: ${{format(fees)}}</label> <label v-if="credits">Credits: ${{credits}}</label> -<label>Down payment: ${{downpayment.toFixed(2)}}</label> +<label>Down payment: ${{format(downpayment)}}</label> <label v-if="!loan.mi.monthly"> - Mortgage insurance: ${{(loanPayment*loan.mi.rate/100).toFixed(2)}} + Mortgage insurance: ${{format(loan.amount*loan.mi.rate/100)}} </label> </section> @@ -30,7 +31,8 @@ <script setup> import { ref, computed, onMounted } from 'vue' -const props = defineProps(['downpayment', 'loan', 'valid', 'token', 'estimate']) +let valid = ref(false) +const props = defineProps(['downpayment', 'loan', 'token', 'estimate']) function amortize(principle, rate, periods) { return principle * rate*(1+rate)**periods / ((1+rate)**periods - 1) @@ -38,43 +40,46 @@ function amortize(principle, rate, periods) { const loanPayment = computed(() => { let amount = props.loan.amount - if (!props.loan.mi.monthly) amount = - amount + props.loan.mi.rate/100*(amount+props.downpayment) + return amortize(props.loan.amount, props.loan.interest / 100 / 12, props.loan.term*12) }) -const totalMonthly = computed ( - () => (loanPayment.value + +const totalMonthly = computed (() => { + let total = loanPayment.value + props.loan.tax + props.loan.hoa + - props.loan.hazard).toFixed(2) - ) - -const totalCash = computed ( - () => (fees.value + - credits.value + - props.downpayment).toFixed(2) - ) + props.loan.hazard + + if (props.loan.mi.monthly) { + total = total + props.loan.mi.rate/100*(props.loan.amount) + } + return total +}) // Closing costs const fees = computed(() => { return props.loan.fees.reduce((total, x) => { return x.amount > 0 ? total + x.amount : 0 }, 0 - ).toFixed(2) + ) }) const credits = computed(() => { return props.loan.fees.reduce((total, x) => { return x.amount < 0 ? total + x.amount : 0 }, 0 - ).toFixed(2) + ) }) const cashToClose = computed(() => { - return fees + credits + downpayment + let total = fees.value + credits.value + props.downpayment + if (!props.loan.mi.monthly) { + total = total + props.loan.mi.rate/100*(props.loan.amount) + } + + return total }) function validate() { @@ -87,15 +92,21 @@ function validate() { }, }).then(resp => { if (resp.ok && resp.status == 200) { + valid.value = true return } else { // resp.text().then(t => this.errors = [t]) - window.location.hash = 'new' + // window.location.hash = 'new' } }) } +// Print number of cents as a nice string of dollars +function format(num) { + return (num/100).toFixed(2) +} + onMounted(() => {validate()}) </script> diff --git a/skouter.go b/skouter.go index a2f76c0..2f18d98 100644 --- a/skouter.go +++ b/skouter.go @@ -94,7 +94,7 @@ type Loan struct { Ltv float32 `json:"ltv"` Dti float32 `json:"dti"` Hoi int `json:"hoi"` - Interest int `json:"interest"` + Interest float32 `json:"interest"` Mi MI `json:"mi"` Fees []Fee `json:"fees"` Name string `json:"name"`