diff --git a/migrations/0_29092022_setup_tables.sql b/migrations/0_29092022_setup_tables.sql index db5c082..945a4a4 100644 --- a/migrations/0_29092022_setup_tables.sql +++ b/migrations/0_29092022_setup_tables.sql @@ -70,11 +70,11 @@ CREATE TABLE license ( * Types with branch_id and user_id values of 0 will be general cases. */ CREATE TABLE loan_type ( id INT AUTO_INCREMENT, - branch_id INT NOT NULL, - user_id INT NOT NULL, + branch_id INT, + user_id INT, name VARCHAR(30) UNIQUE NOT NULL, - /* FOREIGN KEY (branch_id) REFERENCES branch(id), */ - /* FOREIGN KEY (user_id) REFERENCES user(id), */ + FOREIGN KEY (branch_id) REFERENCES branch(id), + FOREIGN KEY (user_id) REFERENCES user(id), PRIMARY KEY (`id`) ); @@ -109,7 +109,7 @@ CREATE TABLE loan ( type_id INT NOT NULL, amount INT NOT NULL, term INT, /* In years */ - interest FLOAT(5, 2) DEFAULT 0, + interest FLOAT(5, 2) DEFAULT 0, /* Percentage to 2 decimal places */ ltv FLOAT(5, 2) DEFAULT 0, dti FLOAT(5, 2) DEFAULT 1, hoi INT DEFAULT 0, /* Home owner's insurance annual payments */ diff --git a/skouter.go b/skouter.go index 602e424..617137c 100644 --- a/skouter.go +++ b/skouter.go @@ -230,6 +230,21 @@ var roles = map[string]int{ "Admin": 3, } +var propertyTypes = []string{ + "Single Detached", + "Single Attached", + "Condo Lo-rise", + "Condo Hi-rise", +} + +var feeTypes = []string{ + "Government", + "Title", + "Required", + "Lender", + "Other", +} + // Used to validate claim in JWT token body. Checks if user id is greater than // zero and time format is valid func (c UserClaims) Valid() error { @@ -368,8 +383,8 @@ func getLoanTypes( db *sql.DB, id int, user int, branch int ) ( var loans []LoanType var query = `SELECT id, - user_id, - branch_id, + coalesce(user_id, 0), + coalesce(branch_id, 0), name FROM loan_type WHERE loan_type.id = CASE @e := ? WHEN 0 THEN id ELSE @e END OR @@ -908,7 +923,7 @@ func insertLicense(db *sql.DB, license License) (int, error) { ( user_id, type, - num, + num ) VALUES (?, ?, ?) RETURNING id @@ -1786,7 +1801,7 @@ func insertMi(db *sql.DB, mi MI) (int, error) { initial_rate, initial_amount ) - VALUES (?, ?, ?, ?, ?, ?, ?) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING id` row := db.QueryRow(query, @@ -1832,11 +1847,29 @@ func insertFee(db *sql.DB, fee Fee) (int, error) { return id, nil } +func insertLoanType(db *sql.DB, lt LoanType) (int, error) { + var id int + + query := `INSERT INTO loan_type (branch_id, user_id, name) + VALUES (NULLIF(?, 0), NULLIF(?, 0), ?) + RETURNING id` + + row := db.QueryRow(query, + lt.Branch, + lt.User, + lt.Name, + ) + + err := row.Scan(&id) + if err != nil { return 0, err } + + return id, nil +} + func insertLoan(db *sql.DB, loan Loan) (Loan, error){ var query string var row *sql.Row var err error - var id int // Inserted loan's id query = `INSERT INTO loan ( @@ -1867,19 +1900,17 @@ func insertLoan(db *sql.DB, loan Loan) (Loan, error){ loan.Name, ) - err = row.Scan(&id) + err = row.Scan(&loan.Id) if err != nil { return loan, err } _, err = insertMi(db, loan.Mi) if err != nil { return loan, err } for i := range loan.Fees { + loan.Fees[i].LoanId = loan.Id _, err := insertFee(db, loan.Fees[i]) if err != nil { return loan, err } } - loans, err := getLoans(db, id, 0) - if err != nil { return Loan{}, err } - - return loans[0], nil + return loan, nil } @@ -1925,11 +1956,8 @@ func insertEstimate(db *sql.DB, estimate Estimate) (Estimate, error){ _, err = insertLoan(db, l) if err != nil { return estimate, err } } - - estimates, err := getEstimates(db, estimate.Id, 0) - if err != nil { return Estimate{}, err } - return estimates[0], nil + return estimate, nil } func createEstimate(w http.ResponseWriter, db *sql.DB, r *http.Request) { @@ -2377,6 +2405,44 @@ func dbReset(db *sql.DB) { } } +func generateFees(loan Loan) []Fee { + var fees []Fee + var fee Fee + p := gofakeit.Float32Range(0.5, 10) + size := gofakeit.Number(1, 10) + + for f := 0; f < size; f++ { + fee = Fee{ + Amount: int(float32(loan.Amount)*p/100), + Perc: p, + Name: gofakeit.BuzzWord(), + Type: feeTypes[gofakeit.Number(0, len(feeTypes) - 1)], + } + fees = append(fees, fee) + } + + return fees +} + +func generateCredits(loan Loan) []Fee { + var fees []Fee + var fee Fee + p := gofakeit.Float32Range(-10, -0.5) + size := gofakeit.Number(1, 10) + + for f := 0; f < size; f++ { + fee = Fee{ + Amount: int(float32(loan.Amount)*p/100), + Perc: p, + Name: gofakeit.BuzzWord(), + Type: feeTypes[gofakeit.Number(0, len(feeTypes) - 1)], + } + fees = append(fees, fee) + } + + return fees +} + func seedAddresses(db *sql.DB) []Address { addresses := make([]Address, 10) @@ -2468,11 +2534,88 @@ func seedLicenses(db *sql.DB, users []User) []License { return licenses } +func seedLoanTypes(db *sql.DB) []LoanType { + var loantypes []LoanType + var loantype LoanType + var err error + + loantype = LoanType{Branch: 0, User: 0, Name: "Conventional"} + loantype.Id, err = insertLoanType(db, loantype) + if err != nil { panic(err) } + loantypes = append(loantypes, loantype) + + loantype = LoanType{Branch: 0, User: 0, Name: "FHA"} + loantype.Id, err = insertLoanType(db, loantype) + if err != nil { panic(err) } + loantypes = append(loantypes, loantype) + + loantype = LoanType{Branch: 0, User: 0, Name: "USDA"} + loantype.Id, err = insertLoanType(db, loantype) + if err != nil { panic(err) } + loantypes = append(loantypes, loantype) + + loantype = LoanType{Branch: 0, User: 0, Name: "VA"} + loantype.Id, err = insertLoanType(db, loantype) + if err != nil { panic(err) } + loantypes = append(loantypes, loantype) + + return loantypes +} + +func seedEstimates(db *sql.DB, users []User, ltypes []LoanType) []Estimate { + var estimates []Estimate + var estimate Estimate + var l Loan + var err error + + for i := 0; i < 20; i++ { + estimate.User = users[gofakeit.Number(0, len(users) - 1)].Id + estimate.Borrower = Borrower{ + Credit: gofakeit.Number(600, 800), + Income: gofakeit.Number(1000000, 15000000), + Num: gofakeit.Number(1, 20), + } + estimate.Transaction = []string{"Purchase", "Refinance"}[gofakeit.Number(0, 1)] + estimate.Price = gofakeit.Number(50000, 200000000) + estimate.Property = + propertyTypes[gofakeit.Number(0, len(propertyTypes) - 1)] + estimate.Occupancy = + []string{"Primary", "Secondary", "Investment"}[gofakeit.Number(0, 2)] + estimate.Zip = gofakeit.Zip() + + lsize := gofakeit.Number(1, 6) + for j := 0; j < lsize; j++ { + l.Type = ltypes[gofakeit.Number(0, len(ltypes) - 1)] + l.Amount = gofakeit.Number( + int(float32(estimate.Price)*0.5), + int(float32(estimate.Price)*0.93)) + l.Term = gofakeit.Number(4, 30) + l.Hoi = gofakeit.Number(50000, 700000) + l.Hazard = gofakeit.Number(5000, 200000) + l.Tax = gofakeit.Number(5000, 200000) + l.Interest = gofakeit.Float32Range(0.5, 8) + l.Fees = generateFees(l) + l.Credits = generateCredits(l) + l.Name = gofakeit.AdjectiveDescriptive() + estimate.Loans = append(estimate.Loans, l) + } + estimate, err = insertEstimate(db, estimate) + if err != nil {log.Println(err); return estimates} + estimates = append(estimates, estimate) + } + + return estimates +} + func dbSeed(db *sql.DB) { addresses := seedAddresses(db) branches := seedBranches(db, addresses) users := seedUsers(db, addresses, branches) _ = seedLicenses(db, users) + loantypes := seedLoanTypes(db) + log.Println(loantypes) + estimates := seedEstimates(db, users, loantypes) + log.Println(estimates) } func dev(args []string) {