124 lines
4.7 KiB
Go
124 lines
4.7 KiB
Go
package handlers
|
|
|
|
import (
|
|
"database/sql"
|
|
"html/template"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type App struct {
|
|
DB *sql.DB
|
|
T *template.Template
|
|
}
|
|
type Row map[string]any
|
|
|
|
func New(db *sql.DB) *App {
|
|
return &App{DB: db, T: template.Must(template.ParseGlob("web/templates/*.html"))}
|
|
}
|
|
func (a *App) Home(w http.ResponseWriter, r *http.Request) {
|
|
reqs, _ := a.DB.Query(`select tr.id,tr.kind,i.name,tr.quantity,tr.price_limit,tr.status,tr.created_at from trade_requests tr join items i on i.id=tr.item_id order by tr.id desc limit 30`)
|
|
defer reqs.Close()
|
|
var rs []Row
|
|
for reqs.Next() {
|
|
var id, qty int
|
|
var kind, item, status string
|
|
var created []byte
|
|
var price float64
|
|
reqs.Scan(&id, &kind, &item, &qty, &price, &status, &created)
|
|
rs = append(rs, Row{"ID": id, "Kind": kind, "Item": item, "Qty": qty, "Price": price, "Status": status, "Created": string(created)})
|
|
}
|
|
qs, _ := a.DB.Query(`select q.id,q.type,q.title,coalesce(d.name,''),q.status,coalesce(q.contractor_note,'') from quests q left join departments d on d.id=q.department_id order by q.id desc limit 50`)
|
|
defer qs.Close()
|
|
var quests []Row
|
|
for qs.Next() {
|
|
var id int
|
|
var typ, title, dept, status, note string
|
|
qs.Scan(&id, &typ, &title, &dept, &status, ¬e)
|
|
quests = append(quests, Row{"ID": id, "Type": typ, "Title": title, "Dept": dept, "Status": status, "Note": note})
|
|
}
|
|
a.T.ExecuteTemplate(w, "home.html", map[string]any{"Requests": rs, "Quests": quests})
|
|
}
|
|
func (a *App) LoginPage(w http.ResponseWriter, r *http.Request) {
|
|
a.T.ExecuteTemplate(w, "login.html", nil)
|
|
}
|
|
func (a *App) NewRequest(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method == "GET" {
|
|
rows, _ := a.DB.Query(`select id,name from items order by name`)
|
|
defer rows.Close()
|
|
var items []Row
|
|
for rows.Next() {
|
|
var id int
|
|
var name string
|
|
rows.Scan(&id, &name)
|
|
items = append(items, Row{"ID": id, "Name": name})
|
|
}
|
|
a.T.ExecuteTemplate(w, "request.html", map[string]any{"Items": items})
|
|
return
|
|
}
|
|
r.ParseForm()
|
|
item, _ := strconv.Atoi(r.FormValue("item_id"))
|
|
qty, _ := strconv.Atoi(r.FormValue("quantity"))
|
|
price, _ := strconv.ParseFloat(r.FormValue("price_limit"), 64)
|
|
kind := r.FormValue("kind")
|
|
if kind != "sell" {
|
|
kind = "buy"
|
|
}
|
|
res, err := a.DB.Exec(`insert into trade_requests(kind,item_id,quantity,price_limit,status) values(?,?,?,?, 'new')`, kind, item, qty, price)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), 500)
|
|
return
|
|
}
|
|
id, _ := res.LastInsertId()
|
|
a.generateQuests(r, id, kind, item, qty, price)
|
|
http.Redirect(w, r, "/", 303)
|
|
}
|
|
func (a *App) generateQuests(r *http.Request, reqID int64, kind string, itemID, qty int, price float64) {
|
|
var item string
|
|
a.DB.QueryRowContext(r.Context(), `select name from items where id=?`, itemID).Scan(&item)
|
|
var auto string
|
|
a.DB.QueryRowContext(r.Context(), `select setting_value from app_settings where setting_key='auto_generate_quests'`).Scan(&auto)
|
|
if auto == "false" || auto == "0" || auto == "no" {
|
|
a.DB.ExecContext(r.Context(), `insert into events(type,payload) values('request.created', JSON_OBJECT('request_id',?,'kind',?,'item_id',?,'quantity',?,'price',?,'auto_generate',false))`, reqID, kind, itemID, qty, price)
|
|
return
|
|
}
|
|
rows, err := a.DB.QueryContext(r.Context(), `select type,title_template,department_id,reward_percent from quest_templates where enabled=true order by sort_order,id`)
|
|
if err != nil {
|
|
return
|
|
}
|
|
defer rows.Close()
|
|
var prev sql.NullInt64
|
|
created := 0
|
|
for rows.Next() {
|
|
var typ, title string
|
|
var dept sql.NullInt64
|
|
var percent float64
|
|
rows.Scan(&typ, &title, &dept, &percent)
|
|
title = strings.ReplaceAll(title, "{{item}}", item)
|
|
title = strings.ReplaceAll(title, "{{quantity}}", strconv.Itoa(qty))
|
|
res, err := a.DB.ExecContext(r.Context(), `insert into quests(parent_request_id,depends_on_quest_id,type,title,department_id,reward,status) values(?,?,?,?,?,?,'open')`, reqID, prev, typ, title, dept, price*percent)
|
|
if err == nil {
|
|
qid, _ := res.LastInsertId()
|
|
prev = sql.NullInt64{Int64: qid, Valid: true}
|
|
created++
|
|
}
|
|
}
|
|
a.DB.ExecContext(r.Context(), `insert into events(type,payload) values('request.created', JSON_OBJECT('request_id',?,'kind',?,'item_id',?,'quantity',?,'price',?,'quests_created',?))`, reqID, kind, itemID, qty, price, created)
|
|
}
|
|
func (a *App) UpdateQuest(w http.ResponseWriter, r *http.Request) {
|
|
r.ParseForm()
|
|
id, _ := strconv.Atoi(r.FormValue("id"))
|
|
status := r.FormValue("status")
|
|
note := r.FormValue("note")
|
|
if status == "" {
|
|
status = "open"
|
|
}
|
|
a.DB.Exec(`update quests set status=?, contractor_note=? where id=?`, status, note, id)
|
|
a.DB.Exec(`insert into quest_updates(quest_id,status,note) values(?,?,?)`, id, status, note)
|
|
if status == "done" {
|
|
a.DB.Exec(`update quests set status='open' where depends_on_quest_id=? and status='waiting'`, id)
|
|
}
|
|
http.Redirect(w, r, "/", 303)
|
|
}
|