From 369f4ebcec71bf340b3b4b63837e961621215828 Mon Sep 17 00:00:00 2001
From: Gonne
Date: Wed, 31 Aug 2022 22:49:14 +0200
Subject: [PATCH] =?UTF-8?q?Erstelle=20Maske,=20um=20Sprechstunden=20hinzuz?=
=?UTF-8?q?uf=C3=BCgen?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
controllers/addOfficeHourHandlers.go | 174 ++++++++++++++++++++
controllers/baseHandler.go | 16 ++
controllers/{handlers.go => getHandlers.go} | 17 +-
controllers/timetable.go | 14 +-
dummydatasqlite.sql | 2 +-
main.go | 2 +-
models/date.go | 1 +
models/officeHour.go | 7 +-
models/tutor.go | 1 +
repositories/officeHour.go | 80 +++++++--
repositories/tutor.go | 18 +-
templates/addFailure.html | 10 ++
templates/addMask.html | 49 ++++++
templates/index.html | 14 +-
templates/officeHourTable.html | 2 +-
15 files changed, 357 insertions(+), 50 deletions(-)
create mode 100644 controllers/addOfficeHourHandlers.go
create mode 100644 controllers/baseHandler.go
rename controllers/{handlers.go => getHandlers.go} (73%)
create mode 100644 templates/addFailure.html
create mode 100644 templates/addMask.html
diff --git a/controllers/addOfficeHourHandlers.go b/controllers/addOfficeHourHandlers.go
new file mode 100644
index 0000000..9cc9ac0
--- /dev/null
+++ b/controllers/addOfficeHourHandlers.go
@@ -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
+ }
+}
diff --git a/controllers/baseHandler.go b/controllers/baseHandler.go
new file mode 100644
index 0000000..2e14d95
--- /dev/null
+++ b/controllers/baseHandler.go
@@ -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}
+}
diff --git a/controllers/handlers.go b/controllers/getHandlers.go
similarity index 73%
rename from controllers/handlers.go
rename to controllers/getHandlers.go
index 5e613c8..160fdc7 100644
--- a/controllers/handlers.go
+++ b/controllers/getHandlers.go
@@ -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)))
}
diff --git a/controllers/timetable.go b/controllers/timetable.go
index 5a8cb9a..bb044e7 100644
--- a/controllers/timetable.go
+++ b/controllers/timetable.go
@@ -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)
diff --git a/dummydatasqlite.sql b/dummydatasqlite.sql
index 802af70..56d24fe 100644
--- a/dummydatasqlite.sql
+++ b/dummydatasqlite.sql
@@ -1,4 +1,4 @@
INSERT INTO `room` (name, max_occupy) VALUES ('S2 15 345',2),('S2 15 415',1),('S2 15 336',2),('S2 15 444',1),('S2 15 333',1),('S2 14 420',1),('Sonstige',1024);
-INSERT INTO `officeHour` VALUES (0,1,1,12,0,1,1,0,'',true,60),(1,1,1,12,15,2,1,0,'',true,60),(2,1,1,12,30,1,2,0,'',true,60);
+INSERT INTO `officeHour` (tutor, day, hour, minute, room, course, week, info, active, duration) VALUES (1,1,12,0,1,1,0,'',true,60),(1,1,12,15,2,1,0,'',true,60),(1,1,12,30,1,2,0,'',true,60);
INSERT INTO `tutor` (name, email) VALUES ('Dummyname','dummy@example.com');
INSERT INTO `course` (name) VALUES ('Integrationstheorie'),('Analysis II (engl.)'),('Analysis II'),('Mathe II für Informatik'),('Mathe II für Bauwesen'),('Diskrete Optimierung'),('Lineare Algebra II'),('Einführung in die Algebra'),('FGdI I&II'),('Algorithmic Discrete Mathematics'),('Einführung in die Stochastik'),('Mathe II für ET'),('Mathe II für Maschinenbau'),('Mathe IV für Maschinenbau'),('Num Mathe für MB (IV)'),('Höhere Mathematik II'),('Elementare PDE'),('LA für Physik und Lehramt'),('Analysis I'),('Mathe III ET'),('Mathe I für Informatik'),('Complex Analysis'),('Mathe & Statistik für Biologen'),('Mathe I für Maschinenbau'),('Mathe I für Bau'),('Nichtlineare Optimierung'),('Einführung in die Numerische Mathematik'),('Differentialgeometrie'),('Mathe I für ET'),('Mathe III (Bau)'),('W. Theorie'),('Gewöhnliche Differentialgleichungen'),('Geometrie für Lehramt'),('Mathe III MB'),('Statistik I für Humanwissenschaftler'),('Einführung in die Optimierung'),('Algebra'),('Lineare Algebra I'),('Höhere Mathematik 1'),('Darstellende Geometrie'),('Statistik 1 für WI'),('Diskrete Mathematik'),('Linear Algebra I (engl.)'),('Introduction to mathematical logic'),('Statistik I für WI'),('Weihnachtsknobelstraße'),('Numerische Lineare Algebra'),('Mathe IV (ET) / Mathe III (Inf) / Praktische Mathe (MEd)'),('Topologie'),('Linear Algebra II (engl.)'),('Einführung in die Finanzmathematik'),('Einführung in die mathematische Software'),('Mathematische Statistik'),('Algebraische Kurven'),('Analysis I (engl.)'),('Funktionalanalysis'),('Lebensversicherungsmathematik'),('Automaten, Formale Sprachen und Entscheidbarkeit (FGdI)'),('Mathematik für Chemiker'),('Numerik gewöhnlicher Differentialgleichungen'),('Darstellungstheorie'),('Aussagen- und Prädikatenlogik'),('Riemannsche Flächen'),('Mathematische Grundlagen der Quantenmechanik'),('Elementare Zahlentheorie'),('Einführung in die mathematische Modellierung'),('Stochastische Prozesse I'),('Mathematik im Kontext'),('Funktionalanalysis II'),('Mathematik IV (für ET) /Mathematik III (für Inf) /PraktischeMathematik (für M.Ed.Math)'),('Differentialgeometrie fuer VI'),('Probability Theory'),('Mathe für MINT'),('Mathematik als gemeinsame Sprache der Naturwissenschaften'),('Lineare Algebra I für Physiker'),('Manifolds'),('Kurvenschätzung'),('Spieltheorie'),('Einführung in die Programmierung'),('Algebraische Topologie'),('Schadenversicherungsmathematik'),('Partial Differential Equations I');
diff --git a/main.go b/main.go
index 30c6721..e47336f 100644
--- a/main.go
+++ b/main.go
@@ -20,7 +20,7 @@ func main() {
http.HandleFunc("/getByRoom", h.GetByRoomHandler)
http.HandleFunc("/getByCourse", h.GetByCourseHandler)
-
+ http.HandleFunc("/addOfficeHour", h.AddOfficeHourHandler)
http.HandleFunc("/", h.RootHandler)
http.ListenAndServe(":8080", nil)
diff --git a/models/date.go b/models/date.go
index 1b71272..f737735 100644
--- a/models/date.go
+++ b/models/date.go
@@ -2,6 +2,7 @@
package models
type Date struct {
+ Week int
Day int
Hour int
Minute int
diff --git a/models/officeHour.go b/models/officeHour.go
index aadf0ce..0c81f94 100644
--- a/models/officeHour.go
+++ b/models/officeHour.go
@@ -4,7 +4,6 @@ package models
type OfficeHour struct {
Id int
Tutor Tutor
- Week int
Date
Room Room
Course Course
@@ -15,9 +14,9 @@ type OfficeHour struct {
type OfficeHourRepository interface {
FindById(id int) (OfficeHour, error)
- FindByCourse(course Course) ([]OfficeHour, error)
- FindByRoom(room Room) ([]OfficeHour, error)
- GetAll() ([]OfficeHour, error)
+ FindByCourse(course Course, activeOnly bool) ([]OfficeHour, error)
+ FindByRoom(room Room, activatedOnly bool) ([]OfficeHour, error)
+ GetAll(activatedOnly bool) ([]OfficeHour, error)
Delete(officeHour OfficeHour) error
Add(officeHour OfficeHour) error
}
diff --git a/models/tutor.go b/models/tutor.go
index 2a317cd..81fa828 100644
--- a/models/tutor.go
+++ b/models/tutor.go
@@ -9,6 +9,7 @@ type Tutor struct {
type TutorRepository interface {
FindByEmail(Email string) ([]Tutor, error)
+ FindByNameAndEmail(name string, email string) (Tutor, error)
FindById(Id int) (Tutor, error)
GetAll() ([]Tutor, error)
Add(tutor Tutor) error
diff --git a/repositories/officeHour.go b/repositories/officeHour.go
index 5e142d1..05bd3b4 100644
--- a/repositories/officeHour.go
+++ b/repositories/officeHour.go
@@ -22,8 +22,14 @@ func NewOfficeHourRepo(db *sql.DB, roomRepo *RoomRepo, tutorRepo *TutorRepo, cou
}
}
-func (r *OfficeHourRepo) GetAll() ([]models.OfficeHour, error) {
- rows, err := r.db.Query("SELECT * FROM officeHour")
+func (r *OfficeHourRepo) GetAll(activeOnly bool) ([]models.OfficeHour, error) {
+ var rows *sql.Rows
+ var err error
+ if activeOnly {
+ rows, err = r.db.Query("SELECT * FROM officeHour WHERE active")
+ } else {
+ rows, err = r.db.Query("SELECT * FROM officeHour")
+ }
if err != nil {
return nil, err
}
@@ -31,8 +37,14 @@ func (r *OfficeHourRepo) GetAll() ([]models.OfficeHour, error) {
return r.getFromRows(rows)
}
-func (r *OfficeHourRepo) FindByCourse(course models.Course) ([]models.OfficeHour, error) {
- rows, err := r.db.Query("SELECT * FROM officeHour WHERE course=?", course.Id)
+func (r *OfficeHourRepo) FindByCourse(course models.Course, activeOnly bool) ([]models.OfficeHour, error) {
+ var rows *sql.Rows
+ var err error
+ if activeOnly {
+ rows, err = r.db.Query("SELECT * FROM officeHour WHERE course=? and active", course.Id)
+ } else {
+ rows, err = r.db.Query("SELECT * FROM officeHour WHERE course=?", course.Id)
+ }
if err != nil {
return nil, err
}
@@ -40,8 +52,14 @@ func (r *OfficeHourRepo) FindByCourse(course models.Course) ([]models.OfficeHour
return r.getFromRows(rows)
}
-func (r *OfficeHourRepo) FindByRoom(room models.Room) ([]models.OfficeHour, error) {
- rows, err := r.db.Query("SELECT * FROM officeHour WHERE room=?", room.Id)
+func (r *OfficeHourRepo) FindByRoom(room models.Room, activeOnly bool) ([]models.OfficeHour, error) {
+ var rows *sql.Rows
+ var err error
+ if activeOnly {
+ rows, err = r.db.Query("SELECT * FROM officeHour WHERE room=? AND active", room.Id)
+ } else {
+ rows, err = r.db.Query("SELECT * FROM officeHour WHERE room=?", room.Id)
+ }
if err != nil {
return nil, err
}
@@ -55,7 +73,43 @@ func (r *OfficeHourRepo) FindById(id int) (models.OfficeHour, error) {
}
func (r *OfficeHourRepo) Add(officeHour models.OfficeHour) error {
- return nil
+ // Find correct tutor or add if not existent
+ r.tutorRepo.Add(officeHour.Tutor)
+ var err error
+ officeHour.Tutor, err = r.tutorRepo.FindByNameAndEmail(officeHour.Tutor.Name, officeHour.Tutor.Email)
+ if err != nil {
+ return err
+ }
+
+ //Don't add identical officeHours
+ officeHours, err := r.FindByCourse(officeHour.Course, false)
+ if err != nil {
+ return err
+ }
+ for _, oldOfficeHour := range officeHours {
+ if officeHour.Tutor == oldOfficeHour.Tutor &&
+ officeHour.Date == oldOfficeHour.Date &&
+ officeHour.Room == oldOfficeHour.Room &&
+ // officeHour.Course == oldOfficeHour.Course && already filtered above
+ officeHour.Info == oldOfficeHour.Info &&
+ officeHour.Active == oldOfficeHour.Active &&
+ officeHour.Duration == oldOfficeHour.Duration {
+ return nil
+ }
+ }
+
+ _, err = r.db.Exec("INSERT INTO `officeHour` (tutor, day, hour, minute, room, course, week, info, active, duration) VALUES (?,?,?,?,?,?,?,?,?,?)",
+ officeHour.Tutor.Id,
+ officeHour.Date.Day,
+ officeHour.Date.Hour,
+ officeHour.Date.Minute,
+ officeHour.Room.Id,
+ officeHour.Course.Id,
+ officeHour.Date.Week,
+ officeHour.Info,
+ officeHour.Active,
+ officeHour.Duration)
+ return err
}
func (r *OfficeHourRepo) Delete(officeHour models.OfficeHour) error {
@@ -64,13 +118,13 @@ func (r *OfficeHourRepo) Delete(officeHour models.OfficeHour) error {
func (r *OfficeHourRepo) getFromRow(row *sql.Row) (models.OfficeHour, error) {
var officeHour models.OfficeHour
- var day, hour, minute, tutorid int
+ var week, day, hour, minute, tutorid int
var roomName, courseName string
- err := row.Scan(&officeHour.Id, &tutorid, &day, &hour, &minute, &roomName, &courseName, &officeHour.Week, &officeHour.Info, &officeHour.Active, &officeHour.Duration)
+ err := row.Scan(&officeHour.Id, &tutorid, &day, &hour, &minute, &roomName, &courseName, &week, &officeHour.Info, &officeHour.Active, &officeHour.Duration)
if err != nil {
return models.OfficeHour{}, err
}
- officeHour.Date = models.Date{day, hour, minute}
+ officeHour.Date = models.Date{week, day, hour, minute}
officeHour.Room, _ = r.roomRepo.FindByName(roomName)
officeHour.Tutor, _ = r.tutorRepo.FindById(tutorid)
officeHour.Course, _ = r.courseRepo.FindByName(courseName)
@@ -81,11 +135,11 @@ func (r *OfficeHourRepo) getFromRows(rows *sql.Rows) ([]models.OfficeHour, error
var officeHours []models.OfficeHour
for rows.Next() {
var officeHour models.OfficeHour
- var day, hour, minute, tutorId, roomId, courseId int
- if err := rows.Scan(&officeHour.Id, &tutorId, &day, &hour, &minute, &roomId, &courseId, &officeHour.Week, &officeHour.Info, &officeHour.Active, &officeHour.Duration); err != nil {
+ var week, day, hour, minute, tutorId, roomId, courseId int
+ if err := rows.Scan(&officeHour.Id, &tutorId, &day, &hour, &minute, &roomId, &courseId, &week, &officeHour.Info, &officeHour.Active, &officeHour.Duration); err != nil {
return officeHours, err
}
- officeHour.Date = models.Date{day, hour, minute}
+ officeHour.Date = models.Date{week, day, hour, minute}
officeHour.Room, _ = r.roomRepo.FindById(roomId)
officeHour.Tutor, _ = r.tutorRepo.FindById(tutorId)
officeHour.Course, _ = r.courseRepo.FindById(courseId)
diff --git a/repositories/tutor.go b/repositories/tutor.go
index f78b702..a6bc950 100644
--- a/repositories/tutor.go
+++ b/repositories/tutor.go
@@ -43,6 +43,15 @@ func (r *TutorRepo) FindById(id int) (models.Tutor, error) {
return tutor, nil
}
+func (r *TutorRepo) FindByNameAndEmail(name string, email string) (models.Tutor, error) {
+ row := r.db.QueryRow("SELECT * FROM tutor WHERE email=? AND name=?", email, name)
+ var tutor models.Tutor
+ if err := row.Scan(&tutor.Id, &tutor.Name, &tutor.Email); err != nil {
+ return models.Tutor{}, err
+ }
+ return tutor, nil
+}
+
func (r *TutorRepo) GetAll() ([]models.Tutor, error) {
rows, err := r.db.Query("SELECT * FROM tutor")
if err != nil {
@@ -64,5 +73,12 @@ func (r *TutorRepo) Save(tutor models.Tutor) error {
return nil
}
func (r *TutorRepo) Add(tutor models.Tutor) error {
- return nil
+ //Don't add identical tutors
+ _, err := r.FindByNameAndEmail(tutor.Name, tutor.Email)
+ if err == sql.ErrNoRows {
+ _, err = r.db.Exec("INSERT INTO `tutor` (name, email) VALUES (?,?);", tutor.Name, tutor.Email)
+ return err
+ }
+ return err
+
}
diff --git a/templates/addFailure.html b/templates/addFailure.html
new file mode 100644
index 0000000..6ec9f8b
--- /dev/null
+++ b/templates/addFailure.html
@@ -0,0 +1,10 @@
+
+
+ Sprechstunde anlegen
+
+
+ Irgendetwas ist schief gegangen. Bitte sende folgende Daten an sprechstundentool@mathebau.de mit einer Beschreibung, was du tun wolltest.
+
+ {{.}}
+
+
\ No newline at end of file
diff --git a/templates/addMask.html b/templates/addMask.html
new file mode 100644
index 0000000..8efab4e
--- /dev/null
+++ b/templates/addMask.html
@@ -0,0 +1,49 @@
+
+
+ Sprechstunde anlegen
+
+
+
+ {{range .Errors}}{{.}} {{end}}
+
+
+
+
+ Du musst hier eine Email-Adresse angeben, die auf „tu-darmstadt.de“ endet.
+ Außerdem dürfen in Räumen nur begrenzt viele Sprechstunden gleichzeitig stattfinden, nämlich
+