diff --git a/Backend/endpoints/team.go b/Backend/endpoints/team.go index b93585e..54bed44 100644 --- a/Backend/endpoints/team.go +++ b/Backend/endpoints/team.go @@ -34,7 +34,7 @@ func submitReport(w http.ResponseWriter, r *http.Request) { _weekTs := r.FormValue("week") weekTs, err := time.Parse(time.DateOnly, _weekTs) user, err := models.GetUserByPersonalNr(userPN) - workWeek := (*models.WorkWeek).GetWeek(nil, user, weekTs, false) + workWeek := models.NewWorkWeek(user, weekTs, true) if err != nil { log.Println("Could not get user!") @@ -70,7 +70,7 @@ func showWeeks(w http.ResponseWriter, r *http.Request) { lastSub = helper.GetMonday(submissionDate) } } - userWeek := (*models.WorkWeek).GetWeek(nil, user, lastSub, true) + userWeek := models.NewWorkWeek(user, lastSub, true) var workWeeks []models.WorkWeek teamMembers, err := user.GetTeamMembers() diff --git a/Backend/models/user.go b/Backend/models/user.go index 4ba7e1d..b542c01 100644 --- a/Backend/models/user.go +++ b/Backend/models/user.go @@ -13,11 +13,12 @@ import ( ) type User struct { - CardUID string `json:"card_uid"` - Name string `json:"name"` - Vorname string `json:"vorname"` - PersonalNummer int `json:"personal_nummer"` - ArbeitszeitPerTag float32 `json:"arbeitszeit"` + CardUID string `json:"card_uid"` + Name string `json:"name"` + Vorname string `json:"vorname"` + PersonalNummer int `json:"personal_nummer"` + ArbeitszeitPerTag float32 `json:"arbeitszeit_per_tag"` + ArbeitszeitPerWoche float32 `json:"arbeitszeit_per_woche"` } func (u *User) GetUserFromSession(Session *scs.SessionManager, ctx context.Context) (User, error) { @@ -98,11 +99,11 @@ func (u *User) CheckOut() error { func GetUserByPersonalNr(personalNummer int) (User, error) { var user User - qStr, err := DB.Prepare((`SELECT personal_nummer, card_uid, vorname, nachname, arbeitszeit_per_tag FROM s_personal_daten WHERE personal_nummer = $1;`)) + qStr, err := DB.Prepare((`SELECT personal_nummer, card_uid, vorname, nachname, arbeitszeit_per_tag, arbeitszeit_per_woche FROM s_personal_daten WHERE personal_nummer = $1;`)) if err != nil { return user, err } - err = qStr.QueryRow(personalNummer).Scan(&user.PersonalNummer, &user.CardUID, &user.Vorname, &user.Name, &user.ArbeitszeitPerTag) + err = qStr.QueryRow(personalNummer).Scan(&user.PersonalNummer, &user.CardUID, &user.Vorname, &user.Name, &user.ArbeitszeitPerTag, &user.ArbeitszeitPerWoche) if err != nil { return user, err @@ -223,10 +224,8 @@ func (u *User) GetLastSubmission() time.Time { log.Println("Error executing query!", err) return lastSub } - log.Println("From DB: ", lastSub) lastSub = getMonday(lastSub) lastSub = lastSub.Round(24 * time.Hour) - log.Println("After truncate: ", lastSub) return lastSub } diff --git a/Backend/models/workDay.go b/Backend/models/workDay.go index 13a0166..33797f6 100644 --- a/Backend/models/workDay.go +++ b/Backend/models/workDay.go @@ -201,6 +201,11 @@ func (d *WorkDay) GetWorkDayProgress(user User) uint8 { } func (d *WorkDay) CalcOvertime(user User) time.Duration { - overtime := d.workTime - time.Duration(user.ArbeitszeitPerTag*float32(time.Hour)).Round(time.Minute) + var overtime time.Duration + // weekday is WE + overtime = d.workTime - time.Duration(user.ArbeitszeitPerTag*float32(time.Hour)).Round(time.Minute) + if (d.Day.Weekday() == 6 || d.Day.Weekday() == 0) && len(d.Bookings) == 0 { + overtime = 0 + } return overtime } diff --git a/Backend/models/workWeek.go b/Backend/models/workWeek.go index 7bd4beb..03ebae3 100644 --- a/Backend/models/workWeek.go +++ b/Backend/models/workWeek.go @@ -8,12 +8,16 @@ import ( "time" ) +// Workweeks are + type WorkWeek struct { Id int WorkDays []WorkDay + Absences []Absence User User WeekStart time.Time WorkHours time.Duration + Status WeekStatus } type WeekStatus int8 @@ -24,51 +28,68 @@ const ( WeekStatusAccepted ) -func (w *WorkWeek) GetWeek(user User, tsMonday time.Time, populateDays bool) WorkWeek { - var week WorkWeek - if populateDays { - week.WorkDays = (*WorkDay).GetWorkDays(nil, user.CardUID, tsMonday, tsMonday.Add(7*24*time.Hour)) - week.WorkHours = aggregateWorkTime(week.WorkDays) +func NewWorkWeek(user User, tsMonday time.Time, populate bool) WorkWeek { + var week WorkWeek = WorkWeek{ + User: user, + WeekStart: tsMonday, + Status: WeekStatusNone, + } + if populate { + week.WorkDays = (*WorkDay).GetWorkDays(nil, user.CardUID, tsMonday, tsMonday.Add(7*24*time.Hour)) + if absences, err := GetAbsenceByCardUID(user.CardUID, tsMonday, tsMonday.Add(7*24*time.Hour)); err == nil { + week.Absences = absences + } else { + log.Printf("Error populating absences in workWeek (%s): %v", tsMonday, err) + } + week.WorkHours = week.aggregateWorkTime() } - week.User = user - week.WeekStart = tsMonday return week } func (w *WorkWeek) CheckStatus() WeekStatus { - weekStatus := WeekStatusNone + if w.Status != WeekStatusNone { + return w.Status + } + if DB == nil { + log.Println("Cannot access Database!") + return w.Status + } qStr, err := DB.Prepare(`SELECT bestaetigt FROM wochen_report WHERE woche_start = $1::DATE AND personal_nummer = $2;`) if err != nil { log.Println("Error preparing SQL statement", err) - return weekStatus + return w.Status } defer qStr.Close() var beastatigt bool err = qStr.QueryRow(w.WeekStart, w.User.PersonalNummer).Scan(&beastatigt) if err == sql.ErrNoRows { - return weekStatus + return w.Status } if err != nil { log.Println("Error querying database", err) - return weekStatus + return w.Status } if beastatigt { - weekStatus = WeekStatusAccepted + w.Status = WeekStatusAccepted } else { - weekStatus = WeekStatusSent + w.Status = WeekStatusSent } - return weekStatus + return w.Status } func (w *WorkWeek) GetWorkHourString() string { return helper.FormatDuration(w.WorkHours) } -func aggregateWorkTime(days []WorkDay) time.Duration { +func (w *WorkWeek) aggregateWorkTime() time.Duration { var workTime time.Duration - for _, day := range days { + for _, day := range w.WorkDays { workTime += day.workTime } + for _, absences := range w.Absences { + absenceWorkTime := absences.AbwesenheitTyp.WorkTime - (absences.AbwesenheitTyp.WorkTime - w.User.ArbeitszeitPerTag) // workTime Equivalent of Absence is capped at user Worktime per Day + workTime += time.Duration(absenceWorkTime * float32(time.Hour)).Round(time.Minute) + } return workTime } @@ -95,7 +116,7 @@ func (w *WorkWeek) GetSendWeeks(user User) []WorkWeek { return weeks } week.WorkDays = (*WorkDay).GetWorkDays(nil, user.CardUID, week.WeekStart, week.WeekStart.Add(7*24*time.Hour)) - week.WorkHours = aggregateWorkTime(week.WorkDays) + week.WorkHours = week.aggregateWorkTime() weeks = append(weeks, week) } if err = rows.Err(); err != nil { @@ -107,34 +128,40 @@ func (w *WorkWeek) GetSendWeeks(user User) []WorkWeek { var ErrRunningWeek = errors.New("Week is in running week") +func (w *WorkWeek) GetOvertime() time.Duration { + var weekOvertime time.Duration = w.WorkHours - time.Duration(w.User.ArbeitszeitPerWoche*float32(time.Hour)).Round(time.Minute) + return weekOvertime +} + // creates a new entry in the woche_report table with the given workweek func (w *WorkWeek) Send() error { var qStr *sql.Stmt var err error + if time.Since(w.WeekStart) < 5*24*time.Hour { log.Println("Cannot send week, because it's the running week!") return ErrRunningWeek } + if w.CheckStatus() != WeekStatusNone { - qStr, err = DB.Prepare(`UPDATE "wochen_report" SET bestaetigt = FALSE WHERE personal_nummer = $1 AND woche_start = $2;`) + qStr, err = DB.Prepare(`UPDATE "wochen_report" SET bestaetigt = FALSE, ueberstunden = $3 WHERE personal_nummer = $1 AND woche_start = $2;`) if err != nil { log.Println("Error preparing SQL statement", err) return err } } else { - qStr, err = DB.Prepare(`INSERT INTO wochen_report (personal_nummer, woche_start) VALUES ($1, $2);`) + qStr, err = DB.Prepare(`INSERT INTO wochen_report (personal_nummer, woche_start, ueberstunden) VALUES ($1, $2, $3);`) if err != nil { log.Println("Error preparing SQL statement", err) return err } } - _, err = qStr.Exec(w.User.PersonalNummer, w.WeekStart) + _, err = qStr.Exec(w.User.PersonalNummer, w.WeekStart, w.GetOvertime().Hours()) if err != nil { log.Println("Error executing query!", err) return err } return nil - } func (w *WorkWeek) Accept() error {