package api import ( "encoding/json" "log" "net/http" "strconv" "time" "github.com/gorilla/mux" "gorm.io/gorm" "gorm.io/gorm/clause" ) type Transaction struct { gorm.Model MemberNum int `json:"-" gorm:"column:member"` Member Member `json:"member" gorm:"foreignKey:MemberNum;references:Num"` Date time.Time `json:"date"` Total int `json:"total"` Type string `json:"type"` Purchase []Purchase `json:"purchase"` Topup Topup `json:"topup"` } func (a *api) ListTransactions(w http.ResponseWriter, req *http.Request) { var transactions []Transaction err := a.db.Preload("Purchase.Product"). Preload(clause.Associations). Order("date desc"). Find(&transactions).Error if err != nil { log.Printf("Can't list transactions: %v", err) w.WriteHeader(http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) err = json.NewEncoder(w).Encode(transactions) if err != nil { log.Printf("Can't encode transactions: %v", err) w.WriteHeader(http.StatusInternalServerError) } } func (a *api) GetTransaction(num int, role string, w http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) var transaction Transaction err := a.db.Preload("Purchase.Product"). Preload(clause.Associations). First(&transaction, vars["id"]).Error if err != nil { if err.Error() == "record not found" { w.WriteHeader(http.StatusNotFound) return } log.Printf("Can't get transaction %s: %v", vars["code"], err) w.WriteHeader(http.StatusInternalServerError) return } if transaction.MemberNum != num && role != "admin" { w.WriteHeader(http.StatusUnauthorized) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) err = json.NewEncoder(w).Encode(transaction) if err != nil { log.Printf("Can't encode transaction: %v", err) w.WriteHeader(http.StatusInternalServerError) return } } func (a *api) GetMemberTransactions(w http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) num, _ := strconv.Atoi(vars["num"]) a.getTransactionsByMember(num, w, req) } func (a *api) getTransactionsByMember(num int, w http.ResponseWriter, req *http.Request) { var transactions []Transaction err := a.db.Where("member = ?", num). Preload("Purchase.Product"). Preload(clause.Associations). Find(&transactions).Error if err != nil { log.Printf("Can't list transactions: %v", err) w.WriteHeader(http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) err = json.NewEncoder(w).Encode(transactions) if err != nil { log.Printf("Can't encode transactions: %v", err) w.WriteHeader(http.StatusInternalServerError) } } 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 }