diff --git a/Backend/endpoints/team.go b/Backend/endpoints/team.go index 397d45a..e026488 100644 --- a/Backend/endpoints/team.go +++ b/Backend/endpoints/team.go @@ -79,5 +79,5 @@ func showWeeks(w http.ResponseWriter, r *http.Request) { workWeeks = append(workWeeks, weeks...) } // isRunningWeek := time.Since(lastSub) < 24*5*time.Hour //the last submission is this week and cannot be send yet - templates.TeamPage(workWeeks, userWeek).Render(r.Context(), w) + templates.TeamPage([]models.WorkWeek{userWeek, userWeek}, userWeek).Render(r.Context(), w) } diff --git a/Backend/endpoints/time.go b/Backend/endpoints/time.go index bc03c3f..9f85c2e 100644 --- a/Backend/endpoints/time.go +++ b/Backend/endpoints/time.go @@ -66,18 +66,18 @@ func getBookings(w http.ResponseWriter, r *http.Request) { } tsTo = tsTo.AddDate(0, 0, 1) // so that today is inside - workDays := models.GetWorkDays(user, tsFrom, tsTo) - sort.Slice(workDays, func(i, j int) bool { - return workDays[i].Day.After(workDays[j].Day) + days := models.GetDays(user, tsFrom, tsTo) + sort.Slice(days, func(i, j int) bool { + return days[i].Date().After(days[j].Date()) }) lastSub := user.GetLastWorkWeekSubmission() var aggregatedOvertime time.Duration - for _, day := range workDays { - if day.Day.Before(lastSub) { + for _, day := range days { + if day.Date().Before(lastSub) { continue } - aggregatedOvertime += day.CalcOvertime(user) + aggregatedOvertime += day.TimeOvertimeReal(user) } if reportedOvertime, err := user.GetReportedOvertime(); err == nil { user.Overtime = (reportedOvertime + aggregatedOvertime).Round(time.Minute) @@ -88,12 +88,13 @@ func getBookings(w http.ResponseWriter, r *http.Request) { if r.Header.Get("Accept") == "application/json" { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - json.NewEncoder(w).Encode(workDays) + json.NewEncoder(w).Encode(days) return } ctx := context.WithValue(r.Context(), "user", user) - templates.TimePage(workDays, lastSub).Render(ctx, w) + ctx = context.WithValue(ctx, "days", days) + templates.TimePage([]models.WorkDay{}, lastSub).Render(ctx, w) } func updateBooking(w http.ResponseWriter, r *http.Request) { diff --git a/Backend/models/absence.go b/Backend/models/absence.go index 08919f4..a008fde 100644 --- a/Backend/models/absence.go +++ b/Backend/models/absence.go @@ -1,22 +1,25 @@ package models import ( + "encoding/json" "errors" "log" "time" ) type AbsenceType struct { - Id int8 - Name string - WorkTime int8 + Id int8 `json:"abwesenheit_id"` + Name string `json:"abwesenheit_name"` + WorkTime int8 `json:"arbeitszeit_equivalent"` } type Absence struct { + Day time.Time CounterId int CardUID string AbwesenheitTyp AbsenceType - Datum time.Time + DateFrom time.Time + DateTo time.Time } func NewAbsence(card_uid string, abwesenheit_typ int, datum time.Time) (Absence, error) { @@ -24,7 +27,7 @@ func NewAbsence(card_uid string, abwesenheit_typ int, datum time.Time) (Absence, return Absence{ CardUID: card_uid, AbwesenheitTyp: AbsenceType{0, "Custom absence", 100}, - Datum: datum, + DateFrom: datum, }, nil } _absenceType, ok := GetAbsenceTypesCached()[int8(abwesenheit_typ)] @@ -34,18 +37,64 @@ func NewAbsence(card_uid string, abwesenheit_typ int, datum time.Time) (Absence, return Absence{ CardUID: card_uid, AbwesenheitTyp: _absenceType, - Datum: datum, + DateFrom: datum, }, nil } +func (a *Absence) Date() time.Time { + return a.Day.Truncate(24 * time.Hour) +} + +func (a *Absence) TimeWorkVirtual(u User) time.Duration { + return a.TimeWorkReal(u) +} + +func (a *Absence) TimeWorkReal(u User) time.Duration { + if a.AbwesenheitTyp.WorkTime > 1 { + return time.Duration(u.ArbeitszeitPerTag * float32(time.Hour)).Round(time.Minute) + } + return 0 +} + +func (a *Absence) TimePauseReal(u User) (work, pause time.Duration) { + return 0, 0 +} + +func (a *Absence) TimeOvertimeReal(u User) time.Duration { + if a.AbwesenheitTyp.WorkTime > 1 { + return 0 + } + return -u.ArbeitszeitProTag() +} + +func (a *Absence) ToString() string { + return "Abwesenheit" +} + +func (a *Absence) IsWorkDay() bool { + return false +} + +func (a *Absence) IsKurzArbeit() bool { + return false +} + +func (a *Absence) GetDayProgress(u User) int8 { + return 100 +} + +func (a *Absence) RequiresAction() bool { + return false +} + func (a *Absence) Insert() error { - qStr, err := DB.Prepare(`INSERT INTO abwesenheit (card_uid, abwesenheit_typ, datum) VALUES ($1, $2, $3) RETURNING counter_id;`) + qStr, err := DB.Prepare(`INSERT INTO abwesenheit (card_uid, abwesenheit_typ, datum_from, datum_to) VALUES ($1, $2, $3, $4) RETURNING counter_id;`) if err != nil { log.Println("Error preparing sql Statement", err) return err } defer qStr.Close() - err = qStr.QueryRow(a.CardUID, a.AbwesenheitTyp.Id, a.Datum).Scan(&a.CounterId) + err = qStr.QueryRow(a.CardUID, a.AbwesenheitTyp.Id, a.DateFrom, a.DateTo).Scan(&a.CounterId) if err != nil { log.Println("Error executing insert statement", err) return err @@ -55,12 +104,12 @@ func (a *Absence) Insert() error { func GetAbsenceById(counterId int) (Absence, error) { var absence Absence = Absence{CounterId: counterId} - qStr, err := DB.Prepare("SELECT card_uid, abwesenheit_typ, datum FROM abwesenheit WHERE counter_id = $1;") + qStr, err := DB.Prepare("SELECT card_uid, abwesenheit_typ, datum_from, datum_to FROM abwesenheit WHERE counter_id = $1;") if err != nil { return absence, err } defer qStr.Close() - err = qStr.QueryRow(counterId).Scan(&absence.CardUID, &absence.AbwesenheitTyp.Id, &absence.Datum) + err = qStr.QueryRow(counterId).Scan(&absence.CardUID, &absence.AbwesenheitTyp.Id, &absence.DateFrom, &absence.DateTo) if err != nil { return absence, err } @@ -69,7 +118,32 @@ func GetAbsenceById(counterId int) (Absence, error) { func GetAbsencesByCardUID(card_uid string, tsFrom time.Time, tsTo time.Time) ([]Absence, error) { var absences []Absence - qStr, err := DB.Prepare("SELECT counter_id, abwesenheit_typ, datum FROM abwesenheit WHERE card_uid = $1 AND datum BETWEEN $2::DATE AND $3::DATE ORDER BY datum;") + // qStr, err := DB.Prepare(`SELECT counter_id, abwesenheit_typ, datum_from, datum_to FROM abwesenheit WHERE card_uid = $1 AND datum_from <= $2 AND datum_to >= $3 ORDER BY datum_from;`) + qStr, err := DB.Prepare(` + SELECT + ab.counter_id, + gs::DATE AS work_date, + ab.card_uid, + ab.datum_from, + ab.datum_to, + jsonb_build_object( + 'abwesenheit_id', sat.abwesenheit_id, + 'abwesenheit_name', sat.abwesenheit_name, + 'arbeitszeit_equivalent', sat.arbeitszeit_equivalent + ) AS abwesenheit_info + FROM generate_series( + $2, + $3, + INTERVAL '1 day' + ) gs + JOIN abwesenheit ab + ON ab.card_uid = $1 + AND ab.datum_from::DATE <= gs::DATE + AND ab.datum_to::DATE >= gs::DATE + LEFT JOIN s_abwesenheit_typen sat + ON ab.abwesenheit_typ = sat.abwesenheit_id + ORDER BY gs::DATE, ab.counter_id; + `) if err != nil { return absences, err } @@ -81,15 +155,16 @@ func GetAbsencesByCardUID(card_uid string, tsFrom time.Time, tsTo time.Time) ([] defer rows.Close() for rows.Next() { var absence Absence - if err := rows.Scan(&absence.CounterId, &absence.AbwesenheitTyp.Id, &absence.Datum); err != nil { + var abwesenheitsTyp []byte + if err := rows.Scan(&absence.CounterId, &absence.Day, &absence.CardUID, &absence.DateFrom, &absence.DateTo, &abwesenheitsTyp); err != nil { return absences, err } - absence.AbwesenheitTyp, err = GetAbsenceTypeById(absence.AbwesenheitTyp.Id) - if err == nil { - absences = append(absences, absence) - } else { - log.Println("Cannot populate absence type!", err) + err = json.Unmarshal(abwesenheitsTyp, &absence.AbwesenheitTyp) + if err != nil { + log.Println("Error parsing abwesenheitsTyp to JSON!", err) + return absences, nil } + absences = append(absences, absence) } if err = rows.Err(); err != nil { return absences, err diff --git a/Backend/models/user.go b/Backend/models/user.go index b7002d2..ccb188a 100644 --- a/Backend/models/user.go +++ b/Backend/models/user.go @@ -85,6 +85,15 @@ 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) +} + +func (u *User) ArbeitszeitProWoche() time.Duration { + return time.Duration(u.ArbeitszeitPerWoche * float32(time.Hour)).Round(time.Minute) +} + // Returns true if there is a booking 1 for today -> meaning the user is at work // Returns false if there is no booking today or the user is already booked out of the system func (u *User) CheckAnwesenheit() bool { diff --git a/Backend/models/workDay.go b/Backend/models/workDay.go index e5cf71e..0c1f6b9 100644 --- a/Backend/models/workDay.go +++ b/Backend/models/workDay.go @@ -2,21 +2,144 @@ package models import ( "arbeitszeitmessung/helper" - "database/sql" "encoding/json" "log" "strconv" "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 + ToString() string + IsWorkDay() bool + IsKurzArbeit() bool + GetDayProgress(User) int8 + RequiresAction() bool +} + type WorkDay struct { - Day time.Time `json:"day"` - Bookings []Booking `json:"bookings"` - workTime time.Duration - pauseTime time.Duration - TimeFrom time.Time - TimeTo time.Time - Absence Absence + 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 +} + +func GetDays(user User, tsFrom, tsTo time.Time) []IWorkDay { + var allDays map[string]IWorkDay = make(map[string]IWorkDay) + var sortedDays []IWorkDay + for _, day := range GetWorkDays(user, tsFrom, tsTo) { + allDays[day.Date().Format("2006-01-02")] = &day + } + absences, err := GetAbsencesByCardUID(user.CardUID, tsFrom, tsTo) + if err != nil { + log.Println("Error gettings absences for all Days!", err) + return sortedDays + } + for _, day := range absences { + if helper.IsWeekend(day.Date()) { + continue + } + if day.AbwesenheitTyp.WorkTime == 1 { + if workDay, ok := allDays[day.Date().Format("2006-01-02")].(*WorkDay); ok { + workDay.kurzArbeit = true + } + } else { + allDays[day.Date().Format("2006-01-02")] = &day + } + } + + for _, day := range allDays { + sortedDays = append(sortedDays, day) + } + return sortedDays +} + +func (d *WorkDay) Date() time.Time { + return d.Day +} + +func (d *WorkDay) TimeWorkVirtual(u User) time.Duration { + if d.IsKurzArbeit() { + return u.ArbeitszeitProTag() + } + return d.workTime +} + +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()) + } + 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 "WorkDay" +} + +func (d *WorkDay) IsWorkDay() bool { + return true +} + +func (d *WorkDay) SetKurzArbeit(kurzArbeit bool) { + d.kurzArbeit = kurzArbeit +} + +func (d *WorkDay) IsKurzArbeit() bool { + return d.kurzArbeit } func GetWorkDays(user User, tsFrom, tsTo time.Time) []WorkDay { @@ -24,72 +147,60 @@ func GetWorkDays(user User, tsFrom, tsTo time.Time) []WorkDay { var workSec, pauseSec float64 qStr, err := DB.Prepare(` - WITH all_days AS ( - SELECT generate_series($2::DATE, $3::DATE - INTERVAL '1 day', INTERVAL '1 day')::DATE AS work_date -), -ordered_bookings AS ( - SELECT - a.timestamp::DATE AS work_date, - a.timestamp, - a.check_in_out, - a.counter_id, - a.anwesenheit_typ, - sat.anwesenheit_name AS anwesenheit_typ_name, - LAG(a.timestamp) OVER (PARTITION BY a.card_uid, a.timestamp::DATE ORDER BY a.timestamp) AS prev_timestamp, - LAG(a.check_in_out) OVER (PARTITION BY a.card_uid, a.timestamp::DATE ORDER BY a.timestamp) AS prev_check - FROM anwesenheit a - LEFT JOIN s_anwesenheit_typen sat ON a.anwesenheit_typ = sat.anwesenheit_id - WHERE a.card_uid = $1 - AND a.timestamp::DATE >= $2 - AND a.timestamp::DATE <= $3 -), -abwesenheiten AS ( - SELECT - datum::DATE AS work_date, - abwesenheit_typ - FROM abwesenheit - WHERE card_uid = $1 - AND datum::DATE >= $2 - AND datum::DATE <= $3 -) -SELECT - d.work_date, - COALESCE(MIN(b.timestamp), NOW()) AS time_from, - COALESCE(MAX(b.timestamp), NOW()) AS time_to, - COALESCE( - EXTRACT(EPOCH FROM SUM( - CASE - WHEN b.prev_check IN (1, 3) AND b.check_in_out IN (2, 4, 254) - THEN b.timestamp - b.prev_timestamp - ELSE INTERVAL '0' - END - )), 0 - ) AS total_work_seconds, - COALESCE( - EXTRACT(EPOCH FROM SUM( - CASE - WHEN b.prev_check IN (2, 4, 254) AND b.check_in_out IN (1, 3) - THEN b.timestamp - b.prev_timestamp - ELSE INTERVAL '0' - END - )), 0 - ) AS total_pause_seconds, - COALESCE(jsonb_agg(jsonb_build_object( - 'check_in_out', b.check_in_out, - 'timestamp', b.timestamp, - 'counter_id', b.counter_id, - 'anwesenheit_typ', b.anwesenheit_typ, - 'anwesenheit_typ', jsonb_build_object( - 'anwesenheit_id', b.anwesenheit_typ, - 'anwesenheit_name', b.anwesenheit_typ_name - ) - ) ORDER BY b.timestamp), '[]'::jsonb) AS bookings, - a.abwesenheit_typ -FROM all_days d -LEFT JOIN ordered_bookings b ON d.work_date = b.work_date -LEFT JOIN abwesenheiten a ON d.work_date = a.work_date -GROUP BY d.work_date, a.abwesenheit_typ -ORDER BY d.work_date ASC;`) + WITH all_days AS ( + SELECT generate_series($2::DATE, $3::DATE - INTERVAL '1 day', INTERVAL '1 day')::DATE AS work_date), + ordered_bookings AS ( + SELECT + a.timestamp::DATE AS work_date, + a.timestamp, + a.check_in_out, + a.counter_id, + a.anwesenheit_typ, + sat.anwesenheit_name AS anwesenheit_typ_name, + LAG(a.timestamp) OVER (PARTITION BY a.card_uid, a.timestamp::DATE ORDER BY a.timestamp) AS prev_timestamp, + LAG(a.check_in_out) OVER (PARTITION BY a.card_uid, a.timestamp::DATE ORDER BY a.timestamp) AS prev_check + FROM anwesenheit a + LEFT JOIN s_anwesenheit_typen sat ON a.anwesenheit_typ = sat.anwesenheit_id + WHERE a.card_uid = $1 + AND a.timestamp::DATE >= $2 + AND a.timestamp::DATE <= $3 + ) + SELECT + d.work_date, + COALESCE(MIN(b.timestamp), NOW()) AS time_from, + COALESCE(MAX(b.timestamp), NOW()) AS time_to, + COALESCE( + EXTRACT(EPOCH FROM SUM( + CASE + WHEN b.prev_check IN (1, 3) AND b.check_in_out IN (2, 4, 254) + THEN b.timestamp - b.prev_timestamp + ELSE INTERVAL '0' + END + )), 0 + ) AS total_work_seconds, + COALESCE( + EXTRACT(EPOCH FROM SUM( + CASE + WHEN b.prev_check IN (2, 4, 254) AND b.check_in_out IN (1, 3) + THEN b.timestamp - b.prev_timestamp + ELSE INTERVAL '0' + END + )), 0 + ) AS total_pause_seconds, + COALESCE(jsonb_agg(jsonb_build_object( + 'check_in_out', b.check_in_out, + 'timestamp', b.timestamp, + 'counter_id', b.counter_id, + 'anwesenheit_typ', b.anwesenheit_typ, + 'anwesenheit_typ', jsonb_build_object( + 'anwesenheit_id', b.anwesenheit_typ, + 'anwesenheit_name', b.anwesenheit_typ_name + ) + ) ORDER BY b.timestamp), '[]'::jsonb) AS bookings + FROM all_days d + LEFT JOIN ordered_bookings b ON d.work_date = b.work_date + GROUP BY d.work_date + ORDER BY d.work_date ASC;`) if err != nil { log.Println("Error preparing SQL statement", err) @@ -107,8 +218,7 @@ ORDER BY d.work_date ASC;`) for rows.Next() { var workDay WorkDay var bookings []byte - var absenceType sql.NullInt16 - if err := rows.Scan(&workDay.Day, &workDay.TimeFrom, &workDay.TimeTo, &workSec, &pauseSec, &bookings, &absenceType); err != nil { + if err := rows.Scan(&workDay.Day, &workDay.TimeFrom, &workDay.TimeTo, &workSec, &pauseSec, &bookings); err != nil { log.Println("Error scanning row!", err) return workDays } @@ -123,21 +233,8 @@ ORDER BY d.work_date ASC;`) if len(workDay.Bookings) == 1 && workDay.Bookings[0].CounterId == 0 { workDay.Bookings = []Booking{} } - - if absenceType.Valid { - workDay.Absence, err = NewAbsence(user.CardUID, int(absenceType.Int16), workDay.Day) - workDay.CalcRealWorkTime(user) - } - - if workDay.Day.Equal(time.Now().Truncate(24 * time.Hour)) { - workDay.CalcRealWorkTime(user) - workDay.CalcWorkPauseDiff(user) - } else { - workDay.CalcWorkPauseDiff(user) - } - if emptyDays && workDay.Day.Weekday() >= 1 && workDay.Day.Weekday() <= 5 { - workDays = append(workDays, workDay) - } else if len(workDay.Bookings) > 0 || (workDay.Absence != Absence{}) { + workDay.TimePauseReal(user) + if emptyDays && !helper.IsWeekend(workDay.Date()) { workDays = append(workDays, workDay) } } @@ -147,65 +244,16 @@ ORDER BY d.work_date ASC;`) return workDays } -func (d *WorkDay) CalcWorkPauseDiff(user User) (work, pause time.Duration) { - if d.workTime == 0 { - d.CalcRealWorkTime(user) +func (d *WorkDay) GetAllWorkTimesReal(user User) (work, pause, overtime time.Duration) { + if d.pauseTime == 0 || d.workTime == 0 { + d.TimePauseReal(user) } - if d.Absence.AbwesenheitTyp.WorkTime > 0 { - return d.workTime, d.pauseTime - } - if d.workTime <= 6*time.Hour || d.pauseTime > 45*time.Minute { - return d.workTime, d.pauseTime - } - if d.workTime <= (9*time.Hour) && d.pauseTime < 30*time.Minute { - diff := 30*time.Minute - d.pauseTime - d.workTime -= diff - d.pauseTime += diff - } else if d.pauseTime < 45*time.Minute { - diff := 45*time.Minute - d.pauseTime - d.workTime -= diff - d.pauseTime += diff - } - - return d.workTime, d.pauseTime + return d.workTime.Round(time.Minute), d.pauseTime.Round(time.Minute), d.TimeOvertimeReal(user) } -func (d *WorkDay) CalcRealWorkTime(user User) time.Duration { - if (len(d.Bookings) < 1 && d.Absence == Absence{}) { - return 0 - } - var realWorkTime, realPauseTime time.Duration - var lastBooking Booking - for _, booking := range d.Bookings { - if booking.CheckInOut%2 == 1 { - if !lastBooking.Timestamp.IsZero() { - realPauseTime += booking.Timestamp.Sub(lastBooking.Timestamp) - } - } else { - realWorkTime += booking.Timestamp.Sub(lastBooking.Timestamp) - } - lastBooking = booking - } - if helper.IsSameDate(d.Day, time.Now()) && len(d.Bookings)%2 == 1 { - realWorkTime += time.Since(lastBooking.Timestamp.Local()) - } - if d.Absence.AbwesenheitTyp.WorkTime > 0 { - realWorkTime = time.Duration(user.ArbeitszeitPerTag * float32(time.Hour)).Round(time.Minute) - } - d.workTime = realWorkTime - d.pauseTime = realPauseTime - - return realWorkTime -} - -func (d *WorkDay) GetWorkTimeString() (work string, pause string) { - workString := helper.FormatDuration(d.workTime) - pauseString := helper.FormatDuration(d.pauseTime) - return workString, pauseString -} - -func (d *WorkDay) GetAllWorkTimes(user User) (work, pause, overtime time.Duration) { - return d.workTime.Round(time.Minute), d.pauseTime.Round(time.Minute), d.CalcOvertime(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 @@ -216,21 +264,23 @@ func (d *WorkDay) RequiresAction() bool { return d.Bookings[len(d.Bookings)-1].CheckInOut == 254 } -// returns a integer percentage of how much day has been worked of -func (d *WorkDay) GetWorkDayProgress(user User) uint8 { - defaultWorkTime := time.Duration(user.ArbeitszeitPerTag * float32(time.Hour)).Round(time.Minute) - progress := (d.workTime.Seconds() / defaultWorkTime.Seconds()) * 100 - return uint8(progress) +func (d *WorkDay) GetDayProgress(u User) int8 { + if d.RequiresAction() { + return -1 + } + workTime := d.TimeWorkVirtual(u) + progress := (workTime.Seconds() / u.ArbeitszeitProTag().Seconds()) * 100 + return int8(progress) } -func (d *WorkDay) CalcOvertime(user User) time.Duration { - if d.workTime == 0 { - d.CalcWorkPauseDiff(user) - } - if helper.IsWeekend(d.Day) && len(d.Bookings) == 0 { - return 0 - } - var overtime time.Duration - overtime = d.workTime - time.Duration(user.ArbeitszeitPerTag*float32(time.Hour)).Round(time.Minute) - return overtime -} +// 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 5b26ea7..abc3d89 100644 --- a/Backend/models/workDay_test.go +++ b/Backend/models/workDay_test.go @@ -20,11 +20,10 @@ var testWorkDay = models.WorkDay{ Bookings: testBookings8hrs, TimeFrom: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 08:00")), TimeTo: CatchError(time.Parse("2006-01-02 15:04", "2025-01-01 16:30")), - Absence: models.Absence{}, } func TestCalcRealWorkTime(t *testing.T) { - workTime := testWorkDay.CalcRealWorkTime(testUser) + 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)) } @@ -64,10 +63,10 @@ func TestCalcWorkPauseDiff(t *testing.T) { for _, test := range testCases { t.Run(test.Name, func(t *testing.T) { testWorkDay.Bookings = test.bookings - testWorkDay.CalcRealWorkTime(testUser) - testWorkDay.CalcWorkPauseDiff(testUser) - testWorkDay.CalcOvertime(testUser) - workTime, pauseTime, overTime := testWorkDay.GetAllWorkTimes(testUser) + 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)) } diff --git a/Backend/models/workWeek.go b/Backend/models/workWeek.go index fb7d6a7..aeb7879 100644 --- a/Backend/models/workWeek.go +++ b/Backend/models/workWeek.go @@ -1,10 +1,10 @@ package models import ( - "arbeitszeitmessung/helper" "database/sql" "errors" "log" + "sort" "time" ) @@ -14,6 +14,7 @@ type WorkWeek struct { Id int WorkDays []WorkDay Absences []Absence + Days []IWorkDay User User WeekStart time.Time Worktime time.Duration @@ -39,20 +40,21 @@ func NewWorkWeek(user User, tsMonday time.Time, populate bool) WorkWeek { Status: WeekStatusNone, } if populate { - week.PopulateWithBookings(0, 0) + week.PopulateWithDays(0, 0) } return week } -func (w *WorkWeek) PopulateWithBookings(worktime time.Duration, overtime time.Duration) { - w.WorkDays = GetWorkDays(w.User, w.WeekStart, w.WeekStart.Add(7*24*time.Hour)) - if absences, err := GetAbsencesByCardUID(w.User.CardUID, w.WeekStart, w.WeekStart.Add(7*24*time.Hour)); err == nil { - w.Absences = absences - } else { - log.Printf("Error populating absences in workWeek (%s): %v", w.WeekStart, err) +func (w *WorkWeek) PopulateWithDays(worktime time.Duration, overtime time.Duration) { + w.Days = GetDays(w.User, w.WeekStart, w.WeekStart.Add(6*24*time.Hour)) + sort.Slice(w.Days, func(i, j int) bool { + return w.Days[i].Date().Before(w.Days[j].Date()) + }) + + for _, day := range w.Days { + w.Worktime += day.TimeWorkVirtual(w.User) } - w.Worktime = w.aggregateWorkTime() - w.Overtime = w.Worktime - time.Duration(w.User.ArbeitszeitPerWoche*float32(time.Hour)) + w.Overtime = w.Worktime - w.User.ArbeitszeitProWoche() w.Worktime = w.Worktime.Round(time.Minute) w.Overtime = w.Overtime.Round(time.Minute) @@ -99,10 +101,6 @@ func (w *WorkWeek) CheckStatus() WeekStatus { return w.Status } -func (w *WorkWeek) GetWorkHourString() string { - return helper.FormatDuration(w.Worktime) -} - func (w *WorkWeek) aggregateWorkTime() time.Duration { var workTime time.Duration for _, day := range w.WorkDays { @@ -138,7 +136,7 @@ func (w *WorkWeek) GetSendWeeks(user User) []WorkWeek { return weeks } - week.PopulateWithBookings(week.Worktime, week.Overtime) + week.PopulateWithDays(week.Worktime, week.Overtime) weeks = append(weeks, week) } if err = rows.Err(); err != nil { @@ -196,8 +194,8 @@ func (w *WorkWeek) Accept() error { } func (w *WorkWeek) RequiresAction() bool { - var requiresAction bool = true - for _, day := range w.WorkDays { + var requiresAction bool = false + for _, day := range w.Days { requiresAction = requiresAction || day.RequiresAction() } return requiresAction diff --git a/Backend/static/css/styles.css b/Backend/static/css/styles.css index 53202ab..143d6f3 100644 --- a/Backend/static/css/styles.css +++ b/Backend/static/css/styles.css @@ -330,9 +330,6 @@ .h-full { height: 100%; } - .w-1\/7 { - width: calc(1/7 * 100%); - } .w-2 { width: calc(var(--spacing) * 2); } @@ -363,9 +360,6 @@ .grow-1 { flex-grow: 1; } - .border-collapse { - border-collapse: collapse; - } .cursor-pointer { cursor: pointer; } @@ -448,6 +442,9 @@ .overflow-hidden { overflow: hidden; } + .rounded { + border-radius: 0.25rem; + } .rounded-full { border-radius: calc(infinity * 1px); } @@ -458,22 +455,10 @@ border-style: var(--tw-border-style); border-width: 1px; } - .border-1 { - border-style: var(--tw-border-style); - border-width: 1px; - } - .border-t-1 { - border-top-style: var(--tw-border-style); - border-top-width: 1px; - } .border-r-0 { border-right-style: var(--tw-border-style); border-right-width: 0px; } - .border-r-1 { - border-right-style: var(--tw-border-style); - border-right-width: 1px; - } .border-b-0 { border-bottom-style: var(--tw-border-style); border-bottom-width: 0px; @@ -592,16 +577,6 @@ --tw-duration: 300ms; transition-duration: 300ms; } - .\*\:\*\:\*\:border-1 { - :is(& > *) { - :is(& > *) { - :is(& > *) { - border-style: var(--tw-border-style); - border-width: 1px; - } - } - } - } .\*\:text-center { :is(& > *) { text-align: center; diff --git a/Backend/templates/pages.templ b/Backend/templates/pages.templ index b7865cf..2b938bf 100644 --- a/Backend/templates/pages.templ +++ b/Backend/templates/pages.templ @@ -1,10 +1,7 @@ package templates import ( - "arbeitszeitmessung/helper" "arbeitszeitmessung/models" - "fmt" - "strconv" "time" ) @@ -19,13 +16,17 @@ templ Base() { } templ TimePage(workDays []models.WorkDay, lastSub time.Time) { + {{ + allDays := ctx.Value("days").([]models.IWorkDay) + }} @Base() @headerComponent()
Arbeitszeit: { fmt.Sprintf("%s", helper.FormatDuration(userWeek.Worktime)) }
-Überstunden: { fmt.Sprintf("%s", helper.FormatDuration(userWeek.Overtime)) }
-Arbeitszeit: { fmt.Sprintf("%s", helper.FormatDuration(userWeek.Worktime)) }
+ //Überstunden: { fmt.Sprintf("%s", helper.FormatDurationFill(userWeek.Overtime, true)) }
+ //Arbeitszeit: ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var9 string - templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(userWeek.Worktime))) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 125, Col: 84} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "
Überstunden: ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var10 string - templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(userWeek.Overtime))) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 126, Col: 85} - } - _, 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, 24, "
{ day.Bookings[bookingI+1].Timestamp.Format("15:04") }
{ day.Bookings[bookingI].BookingType.Name }
} - if (day.Absence != models.Absence{}) { -{ day.Absence.AbwesenheitTyp.Name }
- } + // if (day.Absence != models.Absence{}) { + //{ day.Absence.AbwesenheitTyp.Name }
+ // }") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var13 string - templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(day.Absence.AbwesenheitTyp.Name) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 44, Col: 64} - } - _, 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, 15, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - work, pause, overtime := day.GetAllWorkTimes(e) + work, pause, overtime := day.GetAllWorkTimesReal(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, 17, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -228,7 +209,7 @@ func PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Tim if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -236,18 +217,18 @@ func PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Tim if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if day.Day.Weekday() == time.Friday { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "Wochenende
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "Wochenende
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -271,9 +252,9 @@ func ColorDuration(d time.Duration, classes string) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var14 := templ.GetChildren(ctx) - if templ_7745c5c3_Var14 == nil { - templ_7745c5c3_Var14 = templ.NopComponent + templ_7745c5c3_Var13 := templ.GetChildren(ctx) + if templ_7745c5c3_Var13 == nil { + templ_7745c5c3_Var13 = templ.NopComponent } ctx = templ.ClearChildren(ctx) @@ -281,38 +262,38 @@ func ColorDuration(d time.Duration, classes string) templ.Component { if d.Abs() < time.Minute { color = "text-neutral-300" } - var templ_7745c5c3_Var15 = []any{color + " " + classes} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var15...) + var templ_7745c5c3_Var14 = []any{color + " " + classes} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...) 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_Var16 string - templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var15).String()) + templ_7745c5c3_Var16, 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: 1, Col: 0} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 66, Col: 72} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "\">") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var17 string - templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDurationFill(d, true)) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 66, Col: 72} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/Backend/templates/teamComponents.templ b/Backend/templates/teamComponents.templ index 71ed2bd..33be818 100644 --- a/Backend/templates/teamComponents.templ +++ b/Backend/templates/teamComponents.templ @@ -26,80 +26,140 @@ templ weekPicker(weekStart time.Time) { - if time.Since(weekStart) < 24*7*time.Hour { -Die Woche kann erst am nächsten Montag gesendet werden!
- } } -templ weekDayComponent(user models.User, day models.WorkDay) { - {{ work, pause := day.GetWorkTimeString() }} +templ defaultWeekDayComponent(u models.User, day models.IWorkDay) {{ day.Day.Format("02.01.2006") }
- if !day.RequiresAction() { -{ day.Absence.AbwesenheitTyp.Name }
- case !day.TimeFrom.Equal(day.TimeTo): - { day.TimeFrom.Format("15:04") } - - - { day.TimeTo.Format("15:04") } - default: -Keine Anwesenheit
- } -{ day.Date().Format("02.01.2006") }
+ if day.IsWorkDay() { + {{ + workDay, _ := day.(*models.WorkDay) + work, pause, _ := workDay.GetAllWorkTimesReal(u) + }} + if !workDay.RequiresAction() { +Keine Anwesenheit
+ } +Bitte anpassen
+ } } else { -Bitte anpassen
+ {{ + absentDay, _ := day.(*models.Absence) + }} +{ week.User.Vorname } { week.User.Name }
-Arbeitszeit: { fmt.Sprintf("%s", helper.FormatDuration(week.Worktime)) }
-Überstunden: { fmt.Sprintf("%s", helper.FormatDuration(week.Overtime)) }
+Arbeitszeit: { fmt.Sprintf("%s", helper.FormatDuration(week.Worktime)) }
+Überstunden: { fmt.Sprintf("%s", helper.FormatDurationFill(week.Overtime, true)) }
+Die Woche kann erst am nächsten Montag gesendet werden!
") + return nil + }) +} + +func defaultWeekDayComponent(u models.User, day models.IWorkDay) 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_Var6 := templ.GetChildren(ctx) + if templ_7745c5c3_Var6 == nil { + templ_7745c5c3_Var6 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(day.Date().Format("Mon")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 35, Col: 92} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, ": ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var8 string + templ_7745c5c3_Var8, 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/teamComponents.templ`, Line: 35, Col: 136} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if day.IsWorkDay() { + + workDay, _ := day.(*models.WorkDay) + work, pause, _ := workDay.GetAllWorkTimesReal(u) + if !workDay.RequiresAction() { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "Keine Anwesenheit
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "Bitte anpassen
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + } else { + + absentDay, _ := day.(*models.Absence) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var7 string - templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(day.Day.Format("Mon")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 39, Col: 89} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, ": ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var8 string - templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(day.Day.Format("02.01.2006")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 39, Col: 130} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var11 string - templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(day.Absence.AbwesenheitTyp.Name) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 52, Col: 43} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case !day.TimeFrom.Equal(day.TimeTo): - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var12 string - templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(day.TimeFrom.Format("15:04")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 54, Col: 43} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, " - ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var13 string - templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(day.TimeTo.Format("15:04")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 56, Col: 41} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - default: - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "Keine Anwesenheit
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "Bitte anpassen
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var16 string - templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(week.User.Name) + templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(week.User.Vorname) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 75, Col: 72} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 93, Col: 53} } _, 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, 29, "
Arbeitszeit: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var17 string - templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(week.Worktime))) + templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(week.User.Name) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 79, Col: 78} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 93, Col: 72} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "
Überstunden: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "
Arbeitszeit: ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var18 string - templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(week.Overtime))) + templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDuration(week.Worktime))) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 80, Col: 79} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 110, Col: 79} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "
Woche: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
Überstunden: ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var19 string - templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d-%d", kw, year)) + templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s", helper.FormatDurationFill(week.Overtime, true))) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 90, Col: 85} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 111, Col: 90} } _, 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, 34, "
Unterschiedliche Arbeitszeit zwischen Abrechnung und individuellen Buchungen
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + switch { + case week.RequiresAction(): + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "bitte zuerst Buchungen anpassen
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + case time.Since(week.WeekStart) < 24*7*time.Hour: + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "Die Woche kann erst am nächsten Montag gesendet werden!
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + case week.Status == models.WeekStatusNone: + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "an Vorgesetzten senden
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + case week.Status == models.WeekStatusSent: + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "an Vorgesetzten gesendet
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + case week.Status == models.WeekStatusAccepted: + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "vom Vorgesetzten bestätigt
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var23 string - templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(user.Vorname) + var templ_7745c5c3_Var25 string + templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(user.Vorname) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 113, Col: 19} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 173, Col: 19} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23)) + _, 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, 45, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var24 string - templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(user.Name) + var templ_7745c5c3_Var26 string + templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(user.Name) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 113, Col: 33} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 173, Col: 33} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24)) + _, 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, 46, "
{ day.Date().Format("02.01.2006") }
+{ absentDay.AbwesenheitTyp.Name } bis { absentDay.DateTo.Format("02.01.2006") }
+{ workDay.Day.Format("02.01.2006") }
- if work!="" { -Arbeitszeit:
- if (workDay.RequiresAction()) { -Bitte anpassen
- } else { -{ work }
- if pause != "" { -{ pause }
- } - if overtime != "" { -{ overtime }
- } + if (workDay.RequiresAction()) { +Bitte anpassen
+ } else { + if work > 0 { +Arbeitszeit:
+{ helper.FormatDuration(work) }
+ } + if pause > 0 { +{ helper.FormatDuration(pause) }
+ } + if overtime > 0 { +{ helper.FormatDuration(overtime) }
} }{ workDay.Absence.AbwesenheitTyp.Name }
- } - if len(workDay.Bookings) < 1 && (workDay.Absence == models.Absence{}) { + if len(workDay.Bookings) < 1 {Keine Buchung gefunden. Bitte Arbeitsstunden oder Grund der Abwesenheit eingeben!
@absenceComponent(workDay) @newBookingComponent(workDay) @@ -83,6 +109,9 @@ templ dayComponent(workDay models.WorkDay, submitted bool) { for _, booking := range workDay.Bookings { @bookingComponent(booking) } + if workDay.IsKurzArbeit() { +Kurzarbeit
+ } @newBookingComponent(workDay) } @@ -105,11 +134,11 @@ templ changeButtonComponent(id string) { } -templ timeGaugeComponent(progress uint8, today bool, warning bool) { +templ timeGaugeComponent(progress int8, today bool) { {{ var bgColor string switch { - case (warning): + case (0 > progress): bgColor = "bg-red-600" break case (progress > 0 && progress < 95): diff --git a/Backend/templates/timeComponents_templ.go b/Backend/templates/timeComponents_templ.go index 83fc257..8beaef4 100644 --- a/Backend/templates/timeComponents_templ.go +++ b/Backend/templates/timeComponents_templ.go @@ -109,7 +109,7 @@ func inputForm() templ.Component { }) } -func dayComponent(workDay models.WorkDay, submitted bool) templ.Component { +func defaultDayComponent(day models.IWorkDay) 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 { @@ -130,143 +130,278 @@ func dayComponent(workDay models.WorkDay, submitted bool) templ.Component { templ_7745c5c3_Var6 = templ.NopComponent } ctx = templ.ClearChildren(ctx) + if day.IsWorkDay() { - work, pause := workDay.GetWorkTimeString() + workDay, _ := day.(*models.WorkDay) + templ_7745c5c3_Err = workDayComponent(*workDay, false).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + + absentDay, _ := day.(*models.Absence) + var templ_7745c5c3_Var7 = []any{"grid-sub divide-x-1 hover:bg-neutral-200 transition-colors"} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var9 string + templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(day.Date().Format("Mon")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 53, Col: 84} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, ": ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var10 string + templ_7745c5c3_Var10, 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/timeComponents.templ`, Line: 53, Col: 128} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var11 string + templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(absentDay.AbwesenheitTyp.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 58, Col: 39} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, " bis ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var12 string + templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(absentDay.DateTo.Format("02.01.2006")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 58, Col: 116} + } + _, 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, 14, "
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var9 string
- templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Day.Format("Mon"))
+ var templ_7745c5c3_Var16 string
+ templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Day.Format("Mon"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 54, Col: 94}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 83, Col: 94}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
+ _, 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, 10, ": ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, ": ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var10 string
- templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Day.Format("02.01.2006"))
+ var templ_7745c5c3_Var17 string
+ templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Day.Format("02.01.2006"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 54, Col: 139}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 83, Col: 139}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " Arbeitszeit: Bitte anpassen Bitte anpassen Arbeitszeit: ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- } else {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, " ")
+ var templ_7745c5c3_Var18 string
+ templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(work))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 89, Col: 172}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var11 string
- templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(work)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 60, Col: 149}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- if pause != "" {
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, " ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var12 string
- templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(pause)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 62, Col: 150}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, " ")
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- var templ_7745c5c3_Var13 string
- templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(overtime)
- if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 65, Col: 134}
- }
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
- if templ_7745c5c3_Err != nil {
- return templ_7745c5c3_Err
- }
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, " ")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var20 string
+ templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(overtime))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 95, Col: 156}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
+ 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 - } - var templ_7745c5c3_Var16 string - templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Absence.AbwesenheitTyp.Name) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 75, Col: 45} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if len(workDay.Bookings) < 1 && (workDay.Absence == models.Absence{}) { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "Keine Buchung gefunden. Bitte Arbeitsstunden oder Grund der Abwesenheit eingeben!
") + if len(workDay.Bookings) < 1 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "Keine Buchung gefunden. Bitte Arbeitsstunden oder Grund der Abwesenheit eingeben!
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -332,7 +448,7 @@ func dayComponent(workDay models.WorkDay, submitted bool) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -351,7 +467,17 @@ func dayComponent(workDay models.WorkDay, submitted bool) templ.Component { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if workDay.IsKurzArbeit() { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "Kurzarbeit
") + 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 } @@ -360,7 +486,7 @@ func dayComponent(workDay models.WorkDay, submitted bool) templ.Component { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "Ändern
Absenden
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -418,7 +544,7 @@ func changeButtonComponent(id string) templ.Component { }) } -func timeGaugeComponent(progress uint8, today bool, warning bool) templ.Component { +func timeGaugeComponent(progress int8, today bool) 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 { @@ -434,15 +560,15 @@ func timeGaugeComponent(progress uint8, today bool, warning bool) templ.Componen }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var19 := templ.GetChildren(ctx) - if templ_7745c5c3_Var19 == nil { - templ_7745c5c3_Var19 = templ.NopComponent + templ_7745c5c3_Var25 := templ.GetChildren(ctx) + if templ_7745c5c3_Var25 == nil { + templ_7745c5c3_Var25 = templ.NopComponent } ctx = templ.ClearChildren(ctx) var bgColor string switch { - case (warning): + case (0 > progress): bgColor = "bg-red-600" break case (progress > 0 && progress < 95): @@ -459,65 +585,65 @@ func timeGaugeComponent(progress uint8, today bool, warning bool) templ.Componen break } if today { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var34 string
- templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(booking.Timestamp.Format("15:04"))
+ var templ_7745c5c3_Var40 string
+ templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.JoinStringErrs(booking.Timestamp.Format("15:04"))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 177, Col: 97}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 206, Col: 97}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var40))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "\" class=\"text-neutral-700 group-[.edit]:inline hidden bg-neutral-100 text-sm border border-neutral-200 rounded-md px-3 py-2 transition duration-300 ease focus:outline-none focus:border-neutral-400 hover:border-neutral-300\"> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var37 string
- templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(booking.GetBookingType())
+ var templ_7745c5c3_Var43 string
+ templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.JoinStringErrs(booking.GetBookingType())
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 179, Col: 29}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 208, Col: 29}
}
- _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37))
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var43))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "