diff --git a/api/purchase.go b/api/purchase.go index 2d0e9c2ae6cdc78392154cb8dc290abcd1a4ce43..0eec3edda652410495598a7cd79a6d09d75a688a 100644 --- a/api/purchase.go +++ b/api/purchase.go @@ -2,6 +2,7 @@ package api import ( "encoding/json" + "fmt" "log" "net/http" "time" @@ -45,12 +46,6 @@ func (a *api) AddPurchase(num int, w http.ResponseWriter, req *http.Request) { return } - httpStatus := a.updateMemberBalance(num, -total) - if httpStatus != http.StatusOK { - w.WriteHeader(httpStatus) - return - } - transaction := Transaction{ MemberNum: num, Date: time.Now(), @@ -58,20 +53,28 @@ func (a *api) AddPurchase(num int, w http.ResponseWriter, req *http.Request) { Type: "purchase", Total: -total, } - err = a.db.Create(&transaction).Error - if err != nil { - log.Printf("Can't create purchase: %v\n%v", err, purchase) - w.WriteHeader(http.StatusInternalServerError) - return - } - - for _, p := range purchase { - err := a.db.Model(&Product{}). - Where("code = ?", p.ProductCode). - Update("stock", gorm.Expr("stock - ?", p.Ammount)).Error + var httpStatus int + err = a.db.Transaction(func(tx *gorm.DB) error { + httpStatus, err = createTransaction(tx, &transaction) if err != nil { - log.Printf("Can't update product stock %d-%d: %v", p.ProductCode, p.Ammount, err) + return err + } + + for _, p := range purchase { + err := tx.Model(&Product{}). + Where("code = ?", p.ProductCode). + Update("stock", gorm.Expr("stock - ?", p.Ammount)).Error + if err != nil { + httpStatus = http.StatusInternalServerError + return fmt.Errorf("Can't update product stock %d-%d: %v", p.ProductCode, p.Ammount, err) + } } + return nil + }) + if err != nil { + log.Println(err) + w.WriteHeader(httpStatus) + return } w.Header().Set("Content-Type", "application/json") diff --git a/api/topup.go b/api/topup.go index 74ed8559497839742e1df7c913849d9daa65ac07..4ee42a62e65a20bb533b570e897f32c32fcbe364 100644 --- a/api/topup.go +++ b/api/topup.go @@ -30,12 +30,6 @@ func (a *api) AddTopup(adminNum int, w http.ResponseWriter, req *http.Request) { return } - httpStatus := a.updateMemberBalance(topup.Member, topup.Ammount) - if httpStatus != http.StatusOK { - w.WriteHeader(httpStatus) - return - } - transaction := Transaction{ MemberNum: topup.Member, Date: time.Now(), @@ -46,10 +40,10 @@ func (a *api) AddTopup(adminNum int, w http.ResponseWriter, req *http.Request) { Type: "topup", Total: topup.Ammount, } - err = a.db.Create(&transaction).Error + httpStatus, err := createTransaction(a.db, &transaction) if err != nil { - log.Printf("Can't create topup: %v\n%v", err, transaction) - w.WriteHeader(http.StatusInternalServerError) + log.Println(err) + w.WriteHeader(httpStatus) return } diff --git a/api/transaction.go b/api/transaction.go index 0420e43430b533d41b2c63639aa8c7456ab60e21..0ec5c635e7707fd758ace7342e53f83b8a2eabd1 100644 --- a/api/transaction.go +++ b/api/transaction.go @@ -2,6 +2,7 @@ package api import ( "encoding/json" + "fmt" "log" "net/http" "strconv" @@ -55,7 +56,7 @@ func (a *api) GetTransaction(num int, role string, w http.ResponseWriter, req *h w.WriteHeader(http.StatusNotFound) return } - log.Printf("Can't get transaction %s: %v", vars["code"], err) + log.Printf("Can't get transaction %s: %v", vars["id"], err) w.WriteHeader(http.StatusInternalServerError) return } @@ -102,23 +103,33 @@ func (a *api) getTransactionsByMember(num int, w http.ResponseWriter, req *http. } } -func (a *api) updateMemberBalance(num int, ammount int) int { - var member Member - err := a.db.Where("num = ?", num).Find(&member).Error - if err != nil { - log.Printf("Can't find member %d: %v", num, err) - return http.StatusNotAcceptable - } - if member.Balance < -ammount { - log.Printf("Member %d don't have enough money (%d-%d)", num, member.Balance, ammount) - return http.StatusBadRequest - } - err = a.db.Model(&Member{}). - Where("num = ?", num). - Update("balance", gorm.Expr("balance + ?", ammount)).Error - if err != nil { - log.Printf("Can't update update member balance %d-%d: %v", num, ammount, err) - return http.StatusNotAcceptable - } - return http.StatusOK +func createTransaction(db *gorm.DB, transaction *Transaction) (httpStatus int, err error) { + httpStatus = http.StatusOK + err = db.Transaction(func(tx *gorm.DB) error { + var member Member + err := tx.Where("num = ?", transaction.MemberNum).Find(&member).Error + if err != nil { + httpStatus = http.StatusNotAcceptable + return fmt.Errorf("Can't find member %d: %v", transaction.MemberNum, err) + } + if member.Balance < -transaction.Total { + httpStatus = http.StatusBadRequest + return fmt.Errorf("Member %d don't have enough money (%d-%d)", member.Num, member.Balance, transaction.Total) + } + err = tx.Model(&Member{}). + Where("num = ?", transaction.MemberNum). + Update("balance", gorm.Expr("balance + ?", transaction.Total)).Error + if err != nil { + httpStatus = http.StatusNotAcceptable + fmt.Errorf("Can't update update member balance %d-%d: %v", member.Num, transaction.Total, err) + } + + err = tx.Create(&transaction).Error + if err != nil { + httpStatus = http.StatusInternalServerError + return fmt.Errorf("Can't create transaction: %v\n%v", err, transaction) + } + return nil + }) + return }