diff --git a/Backend/models/booking.go b/Backend/models/booking.go index 7b4d356..28b638a 100644 --- a/Backend/models/booking.go +++ b/Backend/models/booking.go @@ -6,6 +6,7 @@ import ( "database/sql" "fmt" "log" + "log/slog" "net/url" "strconv" "time" @@ -87,6 +88,27 @@ func (b *Booking) Verify() bool { return true } +func (b *Booking) IsSubmittedAndChecked() bool { + qStr, err := DB.Prepare(`SELECT bestaetigt from wochen_report WHERE $1 = ANY(anwesenheiten);`) + if err != nil { + slog.Warn("Error when preparing SQL Statement", "error", err) + return false + } + defer qStr.Close() + var isSubmittedAndChecked bool = false + + err = qStr.QueryRow(b.CounterId).Scan(&isSubmittedAndChecked) + if err == sql.ErrNoRows { + // No rows found ==> not even submitted + return false + } + + if err != nil { + slog.Warn("Unexpected error when executing SQL Statement", "error", err) + } + return isSubmittedAndChecked +} + func (b *Booking) Insert() error { if !checkLastBooking(*b) { return SameBookingError{} diff --git a/Backend/models/workDay.go b/Backend/models/workDay.go index 9780ce7..5ae30a0 100644 --- a/Backend/models/workDay.go +++ b/Backend/models/workDay.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "log" + "log/slog" "sort" "time" ) @@ -110,6 +111,7 @@ func (d *WorkDay) TimeWorkReal(u User) time.Duration { if helper.IsSameDate(d.Date(), time.Now()) && len(d.Bookings)%2 == 1 { d.realWorkTime += time.Since(lastBooking.Timestamp.Local()) } + slog.Debug("Calculated RealWorkTime for user", "user", u, slog.String("worktime", d.realWorkTime.String())) return d.realWorkTime } diff --git a/Backend/models/workWeek.go b/Backend/models/workWeek.go index 634d6fb..beaf504 100644 --- a/Backend/models/workWeek.go +++ b/Backend/models/workWeek.go @@ -4,23 +4,25 @@ import ( "database/sql" "errors" "log" + "log/slog" "time" + + "github.com/lib/pq" ) // Workweeks are type WorkWeek struct { - Id int - WorkDays []WorkDay - Absences []Absence - Days []IWorkDay - User User - WeekStart time.Time - Worktime time.Duration - Overtime time.Duration - Status WeekStatus - overtimeDiff time.Duration - worktimeDiff time.Duration + Id int + WorkDays []WorkDay + Absences []Absence + Days []IWorkDay + User User + WeekStart time.Time + Worktime time.Duration + WorkTimeVirtual time.Duration + Overtime time.Duration + Status WeekStatus } type WeekStatus int8 @@ -45,16 +47,17 @@ func NewWorkWeek(user User, tsMonday time.Time, populate bool) WorkWeek { } func (w *WorkWeek) PopulateWithDays(worktime time.Duration, overtime time.Duration) { - log.Println("Got Days with overtime and worktime", worktime, overtime) + slog.Debug("Got Days with overtime and worktime", slog.String("worktime", worktime.String()), slog.String("overtime", overtime.String())) w.Days = GetDays(w.User, w.WeekStart, w.WeekStart.Add(6*24*time.Hour), false) - log.Println(w.Worktime) for _, day := range w.Days { - log.Println(day.TimeWorkVirtual(w.User)) - w.Worktime += day.TimeWorkVirtual(w.User) + work, _ := day.TimePauseReal(w.User) + w.Worktime += work + w.WorkTimeVirtual += day.TimeWorkVirtual(w.User) } - log.Println("Calculated new worktime", w.Worktime) - w.Overtime = w.Worktime - w.User.ArbeitszeitProWoche() + slog.Debug("Got worktime for user", "user", w.User, "worktime", w.Worktime.String(), "virtualWorkTime", w.WorkTimeVirtual.String()) + + w.Overtime = w.WorkTimeVirtual - w.User.ArbeitszeitProWoche() w.Worktime = w.Worktime.Round(time.Minute) w.Overtime = w.Overtime.Round(time.Minute) @@ -65,8 +68,6 @@ func (w *WorkWeek) PopulateWithDays(worktime time.Duration, overtime time.Durati if overtime != w.Overtime || worktime != w.Worktime { w.Status = WeekStatusDifferences - w.overtimeDiff = overtime - w.worktimeDiff = worktime } } @@ -149,30 +150,70 @@ func (w *WorkWeek) GetSendWeeks(user User) []WorkWeek { var ErrRunningWeek = errors.New("Week is in running week") +func (w *WorkWeek) GetBookingIds() (anwesenheitsIds, abwesenheitsIds []int64, err error) { + qStr, err := DB.Prepare(` + SELECT + (SELECT array_agg(counter_id ORDER BY counter_id) + FROM anwesenheit + WHERE card_uid = $1 + AND timestamp::DATE >= $2 + AND timestamp::DATE < $3) AS anwesenheit, + + (SELECT array_agg(counter_id ORDER BY counter_id) + FROM abwesenheit + WHERE card_uid = $1 + AND datum_from < $3 + AND datum_to >= $2) AS abwesenheit; + `) + if err != nil { + return nil, nil, err + } + defer qStr.Close() + + slog.Debug("Inserting parameters into qStr:", "user card_uid", w.User.CardUID, "week_start", w.WeekStart, "week_end", w.WeekStart.AddDate(0, 0, 5)) + + err = qStr.QueryRow(w.User.CardUID, w.WeekStart, w.WeekStart.AddDate(0, 0, 5)).Scan(pq.Array(&anwesenheitsIds), pq.Array(&abwesenheitsIds)) + if err != nil { + return anwesenheitsIds, abwesenheitsIds, err + } + return anwesenheitsIds, abwesenheitsIds, nil +} + // creates a new entry in the woche_report table with the given workweek func (w *WorkWeek) SendWeek() error { var qStr *sql.Stmt var err error + slog.Info("Sending workWeek to team head", "week", w.WeekStart.String()) + + anwBookings, awBookings, err := w.GetBookingIds() + if err != nil { + slog.Warn("Error querying bookings from work week", slog.Any("error", err)) + return err + } + + slog.Debug("Recieved Booking Ids", "anwesenheiten", anwBookings) + if time.Since(w.WeekStart) < 5*24*time.Hour { - log.Println("Cannot send week, because it's the running week!") + slog.Warn("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, arbeitszeit = make_interval(secs => $3::numeric / 1000000000), ueberstunden = make_interval(secs => $4::numeric / 1000000000) WHERE personal_nummer = $1 AND woche_start = $2;`) + qStr, err = DB.Prepare(`UPDATE "wochen_report" SET bestaetigt = FALSE, arbeitszeit = make_interval(secs => $3::numeric / 1000000000), ueberstunden = make_interval(secs => $4::numeric / 1000000000), anwesenheiten=$5, abwesenheiten=$6 WHERE personal_nummer = $1 AND woche_start = $2;`) if err != nil { - log.Println("Error preparing SQL statement", err) + slog.Warn("Error preparing SQL statement", "error", err) return err } } else { - qStr, err = DB.Prepare(`INSERT INTO wochen_report (personal_nummer, woche_start, arbeitszeit, ueberstunden) VALUES ($1, $2, make_interval(secs => $3::numeric / 1000000000), make_interval(secs => $4::numeric / 1000000000));`) + qStr, err = DB.Prepare(`INSERT INTO wochen_report (personal_nummer, woche_start, arbeitszeit, ueberstunden, anwesenheiten, abwesenheiten) VALUES ($1, $2, make_interval(secs => $3::numeric / 1000000000), make_interval(secs => $4::numeric / 1000000000), $5, $6);`) if err != nil { - log.Println("Error preparing SQL statement", err) + slog.Warn("Error preparing SQL statement", "error", err) return err } } - _, err = qStr.Exec(w.User.PersonalNummer, w.WeekStart, int64(w.Worktime), int64(w.Overtime)) + + _, err = qStr.Exec(w.User.PersonalNummer, w.WeekStart, int64(w.Worktime), int64(w.Overtime), pq.Array(anwBookings), pq.Array(awBookings)) if err != nil { log.Println("Error executing query!", err) return err diff --git a/Backend/templates/headerComponent_templ.go b/Backend/templates/headerComponent_templ.go index 8e59160..aeef6ec 100644 --- a/Backend/templates/headerComponent_templ.go +++ b/Backend/templates/headerComponent_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.943 +// templ: version: v0.3.924 package templates //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/Backend/templates/pages_templ.go b/Backend/templates/pages_templ.go index ad17982..491784c 100644 --- a/Backend/templates/pages_templ.go +++ b/Backend/templates/pages_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.943 +// templ: version: v0.3.924 package templates //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/Backend/templates/pdf_templ.go b/Backend/templates/pdf_templ.go index 321301b..3c73ded 100644 --- a/Backend/templates/pdf_templ.go +++ b/Backend/templates/pdf_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.943 +// templ: version: v0.3.924 package templates //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/Backend/templates/teamComponents.templ b/Backend/templates/teamComponents.templ index e5738b9..d1dd820 100644 --- a/Backend/templates/teamComponents.templ +++ b/Backend/templates/teamComponents.templ @@ -81,7 +81,7 @@ templ weekDayComponent(user models.User, day models.WorkDay) { templ workWeekComponent(week models.WorkWeek, onlyAccept bool) { {{ year, kw := week.WeekStart.ISOWeek() - progress := (float32(week.Worktime.Hours()) / week.User.ArbeitszeitPerWoche) * 100 + progress := (float32(week.WorkTimeVirtual.Hours()) / week.User.ArbeitszeitPerWoche) * 100 }}
submitted
+ }submitted
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "