From e8f111329392f6eff95a7c9f4b1676ddace8a174 Mon Sep 17 00:00:00 2001
From: tom
Date: Thu, 25 Sep 2025 21:52:53 +0200
Subject: [PATCH] using IWorkDay interface for team
---
Backend/endpoints/pdf.go | 2 +-
Backend/endpoints/time.go | 2 +-
Backend/models/absence.go | 7 ++
Backend/models/workDay.go | 13 ++-
Backend/models/workWeek.go | 6 +-
Backend/templates/pdf.templ | 32 ++++---
Backend/templates/pdf_templ.go | 162 ++++++++++++++++++++-------------
7 files changed, 141 insertions(+), 83 deletions(-)
diff --git a/Backend/endpoints/pdf.go b/Backend/endpoints/pdf.go
index 50f7130..ce27116 100644
--- a/Backend/endpoints/pdf.go
+++ b/Backend/endpoints/pdf.go
@@ -29,7 +29,7 @@ func PDFHandler(w http.ResponseWriter, r *http.Request) {
//TODO: only accepted weeks
- weeks := models.GetWorkDays(user, startDate, endDate)
+ weeks := models.GetDays(user, startDate, endDate, false)
// log.Printf("Using Dates: %s - %s\n", startDate.String(), endDate.String())
templates.PDFReportEmploye(user, weeks, startDate, endDate).Render(r.Context(), w)
diff --git a/Backend/endpoints/time.go b/Backend/endpoints/time.go
index 9f85c2e..0be3f67 100644
--- a/Backend/endpoints/time.go
+++ b/Backend/endpoints/time.go
@@ -66,7 +66,7 @@ func getBookings(w http.ResponseWriter, r *http.Request) {
}
tsTo = tsTo.AddDate(0, 0, 1) // so that today is inside
- days := models.GetDays(user, tsFrom, tsTo)
+ days := models.GetDays(user, tsFrom, tsTo, true)
sort.Slice(days, func(i, j int) bool {
return days[i].Date().After(days[j].Date())
})
diff --git a/Backend/models/absence.go b/Backend/models/absence.go
index a008fde..b0fb959 100644
--- a/Backend/models/absence.go
+++ b/Backend/models/absence.go
@@ -87,6 +87,13 @@ func (a *Absence) RequiresAction() bool {
return false
}
+func (a *Absence) GetAllWorkTimesVirtual(u User) (work, pause, overtime time.Duration) {
+ if a.AbwesenheitTyp.WorkTime > 1 {
+ return u.ArbeitszeitProTag(), 0, 0
+ }
+ return 0, 0, 0
+}
+
func (a *Absence) Insert() error {
qStr, err := DB.Prepare(`INSERT INTO abwesenheit (card_uid, abwesenheit_typ, datum_from, datum_to) VALUES ($1, $2, $3, $4) RETURNING counter_id;`)
if err != nil {
diff --git a/Backend/models/workDay.go b/Backend/models/workDay.go
index 0c1f6b9..51025b9 100644
--- a/Backend/models/workDay.go
+++ b/Backend/models/workDay.go
@@ -4,6 +4,7 @@ import (
"arbeitszeitmessung/helper"
"encoding/json"
"log"
+ "sort"
"strconv"
"time"
)
@@ -14,6 +15,7 @@ type IWorkDay interface {
TimeWorkReal(User) time.Duration
TimePauseReal(User) (work, pause time.Duration)
TimeOvertimeReal(User) time.Duration
+ GetAllWorkTimesVirtual(User) (work, pause, overtime time.Duration)
ToString() string
IsWorkDay() bool
IsKurzArbeit() bool
@@ -33,7 +35,7 @@ type WorkDay struct {
kurzArbeit bool
}
-func GetDays(user User, tsFrom, tsTo time.Time) []IWorkDay {
+func GetDays(user User, tsFrom, tsTo time.Time, orderedForward bool) []IWorkDay {
var allDays map[string]IWorkDay = make(map[string]IWorkDay)
var sortedDays []IWorkDay
for _, day := range GetWorkDays(user, tsFrom, tsTo) {
@@ -60,6 +62,15 @@ func GetDays(user User, tsFrom, tsTo time.Time) []IWorkDay {
for _, day := range allDays {
sortedDays = append(sortedDays, day)
}
+ if orderedForward {
+ sort.Slice(sortedDays, func(i, j int) bool {
+ return sortedDays[i].Date().After(sortedDays[j].Date())
+ })
+ } else {
+ sort.Slice(sortedDays, func(i, j int) bool {
+ return sortedDays[i].Date().Before(sortedDays[j].Date())
+ })
+ }
return sortedDays
}
diff --git a/Backend/models/workWeek.go b/Backend/models/workWeek.go
index aeb7879..7144b8e 100644
--- a/Backend/models/workWeek.go
+++ b/Backend/models/workWeek.go
@@ -4,7 +4,6 @@ import (
"database/sql"
"errors"
"log"
- "sort"
"time"
)
@@ -46,10 +45,7 @@ func NewWorkWeek(user User, tsMonday time.Time, populate bool) WorkWeek {
}
func (w *WorkWeek) PopulateWithDays(worktime time.Duration, overtime time.Duration) {
- w.Days = GetDays(w.User, w.WeekStart, w.WeekStart.Add(6*24*time.Hour))
- sort.Slice(w.Days, func(i, j int) bool {
- return w.Days[i].Date().Before(w.Days[j].Date())
- })
+ w.Days = GetDays(w.User, w.WeekStart, w.WeekStart.Add(6*24*time.Hour), false)
for _, day := range w.Days {
w.Worktime += day.TimeWorkVirtual(w.User)
diff --git a/Backend/templates/pdf.templ b/Backend/templates/pdf.templ
index ad6c6b9..2b92d10 100644
--- a/Backend/templates/pdf.templ
+++ b/Backend/templates/pdf.templ
@@ -6,7 +6,7 @@ import (
"time"
)
-templ PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Time, tsEnd time.Time) {
+templ PDFReportEmploye(e models.User, workDays []models.IWorkDay, tsStart time.Time, tsEnd time.Time) {
{{
_, kw := tsStart.ISOWeek()
noBorder := ""
@@ -33,22 +33,32 @@ templ PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Ti
noBorder = "border-b-0"
}
}}
- { day.Day.Format("02.01.2006") }
+ { day.Date().Format("02.01.2006") }
- for bookingI := 0; bookingI < len(day.Bookings); bookingI+= 2 {
-
{ day.Bookings[bookingI].Timestamp.Format("15:04") }
-
{ day.Bookings[bookingI+1].Timestamp.Format("15:04") }
-
{ day.Bookings[bookingI].BookingType.Name }
+ if day.IsWorkDay() {
+ {{
+ workDay, _ := day.(*models.WorkDay)
+ }}
+ for bookingI := 0; bookingI < len(workDay.Bookings); bookingI+= 2 {
+
{ workDay.Bookings[bookingI].Timestamp.Format("15:04") }
+
{ workDay.Bookings[bookingI+1].Timestamp.Format("15:04") }
+
{ workDay.Bookings[bookingI].BookingType.Name }
+ }
+ if workDay.IsKurzArbeit() {
+
Kurzarbeit
+ }
+ } else {
+ {{
+ absentDay, _ := day.(*models.Absence)
+ }}
+
{ absentDay.AbwesenheitTyp.Name }
}
- // if (day.Absence != models.Absence{}) {
- //
{ day.Absence.AbwesenheitTyp.Name }
- // }
- {{ work, pause, overtime := day.GetAllWorkTimesReal(e) }}
+ {{ work, pause, overtime := day.GetAllWorkTimesVirtual(e) }}
@ColorDuration(work, noBorder)
@ColorDuration(pause, noBorder)
@ColorDuration(overtime, noBorder+" border-r-0")
- if day.Day.Weekday() == time.Friday {
+ if day.Date().Weekday() == time.Friday {
Wochenende
}
}
diff --git a/Backend/templates/pdf_templ.go b/Backend/templates/pdf_templ.go
index 78d3396..57c5998 100644
--- a/Backend/templates/pdf_templ.go
+++ b/Backend/templates/pdf_templ.go
@@ -14,7 +14,7 @@ import (
"time"
)
-func PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Time, tsEnd time.Time) templ.Component {
+func PDFReportEmploye(e models.User, workDays []models.IWorkDay, tsStart time.Time, tsEnd time.Time) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
@@ -113,9 +113,9 @@ func PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Tim
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
- templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(day.Day.Format("02.01.2006"))
+ templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(day.Date().Format("02.01.2006"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 36, Col: 56}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 36, Col: 59}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
@@ -147,61 +147,95 @@ func PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Tim
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- for bookingI := 0; bookingI < len(day.Bookings); bookingI += 2 {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "")
+ if day.IsWorkDay() {
+
+ workDay, _ := day.(*models.WorkDay)
+ for bookingI := 0; bookingI < len(workDay.Bookings); bookingI += 2 {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var10 string
+ templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Bookings[bookingI].Timestamp.Format("15:04"))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 43, Col: 64}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var11 string
+ templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Bookings[bookingI+1].Timestamp.Format("15:04"))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 44, Col: 66}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var12 string
+ templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Bookings[bookingI].BookingType.Name)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 45, Col: 55}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var10 string
- templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(day.Bookings[bookingI].Timestamp.Format("15:04"))
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 39, Col: 59}
+ if workDay.IsKurzArbeit() {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "Kurzarbeit
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
+ } else {
+
+ absentDay, _ := day.(*models.Absence)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
")
+ var templ_7745c5c3_Var13 string
+ templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(absentDay.AbwesenheitTyp.Name)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 54, Col: 62}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var11 string
- templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(day.Bookings[bookingI+1].Timestamp.Format("15:04"))
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 40, Col: 61}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var12 string
- templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(day.Bookings[bookingI].BookingType.Name)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 41, Col: 50}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- work, pause, overtime := day.GetAllWorkTimesReal(e)
+ work, pause, overtime := day.GetAllWorkTimesVirtual(e)
templ_7745c5c3_Err = ColorDuration(work, noBorder).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -209,7 +243,7 @@ func PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Tim
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -217,18 +251,18 @@ func PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Tim
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- if day.Day.Weekday() == time.Friday {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "Wochenende
")
+ if day.Date().Weekday() == time.Friday {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "Wochenende
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -252,9 +286,9 @@ func ColorDuration(d time.Duration, classes string) templ.Component {
}()
}
ctx = templ.InitializeContext(ctx)
- templ_7745c5c3_Var13 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var13 == nil {
- templ_7745c5c3_Var13 = templ.NopComponent
+ templ_7745c5c3_Var14 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var14 == nil {
+ templ_7745c5c3_Var14 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
@@ -262,38 +296,38 @@ func ColorDuration(d time.Duration, classes string) templ.Component {
if d.Abs() < time.Minute {
color = "text-neutral-300"
}
- var templ_7745c5c3_Var14 = []any{color + " " + classes}
- templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
+ var templ_7745c5c3_Var15 = []any{color + " " + classes}
+ templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var15...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "\">")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var17 string
+ templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDurationFill(d, true))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 76, Col: 72}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}