2022-08-31 20:49:14 +00:00
package controllers
import (
"fmt"
2022-09-19 15:00:19 +00:00
"log"
2022-08-31 20:49:14 +00:00
"net/http"
"net/mail"
2022-09-20 10:21:01 +00:00
"officeHours/config"
"officeHours/models"
2022-09-24 13:01:33 +00:00
"officeHours/templating"
2022-08-31 20:49:14 +00:00
"strconv"
"strings"
)
type maskData struct {
Courses [ ] models . Course
Rooms [ ] models . Room
MinuteGranularity int
2023-10-26 09:29:42 +00:00
MaxDuration int
2022-11-15 10:42:23 +00:00
EarliestStartTime struct {
Hour int
Minute int
}
LatestStartTime struct {
Hour int
Minute int
}
2024-01-03 16:04:38 +00:00
SelectedCourse int
SelectedRoom int
Date models . Date
Duration int
Roomname string
Name string
Email string
SubscribeToMailinglist bool
Info string
Errors [ ] string
Config config . Config
2022-08-31 20:49:14 +00:00
}
2022-11-04 20:15:38 +00:00
// Offer a form to add office hours and validate its input on receiving.
2022-08-31 20:49:14 +00:00
func ( b * BaseHandler ) AddOfficeHourHandler ( w http . ResponseWriter , req * http . Request ) {
2023-01-04 11:35:24 +00:00
SendSecurityHeaders ( w , req )
2022-08-31 20:49:14 +00:00
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 {
2022-10-20 06:25:12 +00:00
errors = append ( errors , "Die Vorlesungswoche muss eine ganze Zahl sein." )
2022-08-31 20:49:14 +00:00
}
if ! ( week >= 0 && week <= 2 ) {
2022-10-20 06:25:12 +00:00
errors = append ( errors , "Sprechstunden müssen jede, jede gerade oder jede ungerade Vorlesungswoche stattfinden." )
2022-08-31 20:49:14 +00:00
}
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." )
}
2022-11-15 10:42:23 +00:00
if ! ( hour > b . config . Date . EarliestStartTime . Hour || ( hour == b . config . Date . EarliestStartTime . Hour && minute >= b . config . Date . EarliestStartTime . Minute ) ) {
errors = append ( errors , fmt . Sprintf ( "Sprechstunden müssen nach %02d:%02d Uhr starten." , b . config . Date . EarliestStartTime . Hour , b . config . Date . EarliestStartTime . Minute ) )
}
if ! ( hour < b . config . Date . LatestStartTime . Hour || ( hour == b . config . Date . LatestStartTime . Hour && minute <= b . config . Date . LatestStartTime . Minute ) ) {
errors = append ( errors , fmt . Sprintf ( "Sprechstunden müssen vor %02d:%02d Uhr starten." , b . config . Date . LatestStartTime . Hour , b . config . Date . LatestStartTime . Minute ) )
2022-08-31 20:49:14 +00:00
}
minute , err = strconv . Atoi ( time [ 1 ] )
if err != nil {
errors = append ( errors , "Die Minute muss eine ganze Zahl sein." )
}
2022-09-19 12:46:16 +00:00
if ! ( minute >= 0 && minute <= 60 - b . config . Date . MinuteGranularity && minute % b . config . Date . MinuteGranularity == 0 ) {
errors = append ( errors , fmt . Sprintf ( "Sprechstunden dürfen nur alle %d Minuten starten." , b . config . Date . MinuteGranularity ) )
2022-08-31 20:49:14 +00:00
}
}
2022-09-19 16:51:51 +00:00
date := models . Date { Week : week , Day : day , Hour : hour , Minute : minute }
2022-08-31 20:49:14 +00:00
duration , err := strconv . Atoi ( req . FormValue ( "dauer" ) )
if err != nil {
errors = append ( errors , "Die Dauer muss eine ganze Zahl sein." )
}
2023-10-26 09:29:42 +00:00
if ! ( duration >= b . config . Date . MinuteGranularity && duration <= b . config . Date . MaxDuration && duration % b . config . Date . MinuteGranularity == 0 ) {
errors = append ( errors , fmt . Sprintf ( "Sprechstunden müssen zwischen %d und %d Minuten lang sein." , b . config . Date . MinuteGranularity , b . config . Date . MaxDuration ) )
2022-08-31 20:49:14 +00:00
}
roomname := req . FormValue ( "raumname" )
2022-09-27 14:40:47 +00:00
if roomname != "" && room . Name != "Sonstige" {
errors = append ( errors , "Sonderraumnamen können nur für den Raum \"Sonstige\" angegeben werden." )
}
2022-08-31 20:49:14 +00:00
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 {
2022-09-19 16:51:51 +00:00
email = & mail . Address { Name : "" , Address : req . FormValue ( "email" ) }
2022-08-31 20:49:14 +00:00
errors = append ( errors , "Mailaddresse konnte nicht geparst werden." )
2022-11-15 10:42:58 +00:00
} else if ! ( b . config . Tutor . MailSuffix == "" || strings . HasSuffix ( email . Address , "@" + b . config . Tutor . MailSuffix ) || strings . HasSuffix ( email . Address , "." + b . config . Tutor . MailSuffix ) ) {
2022-09-19 15:00:19 +00:00
errors = append ( errors , fmt . Sprintf ( "Mailaddresse muss auf „%s“ enden." , b . config . Tutor . MailSuffix ) )
2022-08-31 20:49:14 +00:00
}
2024-01-03 16:04:38 +00:00
subscribeToMailinglist := req . FormValue ( "subscribeToMailinglist" ) == "subscribe"
2022-08-31 20:49:14 +00:00
info := req . FormValue ( "info" )
2022-09-07 16:26:05 +00:00
allowed , err := b . officeHourRepo . AllowedAt ( date , duration , room , true )
if err != nil {
errors = append ( errors , fmt . Sprintf ( "Fehler beim Abfragen der Raumkapazität: %s" , err . Error ( ) ) )
} else if ! allowed {
errors = append ( errors , "In dem Raum muss noch Platz für weitere Sprechstunden sein." )
}
2022-11-04 20:15:38 +00:00
// If there were errors in the data for the new office hour,
// answer with the form prefilled with the sent data.
2022-08-31 20:49:14 +00:00
if len ( errors ) != 0 {
var data maskData = maskData {
courses ,
rooms ,
2022-09-19 12:46:16 +00:00
b . config . Date . MinuteGranularity ,
2023-10-26 09:29:42 +00:00
b . config . Date . MaxDuration ,
2022-11-15 10:42:23 +00:00
b . config . Date . EarliestStartTime ,
b . config . Date . LatestStartTime ,
2022-08-31 20:49:14 +00:00
courseid ,
roomid ,
2022-09-07 19:48:40 +00:00
date ,
2022-08-31 20:49:14 +00:00
duration ,
roomname ,
name ,
email . Address ,
2024-01-03 16:04:38 +00:00
subscribeToMailinglist ,
2022-08-31 20:49:14 +00:00
info ,
errors ,
2022-09-19 15:00:19 +00:00
b . config ,
2022-08-31 20:49:14 +00:00
}
b . writeAddOfficeHourMask ( w , req , data )
} else {
2022-11-04 20:15:38 +00:00
// if the data for a new office hour was sent correctly, save it.
2022-09-19 16:51:51 +00:00
officeHour := models . OfficeHour { Id : 0 ,
2024-01-03 16:04:38 +00:00
Tutor : models . Tutor { Id : 0 , Name : name , Email : email . Address , SubscribeToMailinglist : subscribeToMailinglist } ,
2022-09-19 16:51:51 +00:00
Date : date ,
Room : room ,
2022-09-27 14:40:47 +00:00
RoomName : roomname ,
2022-09-19 16:51:51 +00:00
Course : course ,
Info : info ,
Active : false ,
Duration : duration ,
2022-08-31 20:49:14 +00:00
}
2022-09-05 15:55:08 +00:00
id , err := b . officeHourRepo . Add ( officeHour )
2022-08-31 20:49:14 +00:00
if err != nil {
w . WriteHeader ( http . StatusInternalServerError )
2022-09-24 13:01:33 +00:00
templating . ServeTemplate ( w , "addFailure" , err )
2022-09-05 15:55:08 +00:00
return
2022-08-31 20:49:14 +00:00
}
2022-09-21 20:24:08 +00:00
officeHour , err = b . officeHourRepo . FindById ( id )
if err != nil {
log . Printf ( "Error finding new office hour by id %d: %s" , id , err . Error ( ) )
}
_ , err = b . requestRepo . Add ( officeHour , models . RequestActivate )
if err != nil {
log . Printf ( "Error adding request: %s" , err . Error ( ) )
}
2022-09-24 13:01:33 +00:00
templating . ServeTemplate ( w , "addSuccess" , nil )
2022-08-31 20:49:14 +00:00
}
}
func ( b * BaseHandler ) writeAddOfficeHourMask ( w http . ResponseWriter , req * http . Request , data maskData ) {
2022-11-04 20:15:38 +00:00
if req . Method == http . MethodGet { // if the current request is GET, we assume no office hour addition was tried so far and reset the errors.
2022-09-05 15:55:08 +00:00
data . Errors = [ ] string { }
}
2022-09-19 15:00:19 +00:00
if len ( data . Errors ) != 0 {
w . WriteHeader ( http . StatusBadRequest )
}
2022-09-24 13:01:33 +00:00
templating . ServeTemplate ( w , "addMask" , data )
2022-08-31 20:49:14 +00:00
}