package models import ( "database/sql" "errors" "log" "time" ) type WorkWeek struct { Id int WorkDays []WorkDay User User WeekStart time.Time WorkHours time.Duration } type WeekStatus int8 const ( None WeekStatus = iota Sent Accepted ) 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) } week.User = user week.WeekStart = tsMonday return week } func (w *WorkWeek) CheckStatus() WeekStatus { weekStatus := None 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 } defer qStr.Close() var beastatigt bool err = qStr.QueryRow(w.WeekStart, w.User.PersonalNummer).Scan(&beastatigt) if err == sql.ErrNoRows { return weekStatus } if err != nil { log.Println("Error querying database", err) return weekStatus } if beastatigt { weekStatus = Accepted } else { weekStatus = Sent } return weekStatus } func (w *WorkWeek) GetWorkHourString() string { return formatDuration(w.WorkHours) } func aggregateWorkTime(days []WorkDay) time.Duration { var workTime time.Duration for _, day := range days { workTime += day.workTime } return workTime } func (w *WorkWeek) GetSendWeeks(user User) []WorkWeek { var weeks []WorkWeek qStr, err := DB.Prepare(`SELECT id, woche_start::DATE FROM wochen_report WHERE bestaetigt = FALSE AND personal_nummer = $1;`) if err != nil { log.Println("Error preparing SQL statement", err) return weeks } defer qStr.Close() rows, err := qStr.Query(user.PersonalNummer) if err != nil { log.Println("Error querining db!", err) return weeks } defer rows.Close() for rows.Next() { var week WorkWeek week.User = user if err := rows.Scan(&week.Id, &week.WeekStart); err != nil { log.Println("Error scanning row!", err) return weeks } week.WorkDays = (*WorkDay).GetWorkDays(nil, user.CardUID, week.WeekStart, week.WeekStart.Add(7*24*time.Hour)) week.WorkHours = aggregateWorkTime(week.WorkDays) weeks = append(weeks, week) } if err = rows.Err(); err != nil { return weeks } return weeks } var ErrRunningWeek = errors.New("Week is in running week") // 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() != None { qStr, err = DB.Prepare(`UPDATE "wochen_report" SET bestaetigt = FALSE 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);`) if err != nil { log.Println("Error preparing SQL statement", err) return err } } _, err = qStr.Exec(w.User.PersonalNummer, w.WeekStart) if err != nil { log.Println("Error executing query!", err) return err } return nil } func (w *WorkWeek) Accept() error { qStr, err := DB.Prepare(`UPDATE "wochen_report" SET bestaetigt = TRUE WHERE personal_nummer = $1 AND woche_start = $2;`) if err != nil { log.Println("Error preparing SQL statement", err) return err } _, err = qStr.Exec(w.User.PersonalNummer, w.WeekStart) if err != nil { log.Println("Error executing query!", err) return err } return nil }