Преглед изворни кода

Calculate estimate summary values in backend

master
Immanuel Onyeka пре 1 година
родитељ
комит
6d98b7b47a
3 измењених фајлова са 110 додато и 71 уклоњено
  1. +24
    -2
      components/estimates.vue
  2. +1
    -3
      components/new/summary.vue
  3. +85
    -66
      skouter.go

+ 24
- 2
components/estimates.vue Прегледај датотеку

@@ -33,12 +33,15 @@
<h3>Saved Estimates</h3>

<div class="entry" v-for="e in estimates" v-if="!estimate">
<span @click="() => estimate = e">{{e.id}} - {{e.property}} - ${{e.price/100}}</span>
<span @click="() => estimate = e">
{{e.id}} - {{e.property}} - ${{e.price/100}}
</span>
</div>

<div class="details" v-if="estimate">
{{estimate}}
<label>Name: {{estimate.name}}</label>
<label>{{estimate.id}} - {{estimate.property}} - ${{estimate.price / 100}}</label>
<button @click="summarize">test</button>
</div>

</section>
@@ -86,6 +89,25 @@ function getEstimates() {

}

function summarize() {
fetch(`/api/estimate/summarize`,
{method: 'POST',
headers: {
"Accept": "application/json",
"Authorization": `Bearer ${props.token}`,
},
body: JSON.stringify(estimate.value),
}).then(response => {
if (response.ok) { return response.json() } else {
response.text().then(t => console.log(t))
}
}).then (result => {
if (!result || !result.length) return // Exit if token is invalid or no fees are saved
console.log('done', result)
})

}

onMounted(() => {
getEstimates()
})


+ 1
- 3
components/new/summary.vue Прегледај датотеку

@@ -42,9 +42,7 @@ function amortize(principle, rate, periods) {
return principle * rate*(1+rate)**periods / ((1+rate)**periods - 1)
}

const loanPayment = computed(() => {
let amount = props.loan.amount
const loanPayment = computed(() => {
return amortize(props.loan.amount,
props.loan.interest / 100 / 12,
props.loan.term*12)


+ 85
- 66
skouter.go Прегледај датотеку

@@ -16,6 +16,7 @@ import (
"time"
"errors"
"strings"
"math"
// pdf "github.com/SebastiaanKlippert/go-wkhtmltopdf"
"github.com/golang-jwt/jwt/v4"
)
@@ -94,6 +95,7 @@ type Loan struct {
Ltv float32 `json:"ltv"`
Dti float32 `json:"dti"`
Hoi int `json:"hoi"`
Hazard int `json:"hazard"`
Tax int `json:"hoi"`
Interest float32 `json:"interest"`
Mi MI `json:"mi"`
@@ -116,15 +118,15 @@ type MI struct {
}

type Result struct {
User int `json:"user"`
Borrower Borrower `json:"borrower"`
Transaction string `json:"transaction"`
Price int `json:"price"`
Property string `json:"property"`
Occupancy string `json:"occupancy"`
Id int `json:"loanId"`
LoanId int `json:"loanId"`
LoanPayment int `json:"loanPayment"`
TotalMonthly int `json:"totalMonthly"`
Fees int `json:"fees"`
Credits int `json:"credits"`
CashToClose int `json:"cashToClose"`
Zip string `json:"zip"`
Pud bool `json:"pud"`
Loans []Loan `json:"loans"`
}

type Estimate struct {
@@ -209,6 +211,41 @@ func match(path, pattern string, args *[]string) bool {
return true
}

func summarize(w http.ResponseWriter, db *sql.DB, r *http.Request) {
var estimate Estimate
var result Result
err := json.NewDecoder(r.Body).Decode(&estimate)
if err != nil { http.Error(w, "Invalid estimate.", 422); return }
amortize := func(principle float64, rate float64, periods float64) int {
exp := math.Pow(1+rate, periods)
return int(principle * rate * exp / (exp - 1))
}
loan := estimate.Loans[0]
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))
}
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)
json.NewEncoder(w).Encode(result)
}

func getLoanType(
db *sql.DB,
user int,
@@ -249,10 +286,11 @@ func getLoanType(
func getFees(db *sql.DB, loan int) ([]Fee, error) {
var fees []Fee

rows, err := db.Query(
"SELECT * FROM fees " +
"WHERE loan_id = ?",
loan)
query := `SELECT id, loan_id, amount, perc, type, notes, name, category
FROM fee
WHERE loan_id = ?`
rows, err := db.Query(query, loan)
if err != nil {
return nil, fmt.Errorf("Fee query error %v", err)
@@ -340,9 +378,14 @@ func getMi(db *sql.DB, loan int) (MI, error) {
initial_premium, initial_rate, initial_amount
FROM mi WHERE loan_id = ?`

row := db.QueryRow(query, loan)
rows, err := db.Query(query, loan)
if err != nil { return mi, err }
defer rows.Close()

if err := row.Scan(
if (!rows.Next()) { return mi, nil }
if err := rows.Scan(
&mi.Type,
&mi.Label,
&mi.Lender,
@@ -361,53 +404,6 @@ func getMi(db *sql.DB, loan int) (MI, error) {
return mi, nil
}

func getLoans(db *sql.DB, estimate int) ([]Loan, error) {
var loans []Loan

query := `SELECT
l.id, l.amount, l.term, l.interest, l.ltv, l.dti, l.hoi,
lt.id, lt.user_id, lt.branch_id, lt.name
FROM loan l INNER JOIN loan_type lt ON l.type_id = lt.id
WHERE l.estimate_id = ?
`
rows, err := db.Query(query, estimate)
if err != nil {
return nil, fmt.Errorf("Loan query error %v", err)
}

defer rows.Close()

for rows.Next() {
var loan Loan

if err := rows.Scan(
&loan.Id,
&loan.Amount,
&loan.Term,
&loan.Interest,
&loan.Ltv,
&loan.Dti,
&loan.Hoi,
&loan.Type.Id,
&loan.Type.User,
&loan.Type.Branch,
&loan.Type.Name,
)
err != nil {
return loans, fmt.Errorf("Loans scanning error: %v", err)
}
mi, err := getMi(db, loan.Id)
if err != nil {
return loans, err
}
loan.Mi = mi
loans = append(loans, loan)
}
return loans, nil
}

func getBorrower(db *sql.DB, id int) (Borrower, error) {
var borrower Borrower

@@ -867,7 +863,7 @@ func queryBorrower(db *sql.DB, id int) ( Borrower, error ) {
}

// Must have an estimate ID 'e', but not necessarily a loan id 'id'
func queryLoan(db *sql.DB, e int, id int) ( []Loan, error ) {
func getLoans(db *sql.DB, e int, id int) ( []Loan, error ) {
var loans []Loan
var query string
var rows *sql.Rows
@@ -913,6 +909,18 @@ func queryLoan(db *sql.DB, e int, id int) ( []Loan, error ) {
err != nil {
return loans, err
}
mi, err := getMi(db, loan.Id)
if err != nil {
return loans, err
}
loan.Mi = mi
fees, err := getFees(db, loan.Id)
if err != nil {
return loans, err
}
loan.Fees = fees
loans = append(loans, loan)
}
@@ -922,7 +930,7 @@ func queryLoan(db *sql.DB, e int, id int) ( []Loan, error ) {
return loans, nil
}

func queryEstimate(db *sql.DB, id int, user int) ( []Estimate, error ) {
func getEstimates(db *sql.DB, id int, user int) ( []Estimate, error ) {
var estimates []Estimate
var query string
var rows *sql.Rows
@@ -974,7 +982,7 @@ func queryEstimate(db *sql.DB, id int, user int) ( []Estimate, error ) {
if len(estimates) == 0 { return estimates, errors.New("Estimate not found.") }
for i := range estimates {
estimates[i].Loans, err = queryLoan(db, estimates[i].Id, 0)
estimates[i].Loans, err = getLoans(db, estimates[i].Id, 0)
if err != nil { return estimates, err }
}
@@ -1010,6 +1018,13 @@ func insertBorrower(db *sql.DB, borrower Borrower) (int, error) {
return id, nil
}

func insertFee(db *sql.DB, fee Fee) (int, error) {
query := `INSERT INTO fee
id, loan_id, amount, perc, type, notes, name, category
FROM fee
WHERE loan_id = ?`
}

func insertLoan(db *sql.DB, loan Loan) (Loan, error){
var query string
var row *sql.Row
@@ -1048,7 +1063,7 @@ func insertLoan(db *sql.DB, loan Loan) (Loan, error){
err = row.Scan(&id)
if err != nil { return Loan{}, err }

loans, err := queryLoan(db, id, 0)
loans, err := getLoans(db, id, 0)
if err != nil { return Loan{}, err }

return loans[0], nil
@@ -1098,7 +1113,7 @@ func insertEstimate(db *sql.DB, estimate Estimate) (Estimate, error){
if err != nil { return estimate, err }
}
estimates, err := queryEstimate(db, estimate.Id, 0)
estimates, err := getEstimates(db, estimate.Id, 0)
if err != nil { return Estimate{}, err }

return estimates[0], nil
@@ -1122,7 +1137,7 @@ func fetchEstimate(w http.ResponseWriter, db *sql.DB, r *http.Request) {
var estimates []Estimate
claims, err := getClaims(r)

estimates, err = queryEstimate(db, 0, claims.Id)
estimates, err = getEstimates(db, 0, claims.Id)
if err != nil { http.Error(w, err.Error(), 500); return }
json.NewEncoder(w).Encode(estimates)
@@ -1300,6 +1315,10 @@ func api(w http.ResponseWriter, r *http.Request) {
r.Method == http.MethodPost &&
guard(r, 1):
validateEstimate(w, db, r)
case match(p, "/api/estimate/summarize", &args) &&
r.Method == http.MethodPost &&
guard(r, 1):
summarize(w, db, r)
default:
http.Error(w, "Invalid route or token", 404)
}


Loading…
Откажи
Сачувај