From 5603c7890fe81c6c04a8043d4db63269d41fecd4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mikl=C3=B3s=20T=C3=B3th?= <tothmiklostibor@gmail.com>
Date: Thu, 31 Aug 2023 17:36:09 +0200
Subject: [PATCH] Add pultosch API

---
 api/api.go           | 44 +++++++++++++++++++++++++++++++------------
 api/model.go         | 19 ++++++-------------
 db/db.go             | 45 ++++++++++++++++++++++++++++++++++++++++++++
 pultosch/pultosch.go |  6 ++++--
 4 files changed, 87 insertions(+), 27 deletions(-)

diff --git a/api/api.go b/api/api.go
index ffc3d24..cb9d9e5 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 434ebc8..0621196 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 16df09d..058d56e 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 4f21694..e8adc7c 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() {
-- 
GitLab