From f73c2b1a962285092774164b002737758b02db92 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=20Tr=C3=B6ger?=
Date: Fri, 5 Dec 2025 15:03:34 +0100
Subject: [PATCH] tried to add untertags krank
---
.gitea/workflows/build.yaml | 4 +-
Backend/endpoints/pdf-create.go | 19 +-
.../{team_presence.go => team-presence.go} | 0
Backend/endpoints/time.go | 2 +-
Backend/models/absence.go | 8 +-
Backend/models/absence_test.go | 92 ++++
Backend/models/booking_test.go | 12 +-
Backend/models/iworkday.go | 59 +++
Backend/models/user.go | 14 +-
Backend/models/user_test.go | 2 +-
Backend/models/workDay.go | 165 +------
Backend/models/workDay_test.go | 184 +++++---
Backend/models/workWeek.go | 10 +-
Backend/templates/pdf.templ | 129 +++---
Backend/templates/pdf_templ.go | 428 ++++--------------
Backend/templates/teamComponents.templ | 2 +-
Backend/templates/teamComponents_templ.go | 2 +-
Backend/templates/timePage.templ | 3 +-
Backend/templates/timePage_templ.go | 19 +-
DB/initdb/01_schema.sql | 2 +-
DocumentCreator/templates/abrechnung.typ | 5 +-
21 files changed, 508 insertions(+), 653 deletions(-)
rename Backend/endpoints/{team_presence.go => team-presence.go} (100%)
create mode 100644 Backend/models/absence_test.go
create mode 100644 Backend/models/iworkday.go
diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml
index a73ba14..e112b79 100644
--- a/.gitea/workflows/build.yaml
+++ b/.gitea/workflows/build.yaml
@@ -73,5 +73,5 @@ jobs:
push: true
context: Backend
tags: |
- git.letsstein.de/tom/arbeitszeitmessung:latest
- git.letsstein.de/tom/arbeitszeitmessung:${{ github.ref_name }}
+ git.letsstein.de/tom/arbeitszeitmessung-webserver:latest
+ git.letsstein.de/tom/arbeitszeitmessung-webserver:${{ github.ref_name }}
diff --git a/Backend/endpoints/pdf-create.go b/Backend/endpoints/pdf-create.go
index 7d1ae45..b70ea52 100644
--- a/Backend/endpoints/pdf-create.go
+++ b/Backend/endpoints/pdf-create.go
@@ -20,7 +20,7 @@ func convertDaysToTypst(days []models.IWorkDay, u models.User) ([]typstDay, erro
var typstDays []typstDay
for _, day := range days {
var thisTypstDay typstDay
- work, pause, overtime := day.GetTimesReal(u, models.WorktimeBaseWeek)
+ work, pause, overtime := day.GetTimesVirtual(u, models.WorktimeBaseWeek)
thisTypstDay.Date = day.Date().Format(DE_DATE)
thisTypstDay.Worktime = helper.FormatDurationFill(work, true)
thisTypstDay.Pausetime = helper.FormatDurationFill(pause, true)
@@ -45,6 +45,16 @@ func convertDayToTypstDayParts(day models.IWorkDay, user models.User) []typstDay
typstDayPart.IsWorkDay = true
typstDayParts = append(typstDayParts, typstDayPart)
}
+ if day.IsKurzArbeit() {
+ tsFrom, tsTo := workDay.GenerateKurzArbeitBookings(user)
+ typstDayParts = append(typstDayParts, typstDayPart{
+ BookingFrom: tsFrom.Format("15:04"),
+ BookingTo: tsTo.Format("15:04"),
+ WorkType: "Kurzarbeit",
+ IsWorkDay: true,
+ })
+ }
+
} else {
absentDay, _ := day.(*models.Absence)
typstDayParts = append(typstDayParts, typstDayPart{IsWorkDay: false, WorkType: absentDay.AbwesenheitTyp.Name})
@@ -122,7 +132,7 @@ func createEmployeReport(employee models.User, startDate, endDate time.Time) (by
var actualHours time.Duration
for _, day := range workingDays {
- actualHours += day.TimeWorkVirtual(employee)
+ actualHours += day.GetWorktimeVirtual(employee, models.WorktimeBaseDay)
}
worktimeBalance := actualHours - targetHours
@@ -162,8 +172,8 @@ func PDFHandler(w http.ResponseWriter, r *http.Request) {
weeks := models.GetDays(user, startDate, endDate, false)
var aggregatedOvertime, aggregatedWorkTime time.Duration
for _, day := range weeks {
- aggregatedOvertime += day.TimeOvertimeReal(user)
- aggregatedWorkTime += day.TimeWorkVirtual(user)
+ aggregatedOvertime += day.GetOvertimeReal(user, models.WorktimeBaseWeek)
+ aggregatedWorkTime += day.GetWorktimeVirtual(user, models.WorktimeBaseWeek)
}
typstDays, err := convertDaysToTypst(weeks, user)
@@ -193,6 +203,7 @@ type typstMetadata struct {
TimeRange string `json:"time-range"`
EmployeeName string `json:"employee-name"`
WorkTime string `json:"worktime"`
+ Kurzarbeit string `json:"kurzarbeit"`
Overtime string `json:"overtime"`
OvertimeTotal string `json:"overtime-total"`
CurrentTimestamp string `json:"current-timestamp"`
diff --git a/Backend/endpoints/team_presence.go b/Backend/endpoints/team-presence.go
similarity index 100%
rename from Backend/endpoints/team_presence.go
rename to Backend/endpoints/team-presence.go
diff --git a/Backend/endpoints/time.go b/Backend/endpoints/time.go
index d8bb4c3..a3cf760 100644
--- a/Backend/endpoints/time.go
+++ b/Backend/endpoints/time.go
@@ -84,7 +84,7 @@ func getBookings(w http.ResponseWriter, r *http.Request) {
if day.Date().Before(lastSub) {
continue
}
- aggregatedOvertime += day.TimeOvertimeReal(user)
+ aggregatedOvertime += day.GetOvertimeReal(user, models.WorktimeBaseDay)
}
if reportedOvertime, err := user.GetReportedOvertime(); err == nil {
user.Overtime = (reportedOvertime + aggregatedOvertime).Round(time.Minute)
diff --git a/Backend/models/absence.go b/Backend/models/absence.go
index 0f99bbb..493261e 100644
--- a/Backend/models/absence.go
+++ b/Backend/models/absence.go
@@ -50,14 +50,14 @@ func (a *Absence) IsMultiDay() bool {
}
func (a *Absence) GetWorktimeReal(u User, base WorktimeBase) time.Duration {
- if a.AbwesenheitTyp.WorkTime <= 1 {
+ if a.AbwesenheitTyp.WorkTime <= 0 {
return 0
}
switch base {
case WorktimeBaseDay:
- return u.ArbeitszeitProTag()
+ return u.ArbeitszeitProTagFrac(float32(a.AbwesenheitTyp.WorkTime) / 100)
case WorktimeBaseWeek:
- return u.ArbeitszeitProWoche() / 5
+ return u.ArbeitszeitProWocheFrac(0.2 * float32(a.AbwesenheitTyp.WorkTime) / 100)
}
return 0
}
@@ -66,7 +66,7 @@ func (a *Absence) GetPausetimeReal(u User, base WorktimeBase) time.Duration {
}
func (a *Absence) GetOvertimeReal(u User, base WorktimeBase) time.Duration {
- if a.AbwesenheitTyp.WorkTime > 1 {
+ if a.AbwesenheitTyp.WorkTime > 0 {
return 0
}
switch base {
diff --git a/Backend/models/absence_test.go b/Backend/models/absence_test.go
new file mode 100644
index 0000000..7e40dea
--- /dev/null
+++ b/Backend/models/absence_test.go
@@ -0,0 +1,92 @@
+package models_test
+
+import (
+ "arbeitszeitmessung/helper"
+ "arbeitszeitmessung/models"
+ "testing"
+ "time"
+)
+
+var testAbsence = models.Absence{
+ Day: CatchError(time.Parse(time.DateOnly, "2025-01-01")),
+ AbwesenheitTyp: models.AbsenceType{},
+ DateFrom: CatchError(time.Parse(time.DateOnly, "2025-01-01")),
+ DateTo: CatchError(time.Parse(time.DateOnly, "2025-01-03")),
+}
+
+var testKurzarbeit = models.AbsenceType{
+ Name: "Kurzarbeit",
+ WorkTime: -1,
+}
+
+var testUrlaub = models.AbsenceType{
+ Name: "Urlaub",
+ WorkTime: 100,
+}
+
+var testUrlaubUntertags = models.AbsenceType{
+ Name: "Urlaub untertags",
+ WorkTime: 50,
+}
+
+func TestCalcRealWorkTimeDayAbsence(t *testing.T) {
+ testCases := []struct {
+ absenceType models.AbsenceType
+ expectedTime time.Duration
+ }{
+ {
+ absenceType: testUrlaub,
+ expectedTime: time.Hour * 8,
+ },
+ {
+ absenceType: testUrlaubUntertags,
+ expectedTime: time.Hour * 4,
+ },
+ {
+ absenceType: testKurzarbeit,
+ expectedTime: 0,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run("Calc Absence Worktime: "+tc.absenceType.Name, func(t *testing.T) {
+ var testCase = testAbsence
+ testCase.AbwesenheitTyp = tc.absenceType
+ workTime := testCase.GetWorktimeReal(testUser, models.WorktimeBaseDay)
+ if workTime != tc.expectedTime {
+ t.Errorf("Calc Worktime Default not working, time should be %s, but was %s", helper.FormatDurationFill(tc.expectedTime, true), helper.FormatDurationFill(workTime, true))
+ }
+ })
+ }
+}
+
+func TestCalcRealWorkTimeWeekAbsence(t *testing.T) {
+ testCases := []struct {
+ absenceType models.AbsenceType
+ expectedTime time.Duration
+ }{
+ {
+ absenceType: testUrlaub,
+ expectedTime: time.Hour * 7,
+ },
+ {
+ absenceType: testUrlaubUntertags,
+ expectedTime: time.Hour*3 + time.Minute*30,
+ },
+ {
+ absenceType: testKurzarbeit,
+ expectedTime: 0,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run("Calc Absence Worktime: "+tc.absenceType.Name, func(t *testing.T) {
+ var testCase = testAbsence
+ testCase.AbwesenheitTyp = tc.absenceType
+ workTime := testCase.GetWorktimeReal(testUser, models.WorktimeBaseWeek)
+ if workTime != tc.expectedTime {
+ t.Errorf("Calc Worktime Default not working, time should be %s, but was %s", helper.FormatDurationFill(tc.expectedTime, true), helper.FormatDurationFill(workTime, true))
+ }
+ })
+ }
+}
diff --git a/Backend/models/booking_test.go b/Backend/models/booking_test.go
index 032c59e..c5f3e67 100644
--- a/Backend/models/booking_test.go
+++ b/Backend/models/booking_test.go
@@ -10,36 +10,36 @@ var testBookingType = models.BookingType{
Name: "Büro",
}
-var testBookings8hrs = []models.Booking{models.Booking{
+var testBookings8hrs = []models.Booking{{
CardUID: "aaaa-aaaa",
CheckInOut: 1,
Timestamp: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 08:00")),
BookingType: testBookingType,
-}, models.Booking{
+}, {
CardUID: "aaaa-aaaa",
CheckInOut: 2,
Timestamp: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 16:00")),
BookingType: testBookingType,
}}
-var testBookings6hrs = []models.Booking{models.Booking{
+var testBookings6hrs = []models.Booking{{
CardUID: "aaaa-aaaa",
CheckInOut: 1,
Timestamp: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 08:00")),
BookingType: testBookingType,
-}, models.Booking{
+}, {
CardUID: "aaaa-aaaa",
CheckInOut: 2,
Timestamp: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 14:00")),
BookingType: testBookingType,
}}
-var testBookings10hrs = []models.Booking{models.Booking{
+var testBookings10hrs = []models.Booking{{
CardUID: "aaaa-aaaa",
CheckInOut: 1,
Timestamp: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 08:00")),
BookingType: testBookingType,
-}, models.Booking{
+}, {
CardUID: "aaaa-aaaa",
CheckInOut: 2,
Timestamp: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 18:00")),
diff --git a/Backend/models/iworkday.go b/Backend/models/iworkday.go
new file mode 100644
index 0000000..cf0344e
--- /dev/null
+++ b/Backend/models/iworkday.go
@@ -0,0 +1,59 @@
+package models
+
+import (
+ "arbeitszeitmessung/helper"
+ "log"
+ "time"
+)
+
+type IWorkDay interface {
+ Date() time.Time
+ ToString() string
+ IsWorkDay() bool
+ IsKurzArbeit() bool
+ GetDayProgress(User) int8
+ RequiresAction() bool
+ GetWorktimeReal(User, WorktimeBase) time.Duration
+ GetPausetimeReal(User, WorktimeBase) time.Duration
+ GetOvertimeReal(User, WorktimeBase) time.Duration
+ GetWorktimeVirtual(User, WorktimeBase) time.Duration
+ GetPausetimeVirtual(User, WorktimeBase) time.Duration
+ GetOvertimeVirtual(User, WorktimeBase) time.Duration
+ GetTimesReal(User, WorktimeBase) (work, pause, overtime time.Duration)
+ GetTimesVirtual(User, WorktimeBase) (work, pause, overtime time.Duration)
+}
+
+func GetDays(user User, tsFrom, tsTo time.Time, orderedForward bool) []IWorkDay {
+ var allDays map[string]IWorkDay = make(map[string]IWorkDay)
+
+ for _, day := range GetWorkDays(user, tsFrom, tsTo) {
+ allDays[day.Date().Format(time.DateOnly)] = &day
+ }
+ absences, err := GetAbsencesByCardUID(user.CardUID, tsFrom, tsTo)
+ if err != nil {
+ log.Println("Error gettings absences for all Days!", err)
+ return nil
+ }
+ for _, day := range absences {
+ if helper.IsWeekend(day.Date()) {
+ continue
+ }
+ // Absence should be integrated in workday
+ switch {
+ case day.AbwesenheitTyp.WorkTime < 0:
+ if workDay, ok := allDays[day.Date().Format(time.DateOnly)].(*WorkDay); ok {
+ workDay.kurzArbeit = true
+ workDay.kurzArbeitAbsence = day
+ }
+ case day.AbwesenheitTyp.WorkTime < 100:
+ if workDay, ok := allDays[day.Date().Format(time.DateOnly)].(*WorkDay); ok {
+ workDay.worktimeAbsece = day
+ }
+ default:
+ allDays[day.Date().Format(time.DateOnly)] = &day
+ }
+ }
+
+ sortedDays := sortDays(allDays, orderedForward)
+ return sortedDays
+}
diff --git a/Backend/models/user.go b/Backend/models/user.go
index 646a561..8f654e0 100644
--- a/Backend/models/user.go
+++ b/Backend/models/user.go
@@ -113,13 +113,21 @@ func (u *User) GetAll() ([]User, error) {
return users, nil
}
-// Returns the worktime per day rounded to minutes
func (u *User) ArbeitszeitProTag() time.Duration {
- return time.Duration(u.ArbeitszeitPerTag * float32(time.Hour)).Round(time.Minute)
+ return u.ArbeitszeitProTagFrac(1)
+}
+
+// Returns the worktime per day rounded to minutes
+func (u *User) ArbeitszeitProTagFrac(fraction float32) time.Duration {
+ return time.Duration(u.ArbeitszeitPerTag * float32(time.Hour) * fraction).Round(time.Minute)
}
func (u *User) ArbeitszeitProWoche() time.Duration {
- return time.Duration(u.ArbeitszeitPerWoche * float32(time.Hour)).Round(time.Minute)
+ return u.ArbeitszeitProWocheFrac(1)
+}
+
+func (u *User) ArbeitszeitProWocheFrac(fraction float32) time.Duration {
+ return time.Duration(u.ArbeitszeitPerWoche * float32(time.Hour) * fraction).Round(time.Minute)
}
// Returns true if there is a booking 1 for today -> meaning the user is at work
diff --git a/Backend/models/user_test.go b/Backend/models/user_test.go
index c214625..0fe0a71 100644
--- a/Backend/models/user_test.go
+++ b/Backend/models/user_test.go
@@ -6,7 +6,7 @@ import (
"testing"
)
-var testUser models.User = models.User{Vorname: "Kim", Name: "Mustermensch", PersonalNummer: 456, CardUID: "aaaa-aaaa", ArbeitszeitPerTag: 8, ArbeitszeitPerWoche: 40}
+var testUser models.User = models.User{Vorname: "Kim", Name: "Mustermensch", PersonalNummer: 456, CardUID: "aaaa-aaaa", ArbeitszeitPerTag: 8, ArbeitszeitPerWoche: 35}
func SetupUserFixture(t *testing.T, db models.IDatabase) {
t.Helper()
diff --git a/Backend/models/workDay.go b/Backend/models/workDay.go
index b7d3254..adf8895 100644
--- a/Backend/models/workDay.go
+++ b/Backend/models/workDay.go
@@ -10,39 +10,17 @@ import (
"time"
)
-type IWorkDay interface {
- Date() time.Time
- TimeWorkVirtual(User) time.Duration
- 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
- GetDayProgress(User) int8
- RequiresAction() bool
- GetWorktimeReal(User, WorktimeBase) time.Duration
- GetPausetimeReal(User, WorktimeBase) time.Duration
- GetOvertimeReal(User, WorktimeBase) time.Duration
- GetWorktimeVirtual(User, WorktimeBase) time.Duration
- GetPausetimeVirtual(User, WorktimeBase) time.Duration
- GetOvertimeVirtual(User, WorktimeBase) time.Duration
- GetTimesReal(User, WorktimeBase) (work, pause, overtime time.Duration)
- GetTimesVirtual(User, WorktimeBase) (work, pause, overtime time.Duration)
-}
-
type WorkDay struct {
Day time.Time `json:"day"`
Bookings []Booking `json:"bookings"`
workTime time.Duration
pauseTime time.Duration
- realWorkTime time.Duration
- realPauseTime time.Duration
TimeFrom time.Time
TimeTo time.Time
kurzArbeit bool
kurzArbeitAbsence Absence
+ // Urlaub untertags
+ worktimeAbsece Absence
}
type WorktimeBase string
@@ -52,62 +30,39 @@ const (
WorktimeBaseDay WorktimeBase = "day"
)
-func GetDays(user User, tsFrom, tsTo time.Time, orderedForward bool) []IWorkDay {
- var allDays map[string]IWorkDay = make(map[string]IWorkDay)
-
- for _, day := range GetWorkDays(user, tsFrom, tsTo) {
- allDays[day.Date().Format(time.DateOnly)] = &day
- }
- absences, err := GetAbsencesByCardUID(user.CardUID, tsFrom, tsTo)
- if err != nil {
- log.Println("Error gettings absences for all Days!", err)
- return nil
- }
- for _, day := range absences {
- if helper.IsWeekend(day.Date()) {
- continue
- }
- if day.AbwesenheitTyp.WorkTime == 1 {
- if workDay, ok := allDays[day.Date().Format(time.DateOnly)].(*WorkDay); ok && len(workDay.Bookings) > 0 {
- workDay.kurzArbeit = true
- workDay.kurzArbeitAbsence = day
- }
- } else {
- allDays[day.Date().Format(time.DateOnly)] = &day
- }
- }
-
- sortedDays := sortDays(allDays, orderedForward)
- return sortedDays
-}
-
// Gets the time as is in the db (with corrected pause times)
func (d *WorkDay) GetWorktimeReal(u User, base WorktimeBase) time.Duration {
work, pause := calcWorkPause(d.Bookings)
work, pause = correctWorkPause(work, pause)
- return work
+ if (d.worktimeAbsece != Absence{}) {
+ work += d.worktimeAbsece.GetWorktimeReal(u, WorktimeBaseDay)
+ }
+ return work.Round(time.Minute)
}
// Gets the corrected pause times based on db entries
func (d *WorkDay) GetPausetimeReal(u User, base WorktimeBase) time.Duration {
work, pause := calcWorkPause(d.Bookings)
work, pause = correctWorkPause(work, pause)
- return pause
+ return pause.Round(time.Minute)
}
// Returns the overtime based on the db entries
func (d *WorkDay) GetOvertimeReal(u User, base WorktimeBase) time.Duration {
work, pause := calcWorkPause(d.Bookings)
work, pause = correctWorkPause(work, pause)
+ if (d.worktimeAbsece != Absence{}) {
+ work += d.worktimeAbsece.GetWorktimeReal(u, base)
+ }
var targetHours time.Duration
switch base {
case WorktimeBaseDay:
targetHours = u.ArbeitszeitProTag()
case WorktimeBaseWeek:
- targetHours = u.ArbeitszeitProWoche() / 5
+ targetHours = u.ArbeitszeitProWocheFrac(0.2)
}
- return work - targetHours
+ return (work - targetHours).Round(time.Minute)
}
// Returns the worktime based on absence or kurzarbeit
@@ -119,9 +74,10 @@ func (d *WorkDay) GetWorktimeVirtual(u User, base WorktimeBase) time.Duration {
case WorktimeBaseDay:
return u.ArbeitszeitProTag()
case WorktimeBaseWeek:
- return u.ArbeitszeitProWoche() / 5
+ return u.ArbeitszeitProWocheFrac(0.2)
+ default:
+ return 0
}
- return 0
}
func (d *WorkDay) GetPausetimeVirtual(u User, base WorktimeBase) time.Duration {
@@ -136,9 +92,9 @@ func (d *WorkDay) GetOvertimeVirtual(u User, base WorktimeBase) time.Duration {
case WorktimeBaseDay:
targetHours = u.ArbeitszeitProTag()
case WorktimeBaseWeek:
- targetHours = u.ArbeitszeitProWoche() / 5
+ targetHours = u.ArbeitszeitProWocheFrac(0.2)
}
- return work - targetHours
+ return (work - targetHours).Round(time.Minute)
}
func (d *WorkDay) GetTimesReal(u User, base WorktimeBase) (work, pause, overtime time.Duration) {
@@ -217,70 +173,10 @@ func (d *WorkDay) GenerateKurzArbeitBookings(u User) (time.Time, time.Time) {
return timeFrom, timeTo
}
-func (d *WorkDay) TimeWorkVirtual(u User) time.Duration {
- if d.IsKurzArbeit() {
- return u.ArbeitszeitProTag()
- }
- return d.workTime
-}
-
func (d *WorkDay) GetKurzArbeit() *Absence {
return &d.kurzArbeitAbsence
}
-func (d *WorkDay) TimeWorkReal(u User) time.Duration {
- d.realWorkTime, d.realPauseTime = 0, 0
- var lastBooking Booking
- for _, booking := range d.Bookings {
- if booking.CheckInOut%2 == 1 {
- if !lastBooking.Timestamp.IsZero() {
- d.realPauseTime += booking.Timestamp.Sub(lastBooking.Timestamp)
- }
- } else {
- d.realWorkTime += booking.Timestamp.Sub(lastBooking.Timestamp)
- }
- lastBooking = booking
- }
- if helper.IsSameDate(d.Date(), time.Now()) && len(d.Bookings)%2 == 1 {
- d.realWorkTime += time.Since(lastBooking.Timestamp.Local())
- }
- // slog.Debug("Calculated RealWorkTime for user", "user", u, slog.String("worktime", d.realWorkTime.String()))
- return d.realWorkTime
-}
-
-func (d *WorkDay) TimeOvertimeReal(u User) time.Duration {
- workTime := d.TimeWorkVirtual(u)
- if workTime == 0 {
- workTime, _ = d.TimePauseReal(u)
- }
- if helper.IsWeekend(d.Day) && len(d.Bookings) == 0 {
- return 0
- }
- var overtime time.Duration
- overtime = workTime - u.ArbeitszeitProTag()
- return overtime
-}
-
-func (d *WorkDay) TimePauseReal(u User) (work, pause time.Duration) {
- if d.realWorkTime == 0 {
- d.TimeWorkReal(u)
- }
- d.workTime, d.pauseTime = d.realWorkTime, d.realPauseTime
- if d.realWorkTime <= 6*time.Hour || d.realPauseTime > 45*time.Minute {
- return d.realWorkTime, d.realPauseTime
- }
- if d.realWorkTime <= (9*time.Hour) && d.realPauseTime < 30*time.Minute {
- diff := 30*time.Minute - d.pauseTime
- d.workTime -= diff
- d.pauseTime += diff
- } else if d.realPauseTime < 45*time.Minute {
- diff := 45*time.Minute - d.pauseTime
- d.workTime -= diff
- d.pauseTime += diff
- }
- return d.workTime, d.pauseTime
-}
-
func (d *WorkDay) ToString() string {
return fmt.Sprintf("WorkDay: %s with %d bookings and worktime: %s", d.Date().Format(time.DateOnly), len(d.Bookings), helper.FormatDuration(d.workTime))
}
@@ -388,7 +284,6 @@ func GetWorkDays(user User, tsFrom, tsTo time.Time) []WorkDay {
if len(workDay.Bookings) == 1 && workDay.Bookings[0].CounterId == 0 {
workDay.Bookings = []Booking{}
}
- workDay.TimePauseReal(user)
if len(workDay.Bookings) > 1 || !helper.IsWeekend(workDay.Date()) {
workDays = append(workDays, workDay)
}
@@ -400,18 +295,6 @@ func GetWorkDays(user User, tsFrom, tsTo time.Time) []WorkDay {
return workDays
}
-func (d *WorkDay) GetAllWorkTimesReal(user User) (work, pause, overtime time.Duration) {
- if d.pauseTime == 0 || d.workTime == 0 {
- d.TimePauseReal(user)
- }
- return d.workTime.Round(time.Minute), d.pauseTime.Round(time.Minute), d.TimeOvertimeReal(user)
-}
-
-func (d *WorkDay) GetAllWorkTimesVirtual(user User) (work, pause, overtime time.Duration) {
- _, pause, overtime = d.GetAllWorkTimesReal(user)
- return d.TimeWorkVirtual(user), pause, overtime
-}
-
// returns bool wheter the workday was ended with an automatic logout
func (d *WorkDay) RequiresAction() bool {
if len(d.Bookings) == 0 {
@@ -424,19 +307,7 @@ func (d *WorkDay) GetDayProgress(u User) int8 {
if d.RequiresAction() {
return -1
}
- workTime := d.TimeWorkVirtual(u)
+ workTime := d.GetWorktimeVirtual(u, WorktimeBaseDay)
progress := (workTime.Seconds() / u.ArbeitszeitProTag().Seconds()) * 100
return int8(progress)
}
-
-// func (d *WorkDay) CalcOvertime(user User) time.Duration {
-// if d.workTime == 0 {
-// d.TimePauseReal(user)
-// }
-// if helper.IsWeekend(d.Day) && len(d.Bookings) == 0 {
-// return 0
-// }
-// var overtime time.Duration
-// overtime = d.workTime - user.ArbeitszeitProTag()
-// return overtime
-// }
diff --git a/Backend/models/workDay_test.go b/Backend/models/workDay_test.go
index 5b1aef7..cae5d38 100644
--- a/Backend/models/workDay_test.go
+++ b/Backend/models/workDay_test.go
@@ -22,59 +22,141 @@ var testWorkDay = models.WorkDay{
TimeTo: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 16:30")),
}
-func TestCalcRealWorkTime(t *testing.T) {
- workTime := testWorkDay.TimeWorkReal(testUser)
- if workTime != time.Hour*8 {
- t.Errorf("Calc Worktime Default not working, time should be 8h, but was %s", helper.FormatDuration(workTime))
- }
-}
-
-func TestCalcWorkPauseDiff(t *testing.T) {
- type testCase struct {
- Name string
- bookings []models.Booking
- expectedWorkTime time.Duration
- expectedPauseTime time.Duration
- expectedOvertime time.Duration
- }
-
- testCases := []testCase{testCase{
- Name: "6hrs no pause",
- bookings: testBookings6hrs,
- expectedWorkTime: 6 * time.Hour,
- expectedPauseTime: 0,
- expectedOvertime: -2 * time.Hour,
- },
- testCase{
- Name: "8hrs - 30min pause",
- bookings: testBookings8hrs,
- expectedWorkTime: 7*time.Hour + 30*time.Minute,
- expectedPauseTime: 30 * time.Minute,
- expectedOvertime: -30 * time.Minute,
+func TestWorkdayWorktimeDay(t *testing.T) {
+ testCases := []struct {
+ testName string
+ bookings []models.Booking
+ expectedTime time.Duration
+ }{
+ {
+ testName: "Bookings6hrs",
+ bookings: testBookings6hrs,
+ expectedTime: time.Hour * 6,
},
- testCase{
- Name: "10hrs - 45min pause",
- bookings: testBookings10hrs,
- expectedWorkTime: 9*time.Hour + 15*time.Minute,
- expectedPauseTime: 45 * time.Minute,
- expectedOvertime: 1*time.Hour + 15*time.Minute,
- }}
+ {
+ testName: "Bookings8hrs",
+ bookings: testBookings8hrs,
+ expectedTime: time.Hour*7 + time.Minute*30,
+ },
+ {
+ testName: "Bookings10hrs",
+ bookings: testBookings10hrs,
+ expectedTime: time.Hour*9 + time.Minute*15,
+ },
+ }
- for _, test := range testCases {
- t.Run(test.Name, func(t *testing.T) {
- testWorkDay.Bookings = test.bookings
- testWorkDay.TimeWorkReal(testUser)
- testWorkDay.TimePauseReal(testUser)
- testWorkDay.TimeOvertimeReal(testUser)
- workTime, pauseTime, overTime := testWorkDay.GetAllWorkTimesReal(testUser)
- if workTime != test.expectedWorkTime {
- t.Errorf("Calculated wrong workTime: should be %s, but was %s", helper.FormatDuration(test.expectedWorkTime), helper.FormatDuration(workTime))
- }
- if pauseTime != test.expectedPauseTime {
- t.Errorf("Calculated wrong pauseTime: should be %s, but was %s", helper.FormatDuration(test.expectedPauseTime), helper.FormatDuration(pauseTime))
- }
- if overTime != test.expectedOvertime {
- t.Errorf("Calculated wrong overtime: should be %s, but was %s", helper.FormatDuration(test.expectedOvertime), helper.FormatDuration(overTime))
+ for _, tc := range testCases {
+ t.Run("Calc Absence Worktime: "+tc.testName, func(t *testing.T) {
+ var testCase = testWorkDay
+ testCase.Bookings = tc.bookings
+ workTime := testCase.GetWorktimeReal(testUser, models.WorktimeBaseDay)
+ if workTime != tc.expectedTime {
+ t.Errorf("GetWorktimeReal not working, time should be %s, but was %s", helper.FormatDurationFill(tc.expectedTime, true), helper.FormatDurationFill(workTime, true))
+ }
+ })
+ }
+}
+
+func TestWorkdayWorktimeWeek(t *testing.T) {
+ testCases := []struct {
+ testName string
+ bookings []models.Booking
+ expectedTime time.Duration
+ }{
+ {
+ testName: "Bookings6hrs",
+ bookings: testBookings6hrs,
+ expectedTime: time.Hour * 6,
+ },
+ {
+ testName: "Bookings8hrs",
+ bookings: testBookings8hrs,
+ expectedTime: time.Hour*7 + time.Minute*30,
+ },
+ {
+ testName: "Bookings10hrs",
+ bookings: testBookings10hrs,
+ expectedTime: time.Hour*9 + time.Minute*15,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run("Calc Absence Worktime: "+tc.testName, func(t *testing.T) {
+ var testCase = testWorkDay
+ testCase.Bookings = tc.bookings
+ workTime := testCase.GetWorktimeReal(testUser, models.WorktimeBaseWeek)
+ if workTime != tc.expectedTime {
+ t.Errorf("GetWorktimeReal not working, time should be %s, but was %s", helper.FormatDurationFill(tc.expectedTime, true), helper.FormatDurationFill(workTime, true))
+ }
+ })
+ }
+}
+
+func TestWorkdayPausetimeDay(t *testing.T) {
+ testCases := []struct {
+ testName string
+ bookings []models.Booking
+ expectedTime time.Duration
+ }{
+ {
+ testName: "Bookings6hrs",
+ bookings: testBookings6hrs,
+ expectedTime: 0,
+ },
+ {
+ testName: "Bookings8hrs",
+ bookings: testBookings8hrs,
+ expectedTime: time.Minute * 30,
+ },
+ {
+ testName: "Bookings10hrs",
+ bookings: testBookings10hrs,
+ expectedTime: time.Minute * 45,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run("Calc Absence Worktime: "+tc.testName, func(t *testing.T) {
+ var testCase = testWorkDay
+ testCase.Bookings = tc.bookings
+ workTime := testCase.GetPausetimeReal(testUser, models.WorktimeBaseDay)
+ if workTime != tc.expectedTime {
+ t.Errorf("GetPausetimeReal not working, time should be %s, but was %s", helper.FormatDurationFill(tc.expectedTime, true), helper.FormatDurationFill(workTime, true))
+ }
+ })
+ }
+}
+
+func TestWorkdayPausetimeWeek(t *testing.T) {
+ testCases := []struct {
+ testName string
+ bookings []models.Booking
+ expectedTime time.Duration
+ }{
+ {
+ testName: "Bookings6hrs",
+ bookings: testBookings6hrs,
+ expectedTime: 0,
+ },
+ {
+ testName: "Bookings8hrs",
+ bookings: testBookings8hrs,
+ expectedTime: time.Minute * 30,
+ },
+ {
+ testName: "Bookings10hrs",
+ bookings: testBookings10hrs,
+ expectedTime: time.Minute * 45,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run("Calc Absence Worktime: "+tc.testName, func(t *testing.T) {
+ var testCase = testWorkDay
+ testCase.Bookings = tc.bookings
+ workTime := testCase.GetPausetimeReal(testUser, models.WorktimeBaseWeek)
+ if workTime != tc.expectedTime {
+ t.Errorf("GetPausetimeReal not working, time should be %s, but was %s", helper.FormatDurationFill(tc.expectedTime, true), helper.FormatDurationFill(workTime, true))
}
})
}
diff --git a/Backend/models/workWeek.go b/Backend/models/workWeek.go
index beaf504..ea353d0 100644
--- a/Backend/models/workWeek.go
+++ b/Backend/models/workWeek.go
@@ -47,18 +47,20 @@ func NewWorkWeek(user User, tsMonday time.Time, populate bool) WorkWeek {
}
func (w *WorkWeek) PopulateWithDays(worktime time.Duration, overtime time.Duration) {
+ slog.Debug("Populating Workweek for user", "user", w.User)
slog.Debug("Got Days with overtime and worktime", slog.String("worktime", worktime.String()), slog.String("overtime", overtime.String()))
w.Days = GetDays(w.User, w.WeekStart, w.WeekStart.Add(6*24*time.Hour), false)
for _, day := range w.Days {
- work, _ := day.TimePauseReal(w.User)
- w.Worktime += work
- w.WorkTimeVirtual += day.TimeWorkVirtual(w.User)
+ w.Worktime += day.GetWorktimeReal(w.User, WorktimeBaseDay)
+ w.WorkTimeVirtual += day.GetWorktimeVirtual(w.User, WorktimeBaseDay)
}
- slog.Debug("Got worktime for user", "user", w.User, "worktime", w.Worktime.String(), "virtualWorkTime", w.WorkTimeVirtual.String())
+ slog.Debug("Got worktime for user", "worktime", w.Worktime.String(), "virtualWorkTime", w.WorkTimeVirtual.String())
w.Overtime = w.WorkTimeVirtual - w.User.ArbeitszeitProWoche()
+ slog.Debug("Calculated overtime", "worktime", w.Worktime.String(), "virtualWorkTime", w.WorkTimeVirtual.String())
+
w.Worktime = w.Worktime.Round(time.Minute)
w.Overtime = w.Overtime.Round(time.Minute)
diff --git a/Backend/templates/pdf.templ b/Backend/templates/pdf.templ
index c00d786..332ab33 100644
--- a/Backend/templates/pdf.templ
+++ b/Backend/templates/pdf.templ
@@ -58,71 +58,70 @@ templ CheckboxComponent(id, label string) {
}
-templ PDFReportEmploye(e models.User, overtime, worktime time.Duration, workDays []models.IWorkDay, tsStart time.Time, tsEnd time.Time) {
- {{
- _, kw := tsStart.ISOWeek()
- noBorder := ""
- }}
- @Base()
-
-
-
{ e.Vorname } { e.Name }
-
Zeitraum: { tsStart.Format("02.01.2006") } - { tsEnd.Format("02.01.2006") }
-
Arbeitszeit: { helper.FormatDuration(worktime) }
-
Überstunden: { helper.FormatDuration(overtime) }
-
-
-
{ kw }
-
Kommen
-
Gehen
-
Arbeitsart
-
Stunden
-
Pause
-
Überstunden
- for index, day := range workDays {
- {{
- if index == len(workDays)-1 {
- noBorder = "border-b-0"
- }
- }}
-
{ day.Date().Format("02.01.2006") }
-
- 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() {
- {{
- timeFrom, timeTo := workDay.GenerateKurzArbeitBookings(e)
- }}
-
{ timeFrom.Format("15:04") }
-
{ timeTo.Format("15:04") }
-
Kurzarbeit
- }
- } else {
- {{
- absentDay, _ := day.(*models.Absence)
- }}
-
{ absentDay.AbwesenheitTyp.Name }
- }
-
- {{ work, pause, overtime := day.GetAllWorkTimesVirtual(e) }}
- @ColorDuration(work, noBorder)
- @ColorDuration(pause, noBorder)
- @ColorDuration(overtime, noBorder+" border-r-0")
- if day.Date().Weekday() == time.Friday {
-
Wochenende
- }
- }
-
-
-}
-
+// templ PDFReportEmploye(e models.User, overtime, worktime time.Duration, workDays []models.IWorkDay, tsStart time.Time, tsEnd time.Time) {
+// {{
+// _, kw := tsStart.ISOWeek()
+// noBorder := ""
+// }}
+// @Base()
+//
+//
+//
{ e.Vorname } { e.Name }
+//
Zeitraum: { tsStart.Format("02.01.2006") } - { tsEnd.Format("02.01.2006") }
+//
Arbeitszeit: { helper.FormatDuration(worktime) }
+//
Überstunden: { helper.FormatDuration(overtime) }
+//
+//
+//
{ kw }
+//
Kommen
+//
Gehen
+//
Arbeitsart
+//
Stunden
+//
Pause
+//
Überstunden
+// for index, day := range workDays {
+// {{
+// if index == len(workDays)-1 {
+// noBorder = "border-b-0"
+// }
+// }}
+//
{ day.Date().Format("02.01.2006") }
+//
+// 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() {
+// {{
+// timeFrom, timeTo := workDay.GenerateKurzArbeitBookings(e)
+// }}
+//
{ timeFrom.Format("15:04") }
+//
{ timeTo.Format("15:04") }
+//
Kurzarbeit
+// }
+// } else {
+// {{
+// absentDay, _ := day.(*models.Absence)
+// }}
+//
{ absentDay.AbwesenheitTyp.Name }
+// }
+//
+// {{ work, pause, overtime := day.GetTimesVirtual(e) }}
+// @ColorDuration(work, noBorder)
+// @ColorDuration(pause, noBorder)
+// @ColorDuration(overtime, noBorder+" border-r-0")
+// if day.Date().Weekday() == time.Friday {
+//
Wochenende
+// }
+// }
+//
+//
+// }
templ ColorDuration(d time.Duration, classes string) {
{{
color := ""
diff --git a/Backend/templates/pdf_templ.go b/Backend/templates/pdf_templ.go
index a15eca1..997a431 100644
--- a/Backend/templates/pdf_templ.go
+++ b/Backend/templates/pdf_templ.go
@@ -177,7 +177,71 @@ func CheckboxComponent(id, label string) templ.Component {
})
}
-func PDFReportEmploye(e models.User, overtime, worktime time.Duration, workDays []models.IWorkDay, tsStart time.Time, tsEnd time.Time) templ.Component {
+// templ PDFReportEmploye(e models.User, overtime, worktime time.Duration, workDays []models.IWorkDay, tsStart time.Time, tsEnd time.Time) {
+// {{
+// _, kw := tsStart.ISOWeek()
+// noBorder := ""
+// }}
+// @Base()
+//
+//
+//
{ e.Vorname } { e.Name }
+//
Zeitraum: { tsStart.Format("02.01.2006") } - { tsEnd.Format("02.01.2006") }
+//
Arbeitszeit: { helper.FormatDuration(worktime) }
+//
Überstunden: { helper.FormatDuration(overtime) }
+//
+//
+//
{ kw }
+//
Kommen
+//
Gehen
+//
Arbeitsart
+//
Stunden
+//
Pause
+//
Überstunden
+// for index, day := range workDays {
+// {{
+// if index == len(workDays)-1 {
+// noBorder = "border-b-0"
+// }
+// }}
+//
{ day.Date().Format("02.01.2006") }
+//
+// 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() {
+// {{
+// timeFrom, timeTo := workDay.GenerateKurzArbeitBookings(e)
+// }}
+//
{ timeFrom.Format("15:04") }
+//
{ timeTo.Format("15:04") }
+//
Kurzarbeit
+// }
+// } else {
+// {{
+// absentDay, _ := day.(*models.Absence)
+// }}
+//
{ absentDay.AbwesenheitTyp.Name }
+// }
+//
+// {{ work, pause, overtime := day.GetTimesVirtual(e) }}
+// @ColorDuration(work, noBorder)
+// @ColorDuration(pause, noBorder)
+// @ColorDuration(overtime, noBorder+" border-r-0")
+// if day.Date().Weekday() == time.Friday {
+//
Wochenende
+// }
+// }
+//
+//
+// }
+func ColorDuration(d time.Duration, classes string) 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 {
@@ -199,378 +263,42 @@ func PDFReportEmploye(e models.User, overtime, worktime time.Duration, workDays
}
ctx = templ.ClearChildren(ctx)
- _, kw := tsStart.ISOWeek()
- noBorder := ""
- templ_7745c5c3_Err = Base().Render(ctx, templ_7745c5c3_Buffer)
+ color := ""
+ if d.Abs() < time.Minute {
+ color = "text-neutral-300"
+ }
+ var templ_7745c5c3_Var10 = []any{color + " " + classes}
+ templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
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_Var10 string
- templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(e.Vorname)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 69, Col: 45}
- }
- _, 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, 13, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
Zeitraum: ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var12 string
- templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(tsStart.Format("02.01.2006"))
+ templ_7745c5c3_Var12, 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: 70, Col: 52}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 132, Col: 72}
}
_, 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, 15, " - ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var13 string
- templ_7745c5c3_Var13, 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: 70, Col: 98}
- }
- _, 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, 16, "
Arbeitszeit: ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var14 string
- templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(worktime))
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 71, Col: 58}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
Überstunden: ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var15 string
- templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(overtime))
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 72, Col: 59}
- }
- _, 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, 18, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var16 string
- templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(kw)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 75, Col: 52}
- }
- _, 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, 19, "
Kommen
Gehen
Arbeitsart
Stunden
Pause
Überstunden
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- for index, day := range workDays {
-
- if index == len(workDays)-1 {
- noBorder = "border-b-0"
- }
- var templ_7745c5c3_Var17 = []any{noBorder}
- templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var17...)
- 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
- }
- var templ_7745c5c3_Var19 string
- templ_7745c5c3_Var19, 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: 88, Col: 59}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
- 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
- }
- var templ_7745c5c3_Var20 = []any{"grid grid-cols-subgrid col-span-3 " + noBorder}
- templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...)
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- if day.IsWorkDay() {
-
- workDay, _ := day.(*models.WorkDay)
- for bookingI := 0; bookingI < len(workDay.Bookings); bookingI += 2 {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var22 string
- templ_7745c5c3_Var22, 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: 95, Col: 64}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
- 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
- }
- var templ_7745c5c3_Var23 string
- templ_7745c5c3_Var23, 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: 96, Col: 66}
- }
- _, 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, 27, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var24 string
- templ_7745c5c3_Var24, 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: 97, Col: 55}
- }
- _, 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, 28, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, " ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- if workDay.IsKurzArbeit() {
-
- timeFrom, timeTo := workDay.GenerateKurzArbeitBookings(e)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var25 string
- templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(timeFrom.Format("15:04"))
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 103, Col: 36}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var26 string
- templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(timeTo.Format("15:04"))
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 104, Col: 34}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "
Kurzarbeit
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- }
- } else {
-
- absentDay, _ := day.(*models.Absence)
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var27 string
- templ_7745c5c3_Var27, 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: 111, Col: 62}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- 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, 36, " ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = ColorDuration(pause, noBorder).Render(ctx, templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, " ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = ColorDuration(overtime, noBorder+" border-r-0").Render(ctx, templ_7745c5c3_Buffer)
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, " ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- if day.Date().Weekday() == time.Friday {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
Wochenende
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- }
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "
")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- return nil
- })
-}
-
-func ColorDuration(d time.Duration, classes string) 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_Var28 := templ.GetChildren(ctx)
- if templ_7745c5c3_Var28 == nil {
- templ_7745c5c3_Var28 = templ.NopComponent
- }
- ctx = templ.ClearChildren(ctx)
-
- color := ""
- if d.Abs() < time.Minute {
- color = "text-neutral-300"
- }
- var templ_7745c5c3_Var29 = []any{color + " " + classes}
- templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var29...)
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var31 string
- templ_7745c5c3_Var31, 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: 133, Col: 72}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31))
- 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, 14, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
diff --git a/Backend/templates/teamComponents.templ b/Backend/templates/teamComponents.templ
index 086bd8d..b0e324a 100644
--- a/Backend/templates/teamComponents.templ
+++ b/Backend/templates/teamComponents.templ
@@ -36,7 +36,7 @@ templ defaultWeekDayComponent(u models.User, day models.IWorkDay) {
if day.IsWorkDay() {
{{
workDay, _ := day.(*models.WorkDay)
- work, pause, _ := workDay.GetAllWorkTimesReal(u)
+ work, pause, _ := workDay.GetTimesReal(u, models.WorktimeBaseDay)
}}
if !workDay.RequiresAction() {
diff --git a/Backend/templates/teamComponents_templ.go b/Backend/templates/teamComponents_templ.go
index 6314bce..80a940e 100644
--- a/Backend/templates/teamComponents_templ.go
+++ b/Backend/templates/teamComponents_templ.go
@@ -179,7 +179,7 @@ func defaultWeekDayComponent(u models.User, day models.IWorkDay) templ.Component
if day.IsWorkDay() {
workDay, _ := day.(*models.WorkDay)
- work, pause, _ := workDay.GetAllWorkTimesReal(u)
+ work, pause, _ := workDay.GetTimesReal(u, models.WorktimeBaseDay)
if !workDay.RequiresAction() {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
")
if templ_7745c5c3_Err != nil {
diff --git a/Backend/templates/timePage.templ b/Backend/templates/timePage.templ
index 88cd3ec..a59bc47 100644
--- a/Backend/templates/timePage.templ
+++ b/Backend/templates/timePage.templ
@@ -103,7 +103,8 @@ templ defaultDayComponent(day models.IWorkDay) {
if day.IsWorkDay() {
{{
workDay, _ := day.(*models.WorkDay)
- work, pause, overtime := workDay.GetAllWorkTimesReal(user)
+ work, pause, overtime := workDay.GetTimesVirtual(user, models.WorktimeBaseDay)
+ work = workDay.GetWorktimeReal(user, models.WorktimeBaseDay)
}}
if day.RequiresAction() {
Bitte anpassen
diff --git a/Backend/templates/timePage_templ.go b/Backend/templates/timePage_templ.go
index 209fa28..264a21b 100644
--- a/Backend/templates/timePage_templ.go
+++ b/Backend/templates/timePage_templ.go
@@ -297,7 +297,8 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
if day.IsWorkDay() {
workDay, _ := day.(*models.WorkDay)
- work, pause, overtime := workDay.GetAllWorkTimesReal(user)
+ work, pause, overtime := workDay.GetTimesVirtual(user, models.WorktimeBaseDay)
+ work = workDay.GetWorktimeReal(user, models.WorktimeBaseDay)
if day.RequiresAction() {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "Bitte anpassen
")
if templ_7745c5c3_Err != nil {
@@ -312,7 +313,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
var templ_7745c5c3_Var14 string
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(work))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 113, Col: 155}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 114, Col: 155}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
if templ_7745c5c3_Err != nil {
@@ -335,7 +336,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
var templ_7745c5c3_Var15 string
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(pause))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 116, Col: 173}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 117, Col: 173}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
if templ_7745c5c3_Err != nil {
@@ -358,7 +359,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
var templ_7745c5c3_Var16 string
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(overtime))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 121, Col: 41}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 122, Col: 41}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
if templ_7745c5c3_Err != nil {
@@ -391,7 +392,7 @@ func defaultDayComponent(day models.IWorkDay) templ.Component {
var templ_7745c5c3_Var18 string
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs("time-" + day.Date().Format(time.DateOnly))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 130, Col: 56}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 131, Col: 56}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
@@ -507,7 +508,7 @@ func absentInput(a models.Absence) templ.Component {
var templ_7745c5c3_Var21 string
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(a.DateFrom.Format(time.DateOnly))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 162, Col: 79}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 163, Col: 79}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
if templ_7745c5c3_Err != nil {
@@ -520,7 +521,7 @@ func absentInput(a models.Absence) templ.Component {
var templ_7745c5c3_Var22 string
templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(a.DateTo.Format(time.DateOnly))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 163, Col: 75}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 164, Col: 75}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
if templ_7745c5c3_Err != nil {
@@ -533,7 +534,7 @@ func absentInput(a models.Absence) templ.Component {
var templ_7745c5c3_Var23 string
templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(a.AbwesenheitTyp.Id)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 164, Col: 64}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 165, Col: 64}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
if templ_7745c5c3_Err != nil {
@@ -546,7 +547,7 @@ func absentInput(a models.Absence) templ.Component {
var templ_7745c5c3_Var24 string
templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(a.CounterId)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 165, Col: 54}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 166, Col: 54}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
if templ_7745c5c3_Err != nil {
diff --git a/DB/initdb/01_schema.sql b/DB/initdb/01_schema.sql
index 70cfefe..b434f4c 100755
--- a/DB/initdb/01_schema.sql
+++ b/DB/initdb/01_schema.sql
@@ -104,7 +104,7 @@ CREATE TABLE "s_abwesenheit_typen" (
"arbeitszeit_equivalent" float4 NOT NULL
);
-COMMENT ON COLUMN "s_abwesenheit_typen"."arbeitszeit_equivalent" IS '0=keine Arbeitszeit; -1=Arbeitszeit auffüllen; <=1 => Arbeitszeit';
+COMMENT ON COLUMN "s_abwesenheit_typen"."arbeitszeit_equivalent" IS '0=keine Arbeitszeit; -1=Arbeitszeit auffüllen; <=1 - 100 => Arbeitszeit pro Tag prozentual';
-- Adds crypto extension
diff --git a/DocumentCreator/templates/abrechnung.typ b/DocumentCreator/templates/abrechnung.typ
index 5eb7bb0..ee71ebc 100644
--- a/DocumentCreator/templates/abrechnung.typ
+++ b/DocumentCreator/templates/abrechnung.typ
@@ -37,7 +37,7 @@
[Zeitraum: #meta.TimeRange]
table(
- columns: (1fr, 1fr, 1fr, 1fr, 1fr, 1fr, 1.25fr),
+ columns: (1fr, 1fr, 1fr, 1fr, 1fr, 1fr, .875fr, 1.25fr),
fill: (x, y) =>
if y == 0 { oklch(87%, 0, 0deg) },
table-header(
@@ -68,11 +68,12 @@
]
},
[#day.Worktime],
+ [#day.Kurzarbeit],
[#day.Pausetime],
[#day.Overtime],
)
if day.IsFriday {
- ( table.cell(colspan: 7, fill: oklch(87%, 0, 0deg))[Wochenende], ) // note the trailing comma
+ ( table.cell(colspan: 8, fill: oklch(87%, 0, 0deg))[Wochenende], ) // note the trailing comma
}
}
)