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()
- 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 { day.Date().Format("02.01.2006") } { workDay.Bookings[bookingI].Timestamp.Format("15:04") } { workDay.Bookings[bookingI+1].Timestamp.Format("15:04") } { workDay.Bookings[bookingI].BookingType.Name } { timeFrom.Format("15:04") } { timeTo.Format("15:04") } Kurzarbeit { absentDay.AbwesenheitTyp.Name } Wochenende 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 { day.Date().Format("02.01.2006") } { workDay.Bookings[bookingI].Timestamp.Format("15:04") } { workDay.Bookings[bookingI+1].Timestamp.Format("15:04") } { workDay.Bookings[bookingI].BookingType.Name } { timeFrom.Format("15:04") } { timeTo.Format("15:04") } Kurzarbeit { absentDay.AbwesenheitTyp.Name } Wochenende 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 { day.Date().Format("02.01.2006") } { workDay.Bookings[bookingI].Timestamp.Format("15:04") } { workDay.Bookings[bookingI+1].Timestamp.Format("15:04") } { workDay.Bookings[bookingI].BookingType.Name } { timeFrom.Format("15:04") } { timeTo.Format("15:04") } Kurzarbeit { absentDay.AbwesenheitTyp.Name } Wochenende 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
- }
- 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_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
- }
- 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
- }
- 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, " Wochenende{ e.Vorname } { e.Name }
- { e.Vorname } { e.Name }
+// { e.Vorname } { e.Name }
+// ")
- 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, "
") - 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() {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 } } )