diff --git a/handler/member_handler.go b/handler/member_handler.go index 5f75e2d..a571b96 100644 --- a/handler/member_handler.go +++ b/handler/member_handler.go @@ -38,6 +38,7 @@ func MemberCreateHandler(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") w.Write(bytes) defer db.Close() + return } else { ErrorResponse(w, 500, "Invalid method or headers") return diff --git a/handler/training_handler.go b/handler/training_handler.go new file mode 100644 index 0000000..b4400f3 --- /dev/null +++ b/handler/training_handler.go @@ -0,0 +1,40 @@ +package handler + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + + "github.com/DVC-Software/apiserver/model" +) + +func TrainingSessionCreateHandler(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" || r.Header.Get("Content-Type") != "application/json" { + ErrorResponse(w, 500, "Invalid method or headers") + return + } + data, _ := ioutil.ReadAll(r.Body) + var info model.TrainingSessionInfo + err := json.Unmarshal(data, &info) + if err != nil { + ErrorResponse(w, 500, err.Error()) + return + } + fmt.Println(string(data)) + if !info.ValidateInfo() { + ErrorResponse(w, 500, "Invalid request content") + return + } + db := ConnectDB() + success, sessionCreated, errmsg := model.CreateTrainingSession(db, info) + if !success { + ErrorResponse(w, 500, errmsg) + return + } + bytes, _ := json.Marshal(sessionCreated) + w.Header().Add("Content-Type", "application/json") + w.Write(bytes) + defer db.Close() + return +} diff --git a/migrations/migrations.go b/migrations/migrations.go index a41aa07..a0a0081 100644 --- a/migrations/migrations.go +++ b/migrations/migrations.go @@ -44,8 +44,8 @@ func migrateTestDB(db *gorm.DB) { func migrateDB(db *gorm.DB) { // Migrate all tables db.Exec("Use " + dev_db_name) - db.DropTableIfExists(&model.Name{}, &model.Member{}, &model.Profile{}, &model.Position{}) - db.AutoMigrate(&model.Name{}, &model.Member{}, &model.Profile{}, &model.Position{}) + db.DropTableIfExists(&model.Name{}, &model.Member{}, &model.Profile{}, &model.Position{}, &model.TrainingSession{}) + db.AutoMigrate(&model.Name{}, &model.Member{}, &model.Profile{}, &model.Position{}, &model.TrainingSession{}) } func initDB(db *gorm.DB) { diff --git a/model/training.go b/model/training.go new file mode 100644 index 0000000..bf8f8cf --- /dev/null +++ b/model/training.go @@ -0,0 +1,116 @@ +package model + +import ( + "github.com/jinzhu/gorm" + "time" +) + +type TrainingSession struct { + gorm.Model + Trainers []Member `gorm:"many2many:session_trainers"` + Trainees []Member `gorm:"many2many:session_trainees"` + StartTime time.Time `gorm:"not null"` + EndTime time.Time `gorm:"not null"` + Duration int `gorm:"not null; default: 0"` + Topic string `gorm:"not null"` + Type int `gorm:"not null"` +} + +type TrainingSessionInfo struct { + Trainers []string + Trainees []string + StartTime time.Time + EndTime time.Time + Topic string + Type string +} + +func (info TrainingSessionInfo) getIntType() int { + if info.Type == "Group Session" { + return 0 + } else if info.Type == "Personal Session" { + return 1 + } else { + return -1 + } +} + +func (info TrainingSessionInfo) ValidateInfo() bool { + if info.Topic == "" || len(info.Trainers) == 0 || len(info.Trainees) == 0 { + return false + } + return true +} + +func (session TrainingSession) calcDuration() int { + day := session.StartTime.Day() - session.EndTime.Day() + hour := session.StartTime.Hour() - session.EndTime.Hour() + minute := session.StartTime.Minute() - session.EndTime.Minute() + return day*24*60 + hour*60 + minute +} + +func (session TrainingSession) toSessionInfo() TrainingSessionInfo { + var info TrainingSessionInfo + info.StartTime = session.StartTime + info.EndTime = session.EndTime + info.Topic = session.Topic + if session.Type == 0 { + info.Type = "Group Session" + } else { + info.Type = "Personal Session" + } + for _, trainer := range session.Trainers { + info.Trainers = append(info.Trainers, trainer.Profile.Name) + } + for _, trainee := range session.Trainees { + info.Trainees = append(info.Trainees, trainee.Profile.Name) + } + return info +} + +func CreateTrainingSession(db *gorm.DB, info TrainingSessionInfo) (bool, TrainingSessionInfo, string) { + var session TrainingSession + // look for trainer profiles + for _, trainer := range info.Trainers { + var trainerProfile Profile + var trainerMember Member + err := db.Model(&session).Where("name = ?", trainer).First(&trainerProfile).Error + if err != nil { + return false, TrainingSessionInfo{}, "Trainer with name " + trainer + " does not exist" + } + err = db.Model(&trainerMember).Where("id = ?", trainerProfile.MemberID).First(&trainerMember).Error + if err != nil { + return false, TrainingSessionInfo{}, "Can't match member " + trainer + " with profile" + } + trainerMember.Profile = trainerProfile + session.Trainers = append(session.Trainers, trainerMember) + } + // look for trainee profiles + for _, trainee := range info.Trainees { + var traineeProfile Profile + var traineeMember Member + err := db.Model(&session).Where("name = ?", trainee).First(&traineeProfile).Error + if err != nil { + return false, TrainingSessionInfo{}, "Trainee with name " + trainee + " does not exist" + } + err = db.Model(&traineeMember).Where("id = ?", traineeProfile.MemberID).First(&traineeMember).Error + if err != nil { + return false, TrainingSessionInfo{}, "Can't match member " + trainee + " with profile" + } + traineeMember.Profile = traineeProfile + session.Trainees = append(session.Trainees, traineeMember) + } + session.StartTime = info.StartTime + session.EndTime = info.EndTime + session.Duration = session.calcDuration() + session.Topic = info.Topic + session.Type = info.getIntType() + if session.Type == -1 { + return false, TrainingSessionInfo{}, "Invalid session type " + info.Type + } + err := db.Create(&session).Error + if err != nil { + return false, TrainingSessionInfo{}, err.Error() + } + return true, session.toSessionInfo(), "" +} diff --git a/server.go b/server.go index be7416d..1f63079 100644 --- a/server.go +++ b/server.go @@ -49,6 +49,7 @@ func main() { r.HandleFunc("/name/show", handler.NameReadHandler).Methods("GET") r.HandleFunc("/member/create", handler.MemberCreateHandler).Methods("POST") r.HandleFunc("/member/info/{id}", handler.MemberInfoHandler).Methods("GET") + r.HandleFunc("/training/create", handler.TrainingSessionCreateHandler).Methods("POST") http.Handle(url_prefix, r) port := getPortFromEnv() srv := &http.Server{