diff --git a/api/api.go b/api/api.go index ffc3d2410c8aea3d4d6823f6fca296b1dc1b363b..cb9d9e556a47c8943d7ab9d71df34a19654b248c 100644 --- a/api/api.go +++ b/api/api.go @@ -2,6 +2,7 @@ package api import ( "encoding/json" + "fmt" "git.sch.bme.hu/disappointment-industries/becskasszasch/db" "git.sch.bme.hu/disappointment-industries/becskasszasch/helpers" "git.sch.bme.hu/disappointment-industries/becskasszasch/homepage" @@ -144,26 +145,45 @@ func GetUsers(w http.ResponseWriter, r *http.Request) { func BuyInPult(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodPost: - var boughtInPult BoughtInPult + dec := json.NewDecoder(r.Body) + var pult PultAPIData + err := dec.Decode(&pult) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } - err := r.ParseForm() + user, err := db.GetUser(pult.UserID) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } - for _, productInPult := range boughtInPult.ProductsInPult { - spend := db.Spend{ - User: boughtInPult.User, - Product: productInPult.Product, - Amount: productInPult.Amount, - Date: boughtInPult.Date, - Notes: "Pultosch: " + boughtInPult.Pultosch.Name, + pultosch, err := homepage.GetUserInfoBySession(r) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + var spends []*db.Spend + for _, purchase := range pult.Purchases { + if purchase.Amount == 0 { + continue } - err := spend.Save() - if err != nil { - helpers.Logger.Println(err) + spend := db.Spend{ + User: user, + SchAcc: user.SchAcc, + ProdID: purchase.ProductID, + Amount: purchase.Amount, + Notes: fmt.Sprintf("Pultosch: %s (%s)", pultosch.User.Name, pultosch.User.SchAcc), } + spends = append(spends, &spend) + } + + err = db.SaveMultipleSpend(spends) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return } } } diff --git a/api/model.go b/api/model.go index 434ebc8b48ab390b8227e7fab05d31bbb0a9ae46..0621196203dab95043ef806b302f4ba0694b2959 100644 --- a/api/model.go +++ b/api/model.go @@ -1,18 +1,11 @@ package api -import ( - "git.sch.bme.hu/disappointment-industries/becskasszasch/db" - "time" -) - -type ProductInPult struct { - Product *db.Product `json:"product"` - Amount int64 `json:"amount"` +type PultAPIData struct { + UserID string `json:"userID"` + Purchases []PultAPIProduct `json:"purchases"` } -type BoughtInPult struct { - User *db.User `json:"user"` - ProductsInPult []*ProductInPult `json:"productsInPult"` - Date time.Time `json:"date"` - Pultosch *db.User `json:"pultosch"` +type PultAPIProduct struct { + ProductID string `json:"productID"` + Amount int64 `json:"amount"` } diff --git a/db/db.go b/db/db.go index 16df09d9113a3c4cac5163d7d241564409534f75..058d56ef02d852fb4d282b044a13ea942416207d 100644 --- a/db/db.go +++ b/db/db.go @@ -1,7 +1,10 @@ package db import ( + "context" "encoding/json" + "fmt" + //"git.sch.bme.hu/disappointment-industries/becskasszasch/helpers" "github.com/go-pg/pg/v10" _ "github.com/go-pg/pg/v10" @@ -327,6 +330,48 @@ func (u *User) Load() error { return e } +const credit = 5000 + +func SaveMultipleSpend(sp []*Spend) error { + e := db.RunInTransaction(context.Background(), func(tx *pg.Tx) error { + for _, s := range sp { + p := &Product{ + ID: s.ProdID, + } + e := tx.Model(p).WherePK().First() + if e != nil { + return e + } + + u := &User{ + SchAcc: s.SchAcc, + } + e = tx.Model(u).WherePK().First() + + price := p.Price * s.Amount + if price > u.Money+credit { + return fmt.Errorf("Not enough funds") + } + + u.Money -= price + _, e = tx.Model(u).WherePK().Update() + if e != nil { + return e + } + + spendsNow.With(prometheus.Labels{"product": p.Name}).Inc() + + _, e = tx.Model(s).Insert() + if e != nil { + return e + } + } + return nil + }) + + return e +} + func (sp *Spend) Save() error { p := &Product{ ID: sp.ProdID, diff --git a/pultosch/pultosch.go b/pultosch/pultosch.go index 4f21694ce3018ec00fe02c6fc69499c48cd9b81d..e8adc7ca3d39b93ae9cecbf69bb3785f6de8611d 100644 --- a/pultosch/pultosch.go +++ b/pultosch/pultosch.go @@ -41,13 +41,15 @@ type pultData struct { Users []*db.User } -func toJson(obj any) string { +func toJson(obj any) template.JS { by, e := json.Marshal(obj) if e != nil { panic(e) } - return string(by) + str := string(by) + + return template.JS(str) } func init() {