Erstelle Maske, um Sprechstunden hinzuzufügen
This commit is contained in:
parent
c7a9522c2c
commit
369f4ebcec
15 changed files with 357 additions and 50 deletions
174
controllers/addOfficeHourHandlers.go
Normal file
174
controllers/addOfficeHourHandlers.go
Normal file
|
@ -0,0 +1,174 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/mail"
|
||||
"sprechstundentool/models"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type maskData struct {
|
||||
Courses []models.Course
|
||||
Rooms []models.Room
|
||||
MinuteGranularity int
|
||||
SelectedCourse int
|
||||
SelectedRoom int
|
||||
Week int
|
||||
Day int
|
||||
Hour int
|
||||
Minute int
|
||||
Duration int
|
||||
Roomname string
|
||||
Name string
|
||||
Email string
|
||||
Info string
|
||||
Errors []string
|
||||
}
|
||||
|
||||
func (b *BaseHandler) AddOfficeHourHandler(w http.ResponseWriter, req *http.Request) {
|
||||
var errors []string
|
||||
courses, err := b.courseRepo.GetAll()
|
||||
if err != nil {
|
||||
errors = append(errors, err.Error())
|
||||
}
|
||||
rooms, err := b.roomRepo.GetAll()
|
||||
if err != nil {
|
||||
errors = append(errors, err.Error())
|
||||
}
|
||||
//Parse course
|
||||
courseid, err := strconv.Atoi(req.FormValue("veranstaltung"))
|
||||
if err != nil {
|
||||
errors = append(errors, "Die Veranstaltung muss eine ganze Zahl sein.")
|
||||
}
|
||||
course, err := b.courseRepo.FindById(courseid)
|
||||
if err != nil {
|
||||
errors = append(errors, "Die Veranstaltung muss existieren.")
|
||||
}
|
||||
//Parse room
|
||||
roomid, err := strconv.Atoi(req.FormValue("raum"))
|
||||
if err != nil {
|
||||
errors = append(errors, "Der Raum muss eine ganze Zahl sein.")
|
||||
}
|
||||
room, err := b.roomRepo.FindById(roomid)
|
||||
if err != nil {
|
||||
errors = append(errors, "Der Raum muss existieren.")
|
||||
}
|
||||
//Parse date
|
||||
week, err := strconv.Atoi(req.FormValue("woche"))
|
||||
if err != nil {
|
||||
errors = append(errors, "Die Woche muss eine ganze Zahl sein.")
|
||||
}
|
||||
if !(week >= 0 && week <= 2) {
|
||||
errors = append(errors, "Sprechstunden müssen jede, jede gerade oder jede ungerade Woche stattfinden.")
|
||||
}
|
||||
day, err := strconv.Atoi(req.FormValue("tag"))
|
||||
if err != nil {
|
||||
errors = append(errors, "Der Tag muss eine ganze Zahl sein.")
|
||||
}
|
||||
if !(day >= 0 && day <= 4) {
|
||||
errors = append(errors, "Sprechstunden müssen von Montag bis Freitag stattfinden.")
|
||||
}
|
||||
time := strings.SplitN(req.FormValue("startzeit"), ":", 2)
|
||||
var hour, minute int
|
||||
if len(time) != 2 {
|
||||
errors = append(errors, "Die Zeit muss im Format HH:MM sein.")
|
||||
} else {
|
||||
hour, err = strconv.Atoi(time[0])
|
||||
if err != nil {
|
||||
errors = append(errors, "Die Stunde muss eine ganze Zahl sein.")
|
||||
}
|
||||
if !(hour >= 8 && hour <= 17) {
|
||||
errors = append(errors, fmt.Sprintf("Sprechstunden müssen zwischen 08:00 Uhr und 17:%d starten.", 60-models.MinuteGranularity))
|
||||
}
|
||||
minute, err = strconv.Atoi(time[1])
|
||||
if err != nil {
|
||||
errors = append(errors, "Die Minute muss eine ganze Zahl sein.")
|
||||
}
|
||||
if !(minute >= 0 && minute <= 60-models.MinuteGranularity && minute%models.MinuteGranularity == 0) {
|
||||
errors = append(errors, fmt.Sprintf("Sprechstunden dürfen nur alle %d Minuten starten.", models.MinuteGranularity))
|
||||
}
|
||||
}
|
||||
duration, err := strconv.Atoi(req.FormValue("dauer"))
|
||||
if err != nil {
|
||||
errors = append(errors, "Die Dauer muss eine ganze Zahl sein.")
|
||||
}
|
||||
if !(duration >= models.MinuteGranularity && duration <= 120 && duration%models.MinuteGranularity == 0) {
|
||||
errors = append(errors, fmt.Sprintf("Sprechstunden müssen zwischen %d und 120 Minuten lang sein.", models.MinuteGranularity))
|
||||
}
|
||||
|
||||
roomname := req.FormValue("raumname")
|
||||
name := req.FormValue("name")
|
||||
if name == "" {
|
||||
errors = append(errors, "Der Name darf nicht leer sein.")
|
||||
}
|
||||
email, err := mail.ParseAddress(req.FormValue("email"))
|
||||
if err != nil {
|
||||
email = &mail.Address{"", req.FormValue("email")}
|
||||
errors = append(errors, "Mailaddresse konnte nicht geparst werden.")
|
||||
} else if !strings.HasSuffix(email.Address, "tu-darmstadt.de") {
|
||||
errors = append(errors, "Mailaddresse muss auf „tu-darmstadt.de“ enden.")
|
||||
}
|
||||
info := req.FormValue("info")
|
||||
|
||||
if len(errors) != 0 {
|
||||
var data maskData = maskData{
|
||||
courses,
|
||||
rooms,
|
||||
models.MinuteGranularity,
|
||||
courseid,
|
||||
roomid,
|
||||
week,
|
||||
day,
|
||||
hour,
|
||||
minute,
|
||||
duration,
|
||||
roomname,
|
||||
name,
|
||||
email.Address,
|
||||
info,
|
||||
errors,
|
||||
}
|
||||
b.writeAddOfficeHourMask(w, req, data)
|
||||
} else {
|
||||
officeHour := models.OfficeHour{0,
|
||||
models.Tutor{0, name, email.Address},
|
||||
models.Date{week, day, hour, minute},
|
||||
room,
|
||||
course,
|
||||
info,
|
||||
false,
|
||||
duration,
|
||||
}
|
||||
err := b.officeHourRepo.Add(officeHour)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
failureTemplate, parseErr := template.ParseFiles("templates/addFailure.html")
|
||||
if parseErr != nil {
|
||||
w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", string(err.Error()))))
|
||||
return
|
||||
}
|
||||
failureTemplate.Execute(w, err)
|
||||
}
|
||||
http.Redirect(w, req, "/", http.StatusTemporaryRedirect)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *BaseHandler) writeAddOfficeHourMask(w http.ResponseWriter, req *http.Request, data maskData) {
|
||||
tmpl, err := template.ParseFiles("templates/addMask.html")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", string(err.Error()))))
|
||||
return
|
||||
}
|
||||
if len(data.Errors) != 0 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
}
|
||||
err = tmpl.Execute(w, data)
|
||||
if err != nil {
|
||||
w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", string(err.Error()))))
|
||||
return
|
||||
}
|
||||
}
|
16
controllers/baseHandler.go
Normal file
16
controllers/baseHandler.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package controllers
|
||||
|
||||
import "sprechstundentool/models"
|
||||
|
||||
// BaseHandler will hold everything that controller needs
|
||||
type BaseHandler struct {
|
||||
roomRepo models.RoomRepository
|
||||
officeHourRepo models.OfficeHourRepository
|
||||
courseRepo models.CourseRepository
|
||||
tutorRepo models.TutorRepository
|
||||
}
|
||||
|
||||
// NewBaseHandler returns a new BaseHandler
|
||||
func NewBaseHandler(roomRepo models.RoomRepository, officeHourRepo models.OfficeHourRepository, courseRepo models.CourseRepository, tutorRepo models.TutorRepository) *BaseHandler {
|
||||
return &BaseHandler{roomRepo, officeHourRepo, courseRepo, tutorRepo}
|
||||
}
|
|
@ -8,19 +8,6 @@ import (
|
|||
"strconv"
|
||||
)
|
||||
|
||||
// BaseHandler will hold everything that controller needs
|
||||
type BaseHandler struct {
|
||||
roomRepo models.RoomRepository
|
||||
officeHourRepo models.OfficeHourRepository
|
||||
courseRepo models.CourseRepository
|
||||
tutorRepo models.TutorRepository
|
||||
}
|
||||
|
||||
// NewBaseHandler returns a new BaseHandler
|
||||
func NewBaseHandler(roomRepo models.RoomRepository, officeHourRepo models.OfficeHourRepository, courseRepo models.CourseRepository, tutorRepo models.TutorRepository) *BaseHandler {
|
||||
return &BaseHandler{roomRepo, officeHourRepo, courseRepo, tutorRepo}
|
||||
}
|
||||
|
||||
func (b *BaseHandler) RootHandler(w http.ResponseWriter, req *http.Request) {
|
||||
b.writeTimetablePage(w, req, template.HTML(""))
|
||||
}
|
||||
|
@ -33,7 +20,7 @@ func (b *BaseHandler) GetByRoomHandler(w http.ResponseWriter, req *http.Request)
|
|||
b.RootHandler(w, req)
|
||||
return
|
||||
}
|
||||
officeHours, _ := b.officeHourRepo.FindByRoom(room)
|
||||
officeHours, _ := b.officeHourRepo.FindByRoom(room, true)
|
||||
b.writeTimetablePage(w, req, printTimetable(GetTimetable(officeHours)))
|
||||
}
|
||||
|
||||
|
@ -47,7 +34,7 @@ func (b *BaseHandler) GetByCourseHandler(w http.ResponseWriter, req *http.Reques
|
|||
b.RootHandler(w, req)
|
||||
return
|
||||
}
|
||||
officeHours, _ := b.officeHourRepo.FindByCourse(course)
|
||||
officeHours, _ := b.officeHourRepo.FindByCourse(course, true)
|
||||
b.writeTimetablePage(w, req, printTimetable(GetTimetable(officeHours)))
|
||||
}
|
||||
|
|
@ -13,20 +13,20 @@ func GetTimetable(officeHours []models.OfficeHour) (timetable map[models.Date]ma
|
|||
for _, officeHour := range officeHours {
|
||||
var slot int = 0
|
||||
for minute := 0; minute < officeHour.Duration; minute += models.MinuteGranularity { // find slot id
|
||||
_, exists := fullTimetable[models.Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}]
|
||||
_, exists := fullTimetable[models.Date{0, officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}]
|
||||
if exists {
|
||||
_, exists := fullTimetable[models.Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}][slot]
|
||||
_, exists := fullTimetable[models.Date{0, officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}][slot]
|
||||
if exists {
|
||||
slot += 1
|
||||
minute = 0
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
fullTimetable[models.Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}] = make(map[int]models.OfficeHour)
|
||||
fullTimetable[models.Date{0, officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}] = make(map[int]models.OfficeHour)
|
||||
}
|
||||
}
|
||||
for minute := 0; minute < officeHour.Duration; minute += models.MinuteGranularity { // write officeHour id to timetable
|
||||
fullTimetable[models.Date{officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}][slot] = officeHour
|
||||
fullTimetable[models.Date{0, officeHour.Day, officeHour.Hour + (officeHour.Minute+minute)/60, (officeHour.Minute + minute) % 60}][slot] = officeHour
|
||||
}
|
||||
}
|
||||
slots = []int{1, 1, 1, 1, 1}
|
||||
|
@ -61,16 +61,16 @@ func printTimetable(timetable map[models.Date]map[int]models.OfficeHour, slots [
|
|||
}
|
||||
for day := 0; day < 5; day += 1 {
|
||||
for slot := 0; slot < slots[day]; slot += 1 {
|
||||
current, currentExists := timetable[models.Date{day, hour, minute}][slot]
|
||||
current, currentExists := timetable[models.Date{0, day, hour, minute}][slot]
|
||||
|
||||
if currentExists { // This slot is taken by some office hour
|
||||
var continued bool = false // is this slot occupied by the same office hour the previous minute?
|
||||
var predecessorExists bool
|
||||
var predecessor models.OfficeHour
|
||||
if hour > 0 && minute < models.MinuteGranularity {
|
||||
predecessor, predecessorExists = timetable[models.Date{day, hour - 1, 60 - models.MinuteGranularity}][slot]
|
||||
predecessor, predecessorExists = timetable[models.Date{0, day, hour - 1, 60 - models.MinuteGranularity}][slot]
|
||||
} else {
|
||||
predecessor, predecessorExists = timetable[models.Date{day, hour, minute - models.MinuteGranularity}][slot]
|
||||
predecessor, predecessorExists = timetable[models.Date{0, day, hour, minute - models.MinuteGranularity}][slot]
|
||||
}
|
||||
if predecessorExists {
|
||||
continued = (predecessor == current)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue