From de03c100d40744f11308571e72b12c9a776299fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=20Tr=C3=B6ger?=
Date: Fri, 5 Sep 2025 10:36:26 +0200
Subject: [PATCH 1/7] fixed #28
---
Backend/models/workDay.go | 10 +-
Backend/models/workWeek.go | 8 +
Backend/templates/pages.templ | 2 +-
Backend/templates/pages_templ.go | 2 +-
Backend/templates/teamComponents.templ | 45 ++---
Backend/templates/teamComponents_templ.go | 190 ++++++++++++----------
Backend/templates/timeComponents.templ | 12 +-
Backend/templates/timeComponents_templ.go | 178 ++++++++++----------
8 files changed, 242 insertions(+), 205 deletions(-)
diff --git a/Backend/models/workDay.go b/Backend/models/workDay.go
index c009df3..54f23b8 100644
--- a/Backend/models/workDay.go
+++ b/Backend/models/workDay.go
@@ -56,7 +56,7 @@ func (d *WorkDay) GetWorkDays(card_uid string, tsFrom, tsTo time.Time) []WorkDay
COALESCE(
EXTRACT(EPOCH FROM SUM(
CASE
- WHEN b.prev_check IN (1, 3) AND b.check_in_out IN (2, 4, 255)
+ WHEN b.prev_check IN (1, 3) AND b.check_in_out IN (2, 4, 254)
THEN b.timestamp - b.prev_timestamp
ELSE INTERVAL '0'
END
@@ -65,7 +65,7 @@ func (d *WorkDay) GetWorkDays(card_uid string, tsFrom, tsTo time.Time) []WorkDay
COALESCE(
EXTRACT(EPOCH FROM SUM(
CASE
- WHEN b.prev_check IN (2, 4, 255) AND b.check_in_out IN (1, 3)
+ WHEN b.prev_check IN (2, 4, 254) AND b.check_in_out IN (1, 3)
THEN b.timestamp - b.prev_timestamp
ELSE INTERVAL '0'
END
@@ -189,10 +189,10 @@ func (d *WorkDay) GetWorkTimeString() (string, string) {
// returns bool wheter the workday was ended with an automatic logout
func (d *WorkDay) RequiresAction() bool {
- if len(d.Bookings) > 0 {
- return d.Bookings[len(d.Bookings)-1].CheckInOut == 254
+ if len(d.Bookings) == 0 {
+ return false
}
- return false
+ return d.Bookings[len(d.Bookings)-1].CheckInOut == 254
}
// returns a integer percentage of how much day has been worked of
diff --git a/Backend/models/workWeek.go b/Backend/models/workWeek.go
index 5a9ef61..12c7a78 100644
--- a/Backend/models/workWeek.go
+++ b/Backend/models/workWeek.go
@@ -193,3 +193,11 @@ func (w *WorkWeek) Accept() error {
}
return nil
}
+
+func (w *WorkWeek) RequiresAction() bool {
+ var requiresAction bool = true
+ for _, day := range w.WorkDays {
+ requiresAction = requiresAction || day.RequiresAction()
+ }
+ return requiresAction
+}
diff --git a/Backend/templates/pages.templ b/Backend/templates/pages.templ
index e7c588e..b7865cf 100644
--- a/Backend/templates/pages.templ
+++ b/Backend/templates/pages.templ
@@ -150,7 +150,7 @@ templ TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) {
vom Vorgesetzten bestätigt
}
-
+
diff --git a/Backend/templates/pages_templ.go b/Backend/templates/pages_templ.go
index d7cf3c8..b7915ec 100644
--- a/Backend/templates/pages_templ.go
+++ b/Backend/templates/pages_templ.go
@@ -441,7 +441,7 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- if time.Since(userWeek.WeekStart) < 24*7*time.Hour || userWeek.Status >= models.WeekStatusSent {
+ if time.Since(userWeek.WeekStart) < 24*7*time.Hour || userWeek.Status >= models.WeekStatusSent || userWeek.RequiresAction() {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, " disabled")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
diff --git a/Backend/templates/teamComponents.templ b/Backend/templates/teamComponents.templ
index 6e1a48d..71ed2bd 100644
--- a/Backend/templates/teamComponents.templ
+++ b/Backend/templates/teamComponents.templ
@@ -34,28 +34,33 @@ templ weekPicker(weekStart time.Time) {
templ weekDayComponent(user models.User, day models.WorkDay) {
{{ work, pause := day.GetWorkTimeString() }}
- @timeGaugeComponent(day.GetWorkDayProgress(user), false, false)
+ @timeGaugeComponent(day.GetWorkDayProgress(user), false, day.RequiresAction())
{ day.Day.Format("Mon") }: { day.Day.Format("02.01.2006") }
-
- { work }
- { pause }
-
-
-
- if day.Absence.Datum.Equal(day.Day) {
-
{ day.Absence.AbwesenheitTyp.Name }
- } else if !day.TimeFrom.Equal(day.TimeTo) {
-
{ day.TimeFrom.Format("15:04") }
-
-
-
{ day.TimeTo.Format("15:04") }
- } else {
-
Keine Anwesenheit
- }
-
+ if !day.RequiresAction() {
+
+ { work }
+ { pause }
+
+
+
+ switch {
+ case day.Absence.Datum.Equal(day.Day):
+
{ day.Absence.AbwesenheitTyp.Name }
+ case !day.TimeFrom.Equal(day.TimeTo):
+
{ day.TimeFrom.Format("15:04") }
+
-
+
{ day.TimeTo.Format("15:04") }
+ default:
+
Keine Anwesenheit
+ }
+
+ } else {
+
Bitte anpassen
+ }
}
diff --git a/Backend/templates/teamComponents_templ.go b/Backend/templates/teamComponents_templ.go
index 022e701..0fdead7 100644
--- a/Backend/templates/teamComponents_templ.go
+++ b/Backend/templates/teamComponents_templ.go
@@ -149,7 +149,7 @@ func weekDayComponent(user models.User, day models.WorkDay) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = timeGaugeComponent(day.GetWorkDayProgress(user), false, false).Render(ctx, templ_7745c5c3_Buffer)
+ templ_7745c5c3_Err = timeGaugeComponent(day.GetWorkDayProgress(user), false, day.RequiresAction()).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -179,92 +179,108 @@ func weekDayComponent(user models.User, day models.WorkDay) templ.Component {
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, 14, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var9 string
- templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(work)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 41, Col: 36}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, " ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var10 string
- templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(pause)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 42, Col: 42}
- }
- _, 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, 16, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- if day.Absence.Datum.Equal(day.Day) {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
")
+ if !day.RequiresAction() {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var11 string
- templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(day.Absence.AbwesenheitTyp.Name)
+ var templ_7745c5c3_Var9 string
+ templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(work)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 50, Col: 41}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 42, Col: 37}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- } else if !day.TimeFrom.Equal(day.TimeTo) {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "")
+ var templ_7745c5c3_Var10 string
+ templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(pause)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 43, Col: 43}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var12 string
- templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(day.TimeFrom.Format("15:04"))
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 52, Col: 41}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
+ 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, 20, "
- ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
+ switch {
+ case day.Absence.Datum.Equal(day.Day):
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var11 string
+ templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(day.Absence.AbwesenheitTyp.Name)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 52, Col: 43}
+ }
+ _, 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, 19, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ case !day.TimeFrom.Equal(day.TimeTo):
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var12 string
+ templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(day.TimeFrom.Format("15:04"))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 54, Col: 43}
+ }
+ _, 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, 21, " - ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var13 string
+ templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(day.TimeTo.Format("15:04"))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 56, Col: 41}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ default:
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "Keine Anwesenheit
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
}
- var templ_7745c5c3_Var13 string
- templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(day.TimeTo.Format("15:04"))
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 54, Col: 39}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "
Keine Anwesenheit
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
Bitte anpassen
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -296,33 +312,33 @@ func employeComponent(week models.WorkWeek) templ.Component {
year, kw := week.WeekStart.ISOWeek()
progress := (float32(week.Worktime.Hours()) / week.User.ArbeitszeitPerWoche) * 100
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(week.User.Vorname)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 70, Col: 53}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 75, Col: 53}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(week.User.Name)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 70, Col: 72}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 75, Col: 72}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -330,33 +346,33 @@ func employeComponent(week models.WorkWeek) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "
Arbeitszeit: ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "
Arbeitszeit: ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var17 string
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(week.Worktime)))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 74, Col: 78}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 79, Col: 78}
}
_, 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, 28, "
Überstunden: ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "
Überstunden: ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(week.Overtime)))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 75, Col: 79}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 80, Col: 79}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -366,66 +382,66 @@ func employeComponent(week models.WorkWeek) templ.Component {
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -454,48 +470,48 @@ func userPresenceComponent(user models.User, present bool) templ.Component {
templ_7745c5c3_Var22 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if present {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
Anwesend
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "
Anwesend
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
} else {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "
Abwesend
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "
Abwesend
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var23 string
templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(user.Vorname)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 108, Col: 19}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 113, Col: 19}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var24 string
templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(user.Name)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 108, Col: 33}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 113, Col: 33}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
diff --git a/Backend/templates/timeComponents.templ b/Backend/templates/timeComponents.templ
index 3b89eae..81862f4 100644
--- a/Backend/templates/timeComponents.templ
+++ b/Backend/templates/timeComponents.templ
@@ -57,11 +57,13 @@ templ dayComponent(workDay models.WorkDay, submitted bool) {
if (workDay.RequiresAction()) {
Bitte anpassen
} else {
- { work }
- }
- { pause }
- if overtime != "" {
- { overtime }
+ { work }
+ if pause != "" {
+ { pause }
+ }
+ if overtime != "" {
+ { overtime }
+ }
}
}
diff --git a/Backend/templates/timeComponents_templ.go b/Backend/templates/timeComponents_templ.go
index 3242c18..557daaf 100644
--- a/Backend/templates/timeComponents_templ.go
+++ b/Backend/templates/timeComponents_templ.go
@@ -205,14 +205,14 @@ func dayComponent(workDay models.WorkDay, submitted bool) templ.Component {
return templ_7745c5c3_Err
}
} else {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 string
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(work)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 60, Col: 36}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 60, Col: 35}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
@@ -222,45 +222,51 @@ func dayComponent(workDay models.WorkDay, submitted bool) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var12 string
- templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(pause)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 62, Col: 148}
- }
- _, 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, 17, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- if overtime != "" {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "")
+ if pause != "" {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var12 string
+ templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(pause)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 62, Col: 150}
+ }
+ _, 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, 17, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var13 string
- templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(overtime)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 64, Col: 133}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
+ if overtime != "" {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var13 string
+ templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(overtime)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 65, Col: 134}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "
")
+ 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, 21, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -268,57 +274,57 @@ func dayComponent(workDay models.WorkDay, submitted bool) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -362,7 +368,7 @@ func dayComponent(workDay models.WorkDay, submitted bool) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -395,7 +401,7 @@ func changeButtonComponent(id string) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "\">Ändern
Absenden
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -453,7 +459,7 @@ func timeGaugeComponent(progress uint8, today bool, warning bool) templ.Componen
break
}
if today {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -462,7 +468,7 @@ func timeGaugeComponent(progress uint8, today bool, warning bool) templ.Componen
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "\">
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -498,7 +504,7 @@ func timeGaugeComponent(progress uint8, today bool, warning bool) templ.Componen
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -541,7 +547,7 @@ func lineComponent() templ.Component {
templ_7745c5c3_Var25 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -570,7 +576,7 @@ func absenceComponent(d models.WorkDay) templ.Component {
templ_7745c5c3_Var26 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -578,7 +584,7 @@ func absenceComponent(d models.WorkDay) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -652,53 +658,53 @@ func newBookingComponent(d models.WorkDay) templ.Component {
templ_7745c5c3_Var30 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, ">Gehen")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -727,59 +733,59 @@ func bookingComponent(booking models.Booking) templ.Component {
templ_7745c5c3_Var33 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var34 string
templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(booking.Timestamp.Format("15:04"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 175, Col: 97}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 177, Col: 97}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "\" class=\"text-neutral-700 group-[.edit]:inline hidden bg-neutral-100 text-sm border border-neutral-200 rounded-md px-3 py-2 transition duration-300 ease focus:outline-none focus:border-neutral-400 hover:border-neutral-300\"> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var37 string
templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(booking.GetBookingType())
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 177, Col: 29}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 179, Col: 29}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -808,7 +814,7 @@ func LegendComponent() templ.Component {
templ_7745c5c3_Var38 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "Arbeitszeit unter regulär ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "Arbeitszeit unter regulär ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
From 12ed9959cb2ba08c825e32827c4fdd64d10e2c95 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=20Tr=C3=B6ger?=
Date: Fri, 5 Sep 2025 22:24:42 +0200
Subject: [PATCH 2/7] added helper function, and fixed #28
---
Backend/helper/time.go | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Backend/helper/time.go b/Backend/helper/time.go
index 643072e..0bd5551 100644
--- a/Backend/helper/time.go
+++ b/Backend/helper/time.go
@@ -20,6 +20,11 @@ func IsWeekend(ts time.Time) bool {
return ts.Weekday() == time.Saturday || ts.Weekday() == time.Sunday
}
+func GetKW(t time.Time) int {
+ _, kw := t.ISOWeek()
+ return kw
+}
+
// Converts duration to string
func FormatDuration(d time.Duration) string {
hours := int(d.Abs().Hours())
From 2eab5983486c72b1855e6fe807ccbfe95f75da0d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=20Tr=C3=B6ger?=
Date: Mon, 8 Sep 2025 00:32:29 +0200
Subject: [PATCH 3/7] working on printable PDF Forms
---
Backend/endpoints/pdf.go | 29 +++++
Backend/endpoints/team.go | 2 +-
Backend/endpoints/team_presence.go | 2 +-
Backend/endpoints/time.go | 6 +-
Backend/helper/strings.go | 9 ++
Backend/main.go | 1 +
Backend/models/user.go | 2 +-
Backend/models/workDay.go | 4 +-
Backend/models/workWeek.go | 2 +-
Backend/static/css/styles.css | 49 +++++---
Backend/templates/pdf.templ | 46 ++++++++
Backend/templates/pdf_templ.go | 175 +++++++++++++++++++++++++++++
12 files changed, 305 insertions(+), 22 deletions(-)
create mode 100644 Backend/endpoints/pdf.go
create mode 100644 Backend/helper/strings.go
create mode 100644 Backend/templates/pdf.templ
create mode 100644 Backend/templates/pdf_templ.go
diff --git a/Backend/endpoints/pdf.go b/Backend/endpoints/pdf.go
new file mode 100644
index 0000000..0e47fcd
--- /dev/null
+++ b/Backend/endpoints/pdf.go
@@ -0,0 +1,29 @@
+package endpoints
+
+import (
+ "arbeitszeitmessung/helper"
+ "arbeitszeitmessung/models"
+ "arbeitszeitmessung/templates"
+ "log"
+ "net/http"
+ "time"
+)
+
+func PDFHandler(w http.ResponseWriter, r *http.Request) {
+ helper.RequiresLogin(Session, w, r)
+ startDate, err := time.Parse("2006-01-02", "2025-08-01")
+ if err != nil {
+ log.Println("Error")
+ }
+ endDate := startDate.AddDate(0, 1, -1)
+
+ user, err := models.GetUserFromSession(Session, r.Context())
+ if err != nil {
+ log.Println("Error getting user!")
+ }
+
+ weeks := models.GetWorkDays(user.CardUID, startDate, endDate)
+
+ 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/team.go b/Backend/endpoints/team.go
index 33c5569..397d45a 100644
--- a/Backend/endpoints/team.go
+++ b/Backend/endpoints/team.go
@@ -56,7 +56,7 @@ func submitReport(w http.ResponseWriter, r *http.Request) {
}
func showWeeks(w http.ResponseWriter, r *http.Request) {
- user, err := (*models.User).GetUserFromSession(nil, Session, r.Context())
+ user, err := models.GetUserFromSession(Session, r.Context())
if err != nil {
log.Println("No user found with the given personal number!")
http.Redirect(w, r, "/user/login", http.StatusSeeOther)
diff --git a/Backend/endpoints/team_presence.go b/Backend/endpoints/team_presence.go
index b313627..e4ea775 100644
--- a/Backend/endpoints/team_presence.go
+++ b/Backend/endpoints/team_presence.go
@@ -23,7 +23,7 @@ func TeamPresenceHandler(w http.ResponseWriter, r *http.Request) {
}
func teamPresence(w http.ResponseWriter, r *http.Request) {
- user, err := (*models.User).GetUserFromSession(nil, Session, r.Context())
+ user, err := models.GetUserFromSession(Session, r.Context())
if err != nil {
log.Println("Error getting user!", err)
}
diff --git a/Backend/endpoints/time.go b/Backend/endpoints/time.go
index ac930e7..93b2b74 100644
--- a/Backend/endpoints/time.go
+++ b/Backend/endpoints/time.go
@@ -44,7 +44,7 @@ func parseTimestamp(r *http.Request, getKey string, fallback string) (time.Time,
// Returns bookings from DB with similar card uid -> checks for card uid in http query params
func getBookings(w http.ResponseWriter, r *http.Request) {
- user, err := (*models.User).GetUserFromSession(nil, Session, r.Context())
+ user, err := models.GetUserFromSession(Session, r.Context())
if err != nil {
log.Println("No user found with the given personal number!")
http.Redirect(w, r, "/user/login", http.StatusSeeOther)
@@ -66,7 +66,7 @@ func getBookings(w http.ResponseWriter, r *http.Request) {
}
tsTo = tsTo.AddDate(0, 0, 1) // so that today is inside
- workDays := (*models.WorkDay).GetWorkDays(nil, user.CardUID, tsFrom, tsTo)
+ workDays := models.GetWorkDays(user.CardUID, tsFrom, tsTo)
sort.Slice(workDays, func(i, j int) bool {
return workDays[i].Day.After(workDays[j].Day)
})
@@ -104,7 +104,7 @@ func updateBooking(w http.ResponseWriter, r *http.Request) {
log.Println("Error loading location", err)
loc = time.Local
}
- user, err := (*models.User).GetUserFromSession(nil, Session, r.Context())
+ user, err := models.GetUserFromSession(Session, r.Context())
if err != nil {
log.Println("No user found!", err)
return
diff --git a/Backend/helper/strings.go b/Backend/helper/strings.go
new file mode 100644
index 0000000..4a15702
--- /dev/null
+++ b/Backend/helper/strings.go
@@ -0,0 +1,9 @@
+package helper
+
+func GetFirst[T, U any](val T, _ U) T {
+ return val
+}
+
+func GetSecond[T, U any](_ T, val U) U {
+ return val
+}
diff --git a/Backend/main.go b/Backend/main.go
index 272eb6f..98a5e22 100644
--- a/Backend/main.go
+++ b/Backend/main.go
@@ -50,6 +50,7 @@ func main() {
// server.HandleFunc("/user/settings", endpoints.UserSettingsHandler)
server.HandleFunc("/team", endpoints.TeamHandler)
server.HandleFunc("/team/presence", endpoints.TeamPresenceHandler)
+ server.HandleFunc("/pdf", endpoints.PDFHandler)
server.Handle("/", http.RedirectHandler("/time", http.StatusPermanentRedirect))
server.Handle("/static/", http.StripPrefix("/static/", fs))
diff --git a/Backend/models/user.go b/Backend/models/user.go
index 6e82c70..016d683 100644
--- a/Backend/models/user.go
+++ b/Backend/models/user.go
@@ -22,7 +22,7 @@ type User struct {
Overtime time.Duration
}
-func (u *User) GetUserFromSession(Session *scs.SessionManager, ctx context.Context) (User, error) {
+func GetUserFromSession(Session *scs.SessionManager, ctx context.Context) (User, error) {
var user User
var err error
if helper.GetEnv("GO_ENV", "production") == "debug" {
diff --git a/Backend/models/workDay.go b/Backend/models/workDay.go
index 54f23b8..31da794 100644
--- a/Backend/models/workDay.go
+++ b/Backend/models/workDay.go
@@ -19,7 +19,7 @@ type WorkDay struct {
Absence Absence
}
-func (d *WorkDay) GetWorkDays(card_uid string, tsFrom, tsTo time.Time) []WorkDay {
+func GetWorkDays(card_uid string, tsFrom, tsTo time.Time) []WorkDay {
var workDays []WorkDay
var workSec, pauseSec float64
@@ -181,7 +181,7 @@ func (d *WorkDay) getWorkTime() {
d.calcPauseTime()
}
-func (d *WorkDay) GetWorkTimeString() (string, string) {
+func (d *WorkDay) GetWorkTimeString() (work string, pause string) {
workString := helper.FormatDuration(d.workTime)
pauseString := helper.FormatDuration(d.pauseTime)
return workString, pauseString
diff --git a/Backend/models/workWeek.go b/Backend/models/workWeek.go
index 12c7a78..cb473d2 100644
--- a/Backend/models/workWeek.go
+++ b/Backend/models/workWeek.go
@@ -45,7 +45,7 @@ func NewWorkWeek(user User, tsMonday time.Time, populate bool) WorkWeek {
}
func (w *WorkWeek) PopulateWithBookings(worktime time.Duration, overtime time.Duration) {
- w.WorkDays = (*WorkDay).GetWorkDays(nil, w.User.CardUID, w.WeekStart, w.WeekStart.Add(7*24*time.Hour))
+ w.WorkDays = GetWorkDays(w.User.CardUID, w.WeekStart, w.WeekStart.Add(7*24*time.Hour))
if absences, err := GetAbsencesByCardUID(w.User.CardUID, w.WeekStart, w.WeekStart.Add(7*24*time.Hour)); err == nil {
w.Absences = absences
} else {
diff --git a/Backend/static/css/styles.css b/Backend/static/css/styles.css
index de26b86..97a4852 100644
--- a/Backend/static/css/styles.css
+++ b/Backend/static/css/styles.css
@@ -189,6 +189,9 @@
.\@container {
container-type: inline-size;
}
+ .relative {
+ position: relative;
+ }
.col-span-2 {
grid-column: span 2 / span 2;
}
@@ -364,6 +367,30 @@
.grid-cols-5 {
grid-template-columns: repeat(5, minmax(0, 1fr));
}
+ .grid-cols-6 {
+ grid-template-columns: repeat(6, minmax(0, 1fr));
+ }
+ .grid-cols-7 {
+ grid-template-columns: repeat(7, minmax(0, 1fr));
+ }
+ .grid-cols-\[1fr\] {
+ grid-template-columns: 1fr;
+ }
+ .grid-cols-\[1fr_1fr\] {
+ grid-template-columns: 1fr 1fr;
+ }
+ .grid-cols-\[1fr_1fr_1fr_1fr_1fr_1fr\] {
+ grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
+ }
+ .grid-cols-\[auto_1fr_1fr_1fr_1fr_1fr\] {
+ grid-template-columns: auto 1fr 1fr 1fr 1fr 1fr;
+ }
+ .grid-cols-\[auto_1fr_1fr_1fr_1fr_1fr_1fr\] {
+ grid-template-columns: auto 1fr 1fr 1fr 1fr 1fr 1fr;
+ }
+ .grid-rows-6 {
+ grid-template-rows: repeat(6, minmax(0, 1fr));
+ }
.flex-col {
flex-direction: column;
}
@@ -427,10 +454,6 @@
border-style: var(--tw-border-style);
border-width: 1px;
}
- .border-0 {
- border-style: var(--tw-border-style);
- border-width: 0px;
- }
.border-neutral-200 {
border-color: var(--color-neutral-200);
}
@@ -452,9 +475,6 @@
.bg-neutral-400 {
background-color: var(--color-neutral-400);
}
- .bg-neutral-700 {
- background-color: var(--color-neutral-700);
- }
.bg-orange-500 {
background-color: var(--color-orange-500);
}
@@ -473,6 +493,15 @@
.p-2 {
padding: calc(var(--spacing) * 2);
}
+ .p-4 {
+ padding: calc(var(--spacing) * 4);
+ }
+ .p-8 {
+ padding: calc(var(--spacing) * 8);
+ }
+ .px-2 {
+ padding-inline: calc(var(--spacing) * 2);
+ }
.px-3 {
padding-inline: calc(var(--spacing) * 3);
}
@@ -699,12 +728,6 @@
}
}
}
- .max-md\:border-0 {
- @media (width < 48rem) {
- border-style: var(--tw-border-style);
- border-width: 0px;
- }
- }
.max-md\:border-b-1 {
@media (width < 48rem) {
border-bottom-style: var(--tw-border-style);
diff --git a/Backend/templates/pdf.templ b/Backend/templates/pdf.templ
new file mode 100644
index 0000000..2e87875
--- /dev/null
+++ b/Backend/templates/pdf.templ
@@ -0,0 +1,46 @@
+package templates
+
+import (
+ "arbeitszeitmessung/helper"
+ "arbeitszeitmessung/models"
+ "time"
+)
+
+templ PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Time, tsEnd time.Time) {
+ {{
+ _, kw := tsStart.ISOWeek()
+ }}
+ @Base()
+
+
+
Kim Mustermensch
+
Zeitraum: { tsStart.Format("02.01.2006") } - { tsEnd.Format("02.01.2006") }
+
Arbeitszeit:
+
Überstunden:
+
+
+
KW
+
Montag
+
Dienstag
+
Mittwoche
+
Donnerstag
+
Freitag
+ //
Samstag
+
{ kw }
+ for d := time.Monday; d < tsStart.Weekday(); d++ {
+
+ }
+ for _, day := range workDays {
+ if day.Day.Weekday() == time.Monday {
+
{ helper.GetKW(day.Day) }
+ }
+
+
{ helper.GetFirst(day.GetWorkTimeString()) }
+ for i := 0; i < len(day.Bookings); i += 2 {
+
{ day.Bookings[i].Timestamp.Format("15:04") } - { day.Bookings[i+1].Timestamp.Format("15:04") }
+ }
+
+ }
+
+
+}
diff --git a/Backend/templates/pdf_templ.go b/Backend/templates/pdf_templ.go
new file mode 100644
index 0000000..3ebeaa7
--- /dev/null
+++ b/Backend/templates/pdf_templ.go
@@ -0,0 +1,175 @@
+// Code generated by templ - DO NOT EDIT.
+
+// templ: version: v0.3.924
+package templates
+
+//lint:file-ignore SA4006 This context is only used if a nested component is present.
+
+import "github.com/a-h/templ"
+import templruntime "github.com/a-h/templ/runtime"
+
+import (
+ "arbeitszeitmessung/helper"
+ "arbeitszeitmessung/models"
+ "time"
+)
+
+func PDFReportEmploye(e models.User, workDays []models.WorkDay, 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 {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var1 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var1 == nil {
+ templ_7745c5c3_Var1 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+
+ _, kw := tsStart.ISOWeek()
+ templ_7745c5c3_Err = Base().Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "Kim Mustermensch
Zeitraum: ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var2 string
+ templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(tsStart.Format("02.01.2006"))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 17, Col: 52}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " - ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var3 string
+ templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(tsEnd.Format("02.01.2006"))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 17, Col: 98}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
Arbeitszeit:
Überstunden:
KW
Montag
Dienstag
Mittwoche
Donnerstag
Freitag
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var4 string
+ templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(kw)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 29, Col: 10}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ for d := time.Monday; d < tsStart.Weekday(); d++ {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ for _, day := range workDays {
+ if day.Day.Weekday() == time.Monday {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var5 string
+ templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(helper.GetKW(day.Day))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 35, Col: 31}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var6 string
+ templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(helper.GetFirst(day.GetWorkTimeString()))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 38, Col: 50}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ for i := 0; i < len(day.Bookings); i += 2 {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var7 string
+ templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(day.Bookings[i].Timestamp.Format("15:04"))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 40, Col: 52}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
+ 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_Var8 string
+ templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(day.Bookings[i+1].Timestamp.Format("15:04"))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 40, Col: 102}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
+ 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
+ }
+ }
+ 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
+ }
+ return nil
+ })
+}
+
+var _ = templruntime.GeneratedTemplate
From 133e73a55cd93c57c05272747a37df2ebc094c32 Mon Sep 17 00:00:00 2001
From: tom
Date: Tue, 9 Sep 2025 11:07:14 +0200
Subject: [PATCH 4/7] working on pdf export
---
.gitea/workflows/build-deploy.yaml | 39 ------
.gitea/workflows/build_tags.yaml | 77 +++++++++++
.../{tests/go-test.yaml => go_test.yaml} | 5 +-
Backend/Dockerfile | 1 +
Backend/go.mod | 2 +-
Backend/models/absence.go | 1 -
Backend/models/booking.go | 8 +-
Backend/models/workDay.go | 122 ++++++++++--------
Backend/static/css/styles.css | 30 ++---
Backend/templates/headerComponent_templ.go | 2 +-
Backend/templates/pages_templ.go | 2 +-
Backend/templates/pdf.templ | 44 ++++---
Backend/templates/pdf_templ.go | 118 +++++++++++------
Backend/templates/teamComponents_templ.go | 2 +-
Backend/templates/timeComponents_templ.go | 2 +-
DB/initdb/02_sample_data.sql | 4 +-
db.sql | 8 +-
package-lock.json | 19 ++-
package.json | 3 +-
19 files changed, 296 insertions(+), 193 deletions(-)
delete mode 100644 .gitea/workflows/build-deploy.yaml
create mode 100644 .gitea/workflows/build_tags.yaml
rename .gitea/workflows/{tests/go-test.yaml => go_test.yaml} (96%)
diff --git a/.gitea/workflows/build-deploy.yaml b/.gitea/workflows/build-deploy.yaml
deleted file mode 100644
index 87ac133..0000000
--- a/.gitea/workflows/build-deploy.yaml
+++ /dev/null
@@ -1,39 +0,0 @@
-name: Arbeitszeitmessung Deploy
-run-name: ${{ gitea.actor }} is building and deploying arbeitszeitmesssung
-on:
- workflow_run:
- workflows: ["Tests"]
- types:
- - completed
-
-jobs:
- build:
- name: Build Go Image and Upload
- if: |
- github.event.workflow_run.conclusion == 'success' &&
- github.event.workflow_run.event == 'push' &&
- startsWith(github.event.workflow_run.head_branch, 'main') &&
- startsWith(github.event.workflow_run.head_commit.ref, 'refs/tags/')
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - name: Login to GitHub Container Registry
- uses: docker/login-action@v3
- with:
- registry: git.letsstein.de
- username: ${{ gitea.actor }}
- password: ${{ secrets.REGISTRY_TOKEN }}
- - name: Set up QEMU
- uses: docker/setup-qemu-action@v3
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
- - name: Build and push
- uses: docker/build-push-action@v6
- with:
- platforms: linux/amd64,linux/arm64
- push: true
- context: Backend
- tags: |
- git.letsstein.de/tom/arbeitszeitmessung:latest
- git.letsstein.de/tom/arbeitszeitmessung:${{ github.ref_name }}
diff --git a/.gitea/workflows/build_tags.yaml b/.gitea/workflows/build_tags.yaml
new file mode 100644
index 0000000..a73ba14
--- /dev/null
+++ b/.gitea/workflows/build_tags.yaml
@@ -0,0 +1,77 @@
+name: Arbeitszeitmessung Deploy
+run-name: ${{ gitea.actor }} is building and deploying arbeitszeitmesssung
+on:
+ push:
+ tags:
+ - "*"
+
+jobs:
+ testing:
+ name: Run Go Tests
+ runs-on: ubuntu-latest
+ services:
+ postgres:
+ image: postgres:16
+ env:
+ POSTGRES_USER: root
+ POSTGRES_PASSWORD: password
+ POSTGRES_DB: arbeitszeitmessung
+ env:
+ POSTGRES_HOST: postgres
+ POSTGRES_USER: root
+ POSTGRES_PASSWORD: password
+ POSTGRES_DB: arbeitszeitmessung
+ POSTGRES_PORT: 5432
+ RUNNER_TOOL_CACHE: /toolcache # Runner Tool Cache
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup go
+ uses: actions/setup-go@v5
+ with:
+ go-version-file: Backend/go.mod
+ - uses: https://gitea.com/actions/go-hashfiles@v0.0.1
+ id: hash-go
+ with:
+ patterns: |
+ go.mod
+ go.sum
+ - name: cache go
+ id: cache-go
+ uses: actions/cache@v4
+ with:
+ path: |-
+ /go_path
+ /go_cache
+ key: arbeitszeitmessung-${{ steps.hash-go.outputs.hash }}
+ restore-keys: |-
+ arbeitszeitmessung-
+ - name: Run Go Tests
+ run: cd Backend && go test ./...
+ build:
+ name: Build Go Image and Upload
+ runs-on: ubuntu-latest
+ needs: [testing]
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: Login to GitHub Container Registry
+ uses: docker/login-action@v3
+ with:
+ registry: git.letsstein.de
+ username: ${{ gitea.actor }}
+ password: ${{ secrets.REGISTRY_TOKEN }}
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v3
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+ - name: Build and push
+ uses: docker/build-push-action@v6
+ with:
+ platforms: linux/amd64,linux/arm64
+ push: true
+ context: Backend
+ tags: |
+ git.letsstein.de/tom/arbeitszeitmessung:latest
+ git.letsstein.de/tom/arbeitszeitmessung:${{ github.ref_name }}
diff --git a/.gitea/workflows/tests/go-test.yaml b/.gitea/workflows/go_test.yaml
similarity index 96%
rename from .gitea/workflows/tests/go-test.yaml
rename to .gitea/workflows/go_test.yaml
index 654faa2..c36d1e4 100644
--- a/.gitea/workflows/tests/go-test.yaml
+++ b/.gitea/workflows/go_test.yaml
@@ -1,6 +1,9 @@
name: Tests
run-name: ${{ gitea.actor }} is testing golang Code
-on: push
+on:
+ push:
+ tags-ignore:
+ - "*"
jobs:
testing:
diff --git a/Backend/Dockerfile b/Backend/Dockerfile
index 098f454..c9ef35d 100644
--- a/Backend/Dockerfile
+++ b/Backend/Dockerfile
@@ -14,6 +14,7 @@ COPY . .
RUN go build -o server .
FROM alpine
+RUN apk add --no-cache tzdata
WORKDIR /app
COPY --from=build /app/server /app/server
diff --git a/Backend/go.mod b/Backend/go.mod
index d5c6953..2472dc8 100644
--- a/Backend/go.mod
+++ b/Backend/go.mod
@@ -1,6 +1,6 @@
module arbeitszeitmessung
-go 1.24.5
+go 1.24.7
require github.com/lib/pq v1.10.9
diff --git a/Backend/models/absence.go b/Backend/models/absence.go
index c5184d0..bda305e 100644
--- a/Backend/models/absence.go
+++ b/Backend/models/absence.go
@@ -17,7 +17,6 @@ type Absence struct {
CardUID string
AbwesenheitTyp AbsenceType
Datum time.Time
- // Comment string
}
func NewAbsence(card_uid string, abwesenheit_typ int, datum time.Time) (Absence, error) {
diff --git a/Backend/models/booking.go b/Backend/models/booking.go
index 8b1140e..ba758f8 100644
--- a/Backend/models/booking.go
+++ b/Backend/models/booking.go
@@ -15,8 +15,8 @@ import (
type SameBookingError struct{}
type BookingType struct {
- Id int8
- Name string
+ Id int8 `json:"anwesenheit_id"`
+ Name string `json:"anwesenheit_name"`
}
func (e SameBookingError) Error() string {
@@ -29,7 +29,7 @@ type Booking struct {
CheckInOut int16 `json:"check_in_out"`
Timestamp time.Time `json:"timestamp"`
CounterId int `json:"counter_id"`
- BookingType BookingType `json:"booking_type"`
+ BookingType BookingType `json:"anwesenheit_typ"`
}
type IDatabase interface {
@@ -298,7 +298,7 @@ func (b *Booking) UpdateTime(newTime time.Time) {
}
func (b *Booking) ToString() string {
- return fmt.Sprintf("Booking %d: at: %s, as type: %d", b.CounterId, b.Timestamp.Format("15:04"), b.CheckInOut)
+ return fmt.Sprintf("Booking %d: at: %s, CheckInOut: %d, TypeId: %d", b.CounterId, b.Timestamp.Format("15:04"), b.CheckInOut, b.BookingType.Id)
}
func GetBookingTypes() ([]BookingType, error) {
diff --git a/Backend/models/workDay.go b/Backend/models/workDay.go
index 31da794..cf8df46 100644
--- a/Backend/models/workDay.go
+++ b/Backend/models/workDay.go
@@ -24,64 +24,72 @@ func GetWorkDays(card_uid string, tsFrom, tsTo time.Time) []WorkDay {
var workSec, pauseSec float64
qStr, err := DB.Prepare(`
- WITH all_days AS (
- SELECT generate_series($2::DATE, $3::DATE - INTERVAL '1 day', INTERVAL '1 day')::DATE AS work_date
- ),
- ordered_bookings AS (
- SELECT
- timestamp::DATE AS work_date,
- timestamp,
- check_in_out,
- counter_id,
- LAG(timestamp) OVER (PARTITION BY card_uid, timestamp::DATE ORDER BY timestamp) AS prev_timestamp,
- LAG(check_in_out) OVER (PARTITION BY card_uid, timestamp::DATE ORDER BY timestamp) AS prev_check
- FROM anwesenheit
- WHERE card_uid = $1
- AND timestamp::DATE >= $2
- AND timestamp::DATE <= $3
- ),
- abwesenheiten AS (
- SELECT
- datum::DATE AS work_date,
- abwesenheit_typ
- FROM abwesenheit
- WHERE card_uid = $1
- AND datum::DATE >= $2
- AND datum::DATE <= $3
- )
+ WITH all_days AS (
+ SELECT generate_series($2::DATE, $3::DATE - INTERVAL '1 day', INTERVAL '1 day')::DATE AS work_date
+),
+ordered_bookings AS (
SELECT
- d.work_date,
- COALESCE(MIN(b.timestamp), NOW()) AS time_from,
- COALESCE(MAX(b.timestamp), NOW()) AS time_to,
- COALESCE(
- EXTRACT(EPOCH FROM SUM(
- CASE
- WHEN b.prev_check IN (1, 3) AND b.check_in_out IN (2, 4, 254)
- THEN b.timestamp - b.prev_timestamp
- ELSE INTERVAL '0'
- END
- )), 0
- ) AS total_work_seconds,
- COALESCE(
- EXTRACT(EPOCH FROM SUM(
- CASE
- WHEN b.prev_check IN (2, 4, 254) AND b.check_in_out IN (1, 3)
- THEN b.timestamp - b.prev_timestamp
- ELSE INTERVAL '0'
- END
- )), 0
- ) AS total_pause_seconds,
- COALESCE(jsonb_agg(jsonb_build_object(
- 'check_in_out', b.check_in_out,
- 'timestamp', b.timestamp,
- 'counter_id', b.counter_id
- ) ORDER BY b.timestamp), '[]'::jsonb) AS bookings,
- a.abwesenheit_typ
- FROM all_days d
- LEFT JOIN ordered_bookings b ON d.work_date = b.work_date
- LEFT JOIN abwesenheiten a ON d.work_date = a.work_date
- GROUP BY d.work_date, a.abwesenheit_typ
- ORDER BY d.work_date ASC;`)
+ a.timestamp::DATE AS work_date,
+ a.timestamp,
+ a.check_in_out,
+ a.counter_id,
+ a.anwesenheit_typ,
+ sat.anwesenheit_name AS anwesenheit_typ_name,
+ LAG(a.timestamp) OVER (PARTITION BY a.card_uid, a.timestamp::DATE ORDER BY a.timestamp) AS prev_timestamp,
+ LAG(a.check_in_out) OVER (PARTITION BY a.card_uid, a.timestamp::DATE ORDER BY a.timestamp) AS prev_check
+ FROM anwesenheit a
+ LEFT JOIN s_anwesenheit_typen sat ON a.anwesenheit_typ = sat.anwesenheit_id
+ WHERE a.card_uid = $1
+ AND a.timestamp::DATE >= $2
+ AND a.timestamp::DATE <= $3
+),
+abwesenheiten AS (
+ SELECT
+ datum::DATE AS work_date,
+ abwesenheit_typ
+ FROM abwesenheit
+ WHERE card_uid = $1
+ AND datum::DATE >= $2
+ AND datum::DATE <= $3
+)
+SELECT
+ d.work_date,
+ COALESCE(MIN(b.timestamp), NOW()) AS time_from,
+ COALESCE(MAX(b.timestamp), NOW()) AS time_to,
+ COALESCE(
+ EXTRACT(EPOCH FROM SUM(
+ CASE
+ WHEN b.prev_check IN (1, 3) AND b.check_in_out IN (2, 4, 254)
+ THEN b.timestamp - b.prev_timestamp
+ ELSE INTERVAL '0'
+ END
+ )), 0
+ ) AS total_work_seconds,
+ COALESCE(
+ EXTRACT(EPOCH FROM SUM(
+ CASE
+ WHEN b.prev_check IN (2, 4, 254) AND b.check_in_out IN (1, 3)
+ THEN b.timestamp - b.prev_timestamp
+ ELSE INTERVAL '0'
+ END
+ )), 0
+ ) AS total_pause_seconds,
+ COALESCE(jsonb_agg(jsonb_build_object(
+ 'check_in_out', b.check_in_out,
+ 'timestamp', b.timestamp,
+ 'counter_id', b.counter_id,
+ 'anwesenheit_typ', b.anwesenheit_typ,
+ 'anwesenheit_typ', jsonb_build_object(
+ 'anwesenheit_id', b.anwesenheit_typ,
+ 'anwesenheit_name', b.anwesenheit_typ_name
+ )
+ ) ORDER BY b.timestamp), '[]'::jsonb) AS bookings,
+ a.abwesenheit_typ
+FROM all_days d
+LEFT JOIN ordered_bookings b ON d.work_date = b.work_date
+LEFT JOIN abwesenheiten a ON d.work_date = a.work_date
+GROUP BY d.work_date, a.abwesenheit_typ
+ORDER BY d.work_date ASC;`)
if err != nil {
log.Println("Error preparing SQL statement", err)
diff --git a/Backend/static/css/styles.css b/Backend/static/css/styles.css
index 97a4852..93e47a6 100644
--- a/Backend/static/css/styles.css
+++ b/Backend/static/css/styles.css
@@ -198,6 +198,12 @@
.col-span-3 {
grid-column: span 3 / span 3;
}
+ .col-span-6 {
+ grid-column: span 6 / span 6;
+ }
+ .col-span-7 {
+ grid-column: span 7 / span 7;
+ }
.col-span-full {
grid-column: 1 / -1;
}
@@ -367,27 +373,15 @@
.grid-cols-5 {
grid-template-columns: repeat(5, minmax(0, 1fr));
}
- .grid-cols-6 {
- grid-template-columns: repeat(6, minmax(0, 1fr));
- }
- .grid-cols-7 {
- grid-template-columns: repeat(7, minmax(0, 1fr));
- }
- .grid-cols-\[1fr\] {
- grid-template-columns: 1fr;
- }
- .grid-cols-\[1fr_1fr\] {
- grid-template-columns: 1fr 1fr;
- }
- .grid-cols-\[1fr_1fr_1fr_1fr_1fr_1fr\] {
- grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
- }
.grid-cols-\[auto_1fr_1fr_1fr_1fr_1fr\] {
grid-template-columns: auto 1fr 1fr 1fr 1fr 1fr;
}
.grid-cols-\[auto_1fr_1fr_1fr_1fr_1fr_1fr\] {
grid-template-columns: auto 1fr 1fr 1fr 1fr 1fr 1fr;
}
+ .grid-cols-subgrid {
+ grid-template-columns: subgrid;
+ }
.grid-rows-6 {
grid-template-rows: repeat(6, minmax(0, 1fr));
}
@@ -487,15 +481,15 @@
.mask-repeat {
mask-repeat: repeat;
}
+ .p-0 {
+ padding: calc(var(--spacing) * 0);
+ }
.p-1 {
padding: calc(var(--spacing) * 1);
}
.p-2 {
padding: calc(var(--spacing) * 2);
}
- .p-4 {
- padding: calc(var(--spacing) * 4);
- }
.p-8 {
padding: calc(var(--spacing) * 8);
}
diff --git a/Backend/templates/headerComponent_templ.go b/Backend/templates/headerComponent_templ.go
index aeef6ec..44846c8 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.924
+// templ: version: v0.3.833
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 b7915ec..c0d73e3 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.924
+// templ: version: v0.3.833
package templates
//lint:file-ignore SA4006 This context is only used if a nested component is present.
diff --git a/Backend/templates/pdf.templ b/Backend/templates/pdf.templ
index 2e87875..2aacb05 100644
--- a/Backend/templates/pdf.templ
+++ b/Backend/templates/pdf.templ
@@ -1,8 +1,8 @@
package templates
import (
- "arbeitszeitmessung/helper"
"arbeitszeitmessung/models"
+ "arbeitszeitmessung/helper"
"time"
)
@@ -18,29 +18,33 @@ templ PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Ti
Arbeitszeit:
Überstunden:
-
-
KW
-
Montag
-
Dienstag
-
Mittwoche
-
Donnerstag
-
Freitag
- //
Samstag
-
{ kw }
- for d := time.Monday; d < tsStart.Weekday(); d++ {
-
- }
- for _, day := range workDays {
+
+
{ kw }
+
Kommen
+
Gehen
+
Arbeitsart
+
Stunden gesamt
+
Pause
+
Überstunden
+ for _, day := range workDays{
if day.Day.Weekday() == time.Monday {
-
{ helper.GetKW(day.Day) }
+
Wochenende
+ }
+
{ day.Day.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 }
}
-
-
{ helper.GetFirst(day.GetWorkTimeString()) }
- for i := 0; i < len(day.Bookings); i += 2 {
-
{ day.Bookings[i].Timestamp.Format("15:04") } - { day.Bookings[i+1].Timestamp.Format("15:04") }
- }
+ {{ work, pause := day.GetWorkTimeString() }}
+
{ work }
+
{ pause }
+
{ helper.FormatDuration(day.CalcOvertime(e)) }
}
+
}
diff --git a/Backend/templates/pdf_templ.go b/Backend/templates/pdf_templ.go
index 3ebeaa7..5430b0f 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.924
+// templ: version: v0.3.833
package templates
//lint:file-ignore SA4006 This context is only used if a nested component is present.
@@ -67,104 +67,142 @@ 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, 3, "
Arbeitszeit:
Überstunden:
KW
Montag
Dienstag
Mittwoche
Donnerstag
Freitag
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
Arbeitszeit:
Überstunden:
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(kw)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 29, Col: 10}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 22, Col: 34}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
Kommen
Gehen
Arbeitsart
Stunden gesamt
Pause
Überstunden
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- for d := time.Monday; d < tsStart.Weekday(); d++ {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- }
for _, day := range workDays {
if day.Day.Weekday() == time.Monday {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var5 string
- templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(helper.GetKW(day.Day))
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 35, Col: 31}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
Wochenende
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var6 string
- templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(helper.GetFirst(day.GetWorkTimeString()))
+ var templ_7745c5c3_Var5 string
+ templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(day.Day.Format("02.01.2006"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 38, Col: 50}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 33, Col: 61}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- for i := 0; i < len(day.Bookings); i += 2 {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
")
+ for bookingI := 0; bookingI < len(day.Bookings); bookingI += 2 {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var6 string
+ templ_7745c5c3_Var6, 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: 37, Col: 82}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var7 string
- templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(day.Bookings[i].Timestamp.Format("15:04"))
+ templ_7745c5c3_Var7, 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: 52}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 38, Col: 84}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " - ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var8 string
- templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(day.Bookings[i+1].Timestamp.Format("15:04"))
+ templ_7745c5c3_Var8, 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: 40, Col: 102}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 39, Col: 73}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "")
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, 12, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ work, pause := day.GetWorkTimeString()
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var9 string
+ templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(work)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 43, Col: 38}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
+ 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(pause)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 44, Col: 39}
+ }
+ _, 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, 15, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var11 string
+ templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(day.CalcOvertime(e)))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 45, Col: 76}
+ }
+ _, 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, 16, "
")
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, 17, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
diff --git a/Backend/templates/teamComponents_templ.go b/Backend/templates/teamComponents_templ.go
index 0fdead7..9dd6ee3 100644
--- a/Backend/templates/teamComponents_templ.go
+++ b/Backend/templates/teamComponents_templ.go
@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
-// templ: version: v0.3.924
+// templ: version: v0.3.833
package templates
//lint:file-ignore SA4006 This context is only used if a nested component is present.
diff --git a/Backend/templates/timeComponents_templ.go b/Backend/templates/timeComponents_templ.go
index 557daaf..aca6f54 100644
--- a/Backend/templates/timeComponents_templ.go
+++ b/Backend/templates/timeComponents_templ.go
@@ -1,6 +1,6 @@
// Code generated by templ - DO NOT EDIT.
-// templ: version: v0.3.924
+// templ: version: v0.3.833
package templates
//lint:file-ignore SA4006 This context is only used if a nested component is present.
diff --git a/DB/initdb/02_sample_data.sql b/DB/initdb/02_sample_data.sql
index 5cf0910..a0ee8f3 100644
--- a/DB/initdb/02_sample_data.sql
+++ b/DB/initdb/02_sample_data.sql
@@ -1,5 +1,5 @@
-INSERT INTO "s_personal_daten" ("personal_nummer", "aktiv_beschaeftigt", "vorname", "nachname", "geburtsdatum", "plz", "adresse", "geschlecht", "card_uid", "hauptbeschaeftigungs_ort", "arbeitszeit_per_tag", "arbeitszeit_min_start", "arbeitszeit_max_ende", "vorgesetzter_pers_nr") VALUES
-(123, 't', 'Kim', 'Mustermensch', '2003-02-01', '08963', 'Altenburger Str. 44A', 1, 'aaaa-aaaa', 1, 8, '07:00:00', '20:00:00', 0);
+INSERT INTO "s_personal_daten" ("personal_nummer", "aktiv_beschaeftigt", "vorname", "nachname", "geburtsdatum", "plz", "adresse", "geschlecht", "card_uid", "hauptbeschaeftigungs_ort", "arbeitszeit_per_tag", "arbeitszeit_per_woche", "arbeitszeit_min_start", "arbeitszeit_max_ende", "vorgesetzter_pers_nr") VALUES
+(123, 't', 'Kim', 'Mustermensch', '2003-02-01', '08963', 'Altenburger Str. 44A', 1, 'aaaa-aaaa', 1, 8, 40, '07:00:00', '20:00:00', 0);
INSERT INTO "user_password" ("personal_nummer", "pass_hash") VALUES
(123, crypt('max_pass', gen_salt('bf')));
diff --git a/db.sql b/db.sql
index 6f4d7fc..4ba7830 100644
--- a/db.sql
+++ b/db.sql
@@ -198,11 +198,11 @@ ORDER BY d.work_date;
WITH params AS (
SELECT
- 'acde-edca'::varchar AS card_uid,
+ 'aaaa-aaaa'::varchar AS card_uid,
101::int AS geraet_id,
14::int AS start_days_ago, -- how many days back to start
0::int AS end_days_ahead, -- how many days forward (0 = today)
- 0.5::float AS pause_probability,
+ 0::float AS pause_probability,
0.2::float AS absence_probability
),
days AS (
@@ -249,8 +249,8 @@ all_bookings AS (
SELECT * FROM pause_bookings
),
ins_anw AS (
- INSERT INTO anwesenheit ("timestamp", card_uid, check_in_out, geraet_id)
- SELECT ts, card_uid, check_in_out, geraet_id
+ INSERT INTO anwesenheit ("timestamp", "card_uid", "check_in_out", "geraet_id", "anwesenheit_typ")
+ SELECT ts, card_uid, check_in_out, geraet_id, 1 as anwesenheit_typ
FROM all_bookings
WHERE ts <= NOW()
ORDER BY work_date, ts
diff --git a/package-lock.json b/package-lock.json
index 7e4924a..479ae0e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,8 @@
},
"devDependencies": {
"@iconify-json/material-symbols-light": "^1.2.33",
- "@iconify/tailwind4": "^1.0.6"
+ "@iconify/tailwind4": "^1.0.6",
+ "prettier": "^3.6.2"
}
},
"node_modules/@antfu/install-pkg": {
@@ -1294,6 +1295,22 @@
"pathe": "^2.0.3"
}
},
+ "node_modules/prettier": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
+ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
"node_modules/quansync": {
"version": "0.2.11",
"resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
diff --git a/package.json b/package.json
index fd0ca1d..7d00931 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,7 @@
},
"devDependencies": {
"@iconify-json/material-symbols-light": "^1.2.33",
- "@iconify/tailwind4": "^1.0.6"
+ "@iconify/tailwind4": "^1.0.6",
+ "prettier": "^3.6.2"
}
}
From 2f72eebf22e1c8eba1573587f63518caab877f6f Mon Sep 17 00:00:00 2001
From: tom
Date: Tue, 9 Sep 2025 11:10:53 +0200
Subject: [PATCH 5/7] updated workflows
---
.gitea/workflows/{build_tags.yaml => build.yaml} | 0
.gitea/workflows/{go_test.yaml => test.yaml} | 0
2 files changed, 0 insertions(+), 0 deletions(-)
rename .gitea/workflows/{build_tags.yaml => build.yaml} (100%)
rename .gitea/workflows/{go_test.yaml => test.yaml} (100%)
diff --git a/.gitea/workflows/build_tags.yaml b/.gitea/workflows/build.yaml
similarity index 100%
rename from .gitea/workflows/build_tags.yaml
rename to .gitea/workflows/build.yaml
diff --git a/.gitea/workflows/go_test.yaml b/.gitea/workflows/test.yaml
similarity index 100%
rename from .gitea/workflows/go_test.yaml
rename to .gitea/workflows/test.yaml
From b30686ca068d0a839a777b1902e54c0152d91253 Mon Sep 17 00:00:00 2001
From: tom
Date: Tue, 9 Sep 2025 11:15:31 +0200
Subject: [PATCH 6/7] Update test.yaml
---
.gitea/workflows/test.yaml | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml
index c36d1e4..08cf542 100644
--- a/.gitea/workflows/test.yaml
+++ b/.gitea/workflows/test.yaml
@@ -1,9 +1,6 @@
name: Tests
run-name: ${{ gitea.actor }} is testing golang Code
-on:
- push:
- tags-ignore:
- - "*"
+on: [push]
jobs:
testing:
From 3d76778d4fb5b6f38d764443f6ee11140dac65bd Mon Sep 17 00:00:00 2001
From: tom
Date: Wed, 10 Sep 2025 09:46:06 +0200
Subject: [PATCH 7/7] Update build.yaml
---
.gitea/workflows/build.yaml | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml
index a73ba14..c32282f 100644
--- a/.gitea/workflows/build.yaml
+++ b/.gitea/workflows/build.yaml
@@ -2,8 +2,7 @@ name: Arbeitszeitmessung Deploy
run-name: ${{ gitea.actor }} is building and deploying arbeitszeitmesssung
on:
push:
- tags:
- - "*"
+ tags: "*"
jobs:
testing: