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()
@inputForm() - for _, day := range workDays { - @dayComponent(day, day.Day.Before(lastSub)) - if (day.Day.Weekday() == time.Monday) { + for _, day := range allDays { + @defaultDayComponent(day) + // @dayComponent(day, day.Day.Before(lastSub)) + if (day.Date().Weekday() == time.Monday) {
} } @@ -95,72 +96,75 @@ templ statusCheckMark(status models.WeekStatus, target models.WeekStatus) { templ TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) { @Base() @headerComponent() - {{ - progress := (float32(userWeek.Worktime.Hours()) / userWeek.User.ArbeitszeitPerWoche) * 100 - }}

Eigene Abrechnung

-
-
- @weekPicker(userWeek.WeekStart) -
-

{ fmt.Sprintf("%s %s", userWeek.User.Vorname, userWeek.User.Name) }

-
-
- - @statusCheckMark(userWeek.CheckStatus(), models.WeekStatusSent) - Gesendet - - - @statusCheckMark(userWeek.CheckStatus(), models.WeekStatusAccepted) - Akzeptiert - -
-
- @timeGaugeComponent(uint8(progress), false, false) -
-

Arbeitszeit: { fmt.Sprintf("%s", helper.FormatDuration(userWeek.Worktime)) }

-

Überstunden: { fmt.Sprintf("%s", helper.FormatDuration(userWeek.Overtime)) }

-
-
-
-
-
- for _, day := range userWeek.WorkDays { - @weekDayComponent(userWeek.User, day) - } -
-
-
- @weekPicker(userWeek.WeekStart) -
-
- - - - switch userWeek.CheckStatus() { - case models.WeekStatusNone: -

an Vorgesetzten senden

- case models.WeekStatusSent: -

an Vorgesetzten gesendet

- case models.WeekStatusAccepted: -

vom Vorgesetzten bestätigt

- } - - -
-
+ @workWeekComponent(userWeek, false) + //
+ //
+ //

Eigene Abrechnung

+ //
+ //
+ //
+ // @weekPicker(userWeek.WeekStart) + //
+ //

{ fmt.Sprintf("%s %s", userWeek.User.Vorname, userWeek.User.Name) }

+ //
+ //
+ // + // @statusCheckMark(userWeek.CheckStatus(), models.WeekStatusSent) + // Gesendet + // + // + // @statusCheckMark(userWeek.CheckStatus(), models.WeekStatusAccepted) + // Akzeptiert + // + //
+ //
+ // @timeGaugeComponent(int8(progress), false) + //
+ //

Arbeitszeit: { fmt.Sprintf("%s", helper.FormatDuration(userWeek.Worktime)) }

+ //

Überstunden: { fmt.Sprintf("%s", helper.FormatDurationFill(userWeek.Overtime, true)) }

+ //
+ //
+ //
+ //
+ //
+ // for _, day := range userWeek.Days { + // @defaultWeekDayComponent(userWeek.User, day) + // } + //
+ //
+ //
+ // @weekPicker(userWeek.WeekStart) + //
+ //
+ // + // + // + // switch userWeek.CheckStatus() { + // case models.WeekStatusNone: + //

an Vorgesetzten senden

+ // case models.WeekStatusSent: + //

an Vorgesetzten gesendet

+ // case models.WeekStatusAccepted: + //

vom Vorgesetzten bestätigt

+ // } + // + // + //
+ //
+ //
if len(weeks) > 0 {

Abrechnung Mitarbeiter

} for _, week := range weeks { - @employeComponent(week) + @workWeekComponent(week, true) }
} diff --git a/Backend/templates/pages_templ.go b/Backend/templates/pages_templ.go index d546e65..0dbe185 100644 --- a/Backend/templates/pages_templ.go +++ b/Backend/templates/pages_templ.go @@ -9,10 +9,7 @@ import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" import ( - "arbeitszeitmessung/helper" "arbeitszeitmessung/models" - "fmt" - "strconv" "time" ) @@ -66,6 +63,8 @@ func TimePage(workDays []models.WorkDay, lastSub time.Time) templ.Component { templ_7745c5c3_Var2 = templ.NopComponent } ctx = templ.ClearChildren(ctx) + + allDays := ctx.Value("days").([]models.IWorkDay) templ_7745c5c3_Err = Base().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err @@ -82,16 +81,16 @@ func TimePage(workDays []models.WorkDay, lastSub time.Time) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - for _, day := range workDays { - templ_7745c5c3_Err = dayComponent(day, day.Day.Before(lastSub)).Render(ctx, templ_7745c5c3_Buffer) + for _, day := range allDays { + templ_7745c5c3_Err = defaultDayComponent(day).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - if day.Day.Weekday() == time.Monday { + if day.Date().Weekday() == time.Monday { templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err @@ -147,7 +146,7 @@ func LoginPage(success bool, errorMsg string) templ.Component { var templ_7745c5c3_Var4 string templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(errorMsg) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 45, Col: 46} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 46, Col: 46} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { @@ -289,181 +288,27 @@ func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) templ.Component if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - - progress := (float32(userWeek.Worktime.Hours()) / userWeek.User.ArbeitszeitPerWoche) * 100 - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "

Eigene Abrechnung

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "

Eigene Abrechnung

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = weekPicker(userWeek.WeekStart).Render(ctx, templ_7745c5c3_Buffer) - 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_Var8 string - templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s %s", userWeek.User.Vorname, userWeek.User.Name)) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pages.templ`, Line: 110, Col: 101} - } - _, 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, 19, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = statusCheckMark(userWeek.CheckStatus(), models.WeekStatusSent).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "Gesendet ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = statusCheckMark(userWeek.CheckStatus(), models.WeekStatusAccepted).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "Akzeptiert
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = timeGaugeComponent(uint8(progress), false, false).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "

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, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for _, day := range userWeek.WorkDays { - templ_7745c5c3_Err = weekDayComponent(userWeek.User, day).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = weekPicker(userWeek.WeekStart).Render(ctx, templ_7745c5c3_Buffer) - 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 - } - switch userWeek.CheckStatus() { - case models.WeekStatusNone: - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "

an Vorgesetzten senden

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case models.WeekStatusSent: - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "

an Vorgesetzten gesendet

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case models.WeekStatusAccepted: - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "

vom Vorgesetzten bestätigt

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "Korrigieren = models.WeekStatusSent || userWeek.RequiresAction() { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, " disabled") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, " type=\"submit\" class=\"btn\">Senden
") + templ_7745c5c3_Err = workWeekComponent(userWeek, false).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if len(weeks) > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "

Abrechnung Mitarbeiter

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "

Abrechnung Mitarbeiter

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } for _, week := range weeks { - templ_7745c5c3_Err = employeComponent(week).Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = workWeekComponent(week, true).Render(ctx, templ_7745c5c3_Buffer) 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, 19, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -487,9 +332,9 @@ func TeamPresencePage(teamPresence map[bool][]models.User) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var13 := templ.GetChildren(ctx) - if templ_7745c5c3_Var13 == nil { - templ_7745c5c3_Var13 = templ.NopComponent + templ_7745c5c3_Var8 := templ.GetChildren(ctx) + if templ_7745c5c3_Var8 == nil { + templ_7745c5c3_Var8 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = Base().Render(ctx, templ_7745c5c3_Buffer) @@ -500,7 +345,7 @@ func TeamPresencePage(teamPresence map[bool][]models.User) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "

Anwesend

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "

Anwesend

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -510,7 +355,7 @@ func TeamPresencePage(teamPresence map[bool][]models.User) templ.Component { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "

Nicht Anwesend

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "

Nicht Anwesend

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -520,7 +365,7 @@ func TeamPresencePage(teamPresence map[bool][]models.User) templ.Component { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -544,12 +389,12 @@ func LogoutButton() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var14 := templ.GetChildren(ctx) - if templ_7745c5c3_Var14 == nil { - templ_7745c5c3_Var14 = templ.NopComponent + templ_7745c5c3_Var9 := templ.GetChildren(ctx) + if templ_7745c5c3_Var9 == nil { + templ_7745c5c3_Var9 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/Backend/templates/pdf.templ b/Backend/templates/pdf.templ index 7b8fbda..ad6c6b9 100644 --- a/Backend/templates/pdf.templ +++ b/Backend/templates/pdf.templ @@ -40,11 +40,11 @@ templ PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Ti

{ 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 }

+ // }
- {{ work, pause, overtime := day.GetAllWorkTimes(e) }} + {{ work, pause, overtime := day.GetAllWorkTimesReal(e) }} @ColorDuration(work, noBorder) @ColorDuration(pause, noBorder) @ColorDuration(overtime, noBorder+" border-r-0") diff --git a/Backend/templates/pdf_templ.go b/Backend/templates/pdf_templ.go index da116c3..78d3396 100644 --- a/Backend/templates/pdf_templ.go +++ b/Backend/templates/pdf_templ.go @@ -192,35 +192,16 @@ func PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Tim return templ_7745c5c3_Err } } - if (day.Absence != models.Absence{}) { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "

") - 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) {
- @timeGaugeComponent(day.GetWorkDayProgress(user), false, day.RequiresAction()) + @timeGaugeComponent(day.GetDayProgress(u), false)
-

{ day.Day.Format("02.01.2006") }

- if !day.RequiresAction() { -
- { work } - { pause } -
-
- - - - - switch { - case day.Absence.Datum.Equal(day.Day): -

{ day.Absence.AbwesenheitTyp.Name }

- case !day.TimeFrom.Equal(day.TimeTo): - { day.TimeFrom.Format("15:04") } - - - { day.TimeTo.Format("15:04") } - default: -

Keine Anwesenheit

- } -
+

{ day.Date().Format("02.01.2006") }

+ if day.IsWorkDay() { + {{ + workDay, _ := day.(*models.WorkDay) + work, pause, _ := workDay.GetAllWorkTimesReal(u) + }} + if !workDay.RequiresAction() { +
+ { helper.FormatDuration(work) } + { helper.FormatDuration(pause) } +
+
+ + switch { + case !workDay.TimeFrom.Equal(workDay.TimeTo): + { workDay.TimeFrom.Format("15:04") } + - + { workDay.TimeTo.Format("15:04") } + default: +

Keine Anwesenheit

+ } +
+ } else { +

Bitte anpassen

+ } } else { -

Bitte anpassen

+ {{ + absentDay, _ := day.(*models.Absence) + }} +
{ absentDay.AbwesenheitTyp.Name }
}
} -templ employeComponent(week models.WorkWeek) { +templ weekDayComponent(user models.User, day models.WorkDay) { + // {{ work, pause, _ := day.GetAllWorkTimesReal(user) }} +
+ // @timeGaugeComponent(day.GetWorkDayProgress(user), false, day.RequiresAction()) +
+ if !day.RequiresAction() { + } +
+
+} + +templ workWeekComponent(week models.WorkWeek, onlyAccept bool) { {{ year, kw := week.WeekStart.ISOWeek() progress := (float32(week.Worktime.Hours()) / week.User.ArbeitszeitPerWoche) * 100 }}
+ if !onlyAccept { +
+ @weekPicker(week.WeekStart) +
+ }

{ week.User.Vorname } { week.User.Name }

-
- @timeGaugeComponent(uint8(progress), false, false) -
-

Arbeitszeit: { fmt.Sprintf("%s", helper.FormatDuration(week.Worktime)) }

-

Überstunden: { fmt.Sprintf("%s", helper.FormatDuration(week.Overtime)) }

+
+ if !onlyAccept { +
+ + @statusCheckMark(week.CheckStatus(), models.WeekStatusSent) + Gesendet + + + @statusCheckMark(week.CheckStatus(), models.WeekStatusAccepted) + Akzeptiert + +
+ } +
+ @timeGaugeComponent(int8(progress), false) +
+

Arbeitszeit: { fmt.Sprintf("%s", helper.FormatDuration(week.Worktime)) }

+

Überstunden: { fmt.Sprintf("%s", helper.FormatDurationFill(week.Overtime, true)) }

+
-
- for _, day := range week.WorkDays { - @weekDayComponent(week.User, day) +
+ for _, day := range week.Days { + @defaultWeekDayComponent(week.User, day) }
-
-

Woche: { fmt.Sprintf("%02d-%d", kw, year) }

- - - -
- if week.Status == models.WeekStatusDifferences { -

Unterschiedliche Arbeitszeit zwischen Abrechnung und individuellen Buchungen

+
+ if onlyAccept { +

Woche: { fmt.Sprintf("%02d-%d", kw, year) }

+ } else { +
+ @weekPicker(week.WeekStart) +
+ } + + {{ + week.CheckStatus() + method := "accept" + if !onlyAccept { + method = "send" + } + }} + + + + if onlyAccept { + if week.Status == models.WeekStatusDifferences { +

Unterschiedliche Arbeitszeit zwischen Abrechnung und individuellen Buchungen

+ } + + } else { + switch { + case week.RequiresAction(): +

bitte zuerst Buchungen anpassen

+ case time.Since(week.WeekStart) < 24*7*time.Hour: +

Die Woche kann erst am nächsten Montag gesendet werden!

+ case week.Status == models.WeekStatusNone: +

an Vorgesetzten senden

+ case week.Status == models.WeekStatusSent: +

an Vorgesetzten gesendet

+ case week.Status == models.WeekStatusAccepted: +

vom Vorgesetzten bestätigt

+ } + + } - - // TODO maybe delete function - // -
- + +
} diff --git a/Backend/templates/teamComponents_templ.go b/Backend/templates/teamComponents_templ.go index 239425d..1660f58 100644 --- a/Backend/templates/teamComponents_templ.go +++ b/Backend/templates/teamComponents_templ.go @@ -113,11 +113,176 @@ func weekPicker(weekStart time.Time) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - if time.Since(weekStart) < 24*7*time.Hour { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

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 + } + templ_7745c5c3_Err = timeGaugeComponent(day.GetDayProgress(u), false).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var8 string + templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(day.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, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var9 string + templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(work)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 43, Col: 61} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var10 string + templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(pause)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 44, Col: 67} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + switch { + case !workDay.TimeFrom.Equal(workDay.TimeTo): + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var11 string + templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.TimeFrom.Format("15:04")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 50, Col: 48} + } + _, 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, 18, " - ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var12 string + templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.TimeTo.Format("15:04")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 52, Col: 46} + } + _, 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, 19, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + default: + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "

Keine Anwesenheit

") + 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 + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "

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_Var13 string + templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(absentDay.AbwesenheitTyp.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 64, Col: 40} + } + _, 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, 24, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err } return nil }) @@ -139,148 +304,18 @@ func weekDayComponent(user models.User, day models.WorkDay) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var6 := templ.GetChildren(ctx) - if templ_7745c5c3_Var6 == nil { - templ_7745c5c3_Var6 = templ.NopComponent + templ_7745c5c3_Var14 := templ.GetChildren(ctx) + if templ_7745c5c3_Var14 == nil { + templ_7745c5c3_Var14 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - work, pause := day.GetWorkTimeString() - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = timeGaugeComponent(day.GetWorkDayProgress(user), false, day.RequiresAction()).Render(ctx, templ_7745c5c3_Buffer) - 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.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 } if !day.RequiresAction() { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var9 string - templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(work) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 42, Col: 37} - } - _, 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, 16, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var10 string - templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(pause) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 43, Col: 43} - } - _, 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, 17, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - switch { - case day.Absence.Datum.Equal(day.Day): - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var11 string - templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(day.Absence.AbwesenheitTyp.Name) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 52, Col: 43} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case !day.TimeFrom.Equal(day.TimeTo): - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var12 string - templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(day.TimeFrom.Format("15:04")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 54, Col: 43} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, " - ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var13 string - templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(day.TimeTo.Format("15:04")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 56, Col: 41} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - default: - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "

Keine Anwesenheit

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "

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, 27, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -288,7 +323,7 @@ func weekDayComponent(user models.User, day models.WorkDay) templ.Component { }) } -func employeComponent(week models.WorkWeek) templ.Component { +func workWeekComponent(week models.WorkWeek, onlyAccept 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 { @@ -304,144 +339,292 @@ func employeComponent(week models.WorkWeek) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var14 := templ.GetChildren(ctx) - if templ_7745c5c3_Var14 == nil { - templ_7745c5c3_Var14 = templ.NopComponent + templ_7745c5c3_Var15 := templ.GetChildren(ctx) + if templ_7745c5c3_Var15 == nil { + templ_7745c5c3_Var15 = templ.NopComponent } ctx = templ.ClearChildren(ctx) year, kw := week.WeekStart.ISOWeek() progress := (float32(week.Worktime.Hours()) / week.User.ArbeitszeitPerWoche) * 100 - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var15 string - templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(week.User.Vorname) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 75, Col: 53} + if !onlyAccept { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = weekPicker(week.WeekStart).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } } - _, 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, 28, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "

") 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, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = timeGaugeComponent(uint8(progress), false, false).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "

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, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if !onlyAccept { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = statusCheckMark(week.CheckStatus(), models.WeekStatusSent).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "Gesendet ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = statusCheckMark(week.CheckStatus(), models.WeekStatusAccepted).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "Akzeptiert
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = timeGaugeComponent(int8(progress), false).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "

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, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for _, day := range week.WorkDays { - templ_7745c5c3_Err = weekDayComponent(week.User, day).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "

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, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var20 string - templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(week.User.PersonalNummer)) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 92, Col: 82} + for _, day := range week.Days { + templ_7745c5c3_Err = defaultWeekDayComponent(week.User, day).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "\"> Woche: ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var20 string + templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d-%d", kw, year)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 123, Col: 86} + } + _, 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, 43, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = weekPicker(week.WeekStart).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + + week.CheckStatus() + method := "accept" + if !onlyAccept { + method = "send" + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "\"> Unterschiedliche Arbeitszeit zwischen Abrechnung und individuellen Buchungen

") + var templ_7745c5c3_Var22 string + templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(week.User.PersonalNummer)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/teamComponents.templ`, Line: 138, Col: 83} + } + _, 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, 49, "\"> ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if onlyAccept { + if week.Status == models.WeekStatusDifferences { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "

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, " Korrigieren = models.WeekStatusSent || week.RequiresAction() { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, " disabled") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, " type=\"submit\" class=\"btn\">Senden") 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, 65, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -465,53 +648,53 @@ func userPresenceComponent(user models.User, present bool) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var22 := templ.GetChildren(ctx) - if templ_7745c5c3_Var22 == nil { - templ_7745c5c3_Var22 = templ.NopComponent + templ_7745c5c3_Var24 := templ.GetChildren(ctx) + if templ_7745c5c3_Var24 == nil { + templ_7745c5c3_Var24 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if present { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "
Anwesend
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "
Anwesend
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "
Abwesend
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "
Abwesend
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "

") + 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, "

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/Backend/templates/timeComponents.templ b/Backend/templates/timeComponents.templ index db79920..a258fb3 100644 --- a/Backend/templates/timeComponents.templ +++ b/Backend/templates/timeComponents.templ @@ -37,11 +37,40 @@ templ inputForm() {
} -templ dayComponent(workDay models.WorkDay, submitted bool) { +templ defaultDayComponent(day models.IWorkDay) { + if day.IsWorkDay() { + {{ + workDay, _ := day.(*models.WorkDay) + }} + @workDayComponent(*workDay, false) + } else { + {{ + absentDay, _ := day.(*models.Absence) + }} +
+
+ @timeGaugeComponent(100, false) +

{ day.Date().Format("02.01.2006") }

+
+
+ @lineComponent() +
+

{ absentDay.AbwesenheitTyp.Name } bis { absentDay.DateTo.Format("02.01.2006") }

+
+
+
+ @changeButtonComponent("time-" + absentDay.Date().Format("2006-01-02")) +
+
+ } +} + +templ workDayComponent(workDay models.WorkDay, submitted bool) { {{ - work, pause := workDay.GetWorkTimeString() + // work, pause := workDay.GetWorkTimeString() user := ctx.Value("user").(models.User) - overtime := helper.FormatDuration(workDay.CalcOvertime(user)) + work, pause, overtime := workDay.GetAllWorkTimesReal(user) + // overtime := helper.FormatDuration(workDay.CalcOvertime(user)) justify := "" if len(workDay.Bookings) <= 1 { justify = "justify-content: center" @@ -49,21 +78,21 @@ templ dayComponent(workDay models.WorkDay, submitted bool) { }}
- @timeGaugeComponent(workDay.GetWorkDayProgress(ctx.Value("user").(models.User)), workDay.Day.Equal(time.Now().Truncate(24*time.Hour)), workDay.RequiresAction()) + @timeGaugeComponent(workDay.GetDayProgress(user), workDay.Day.Equal(time.Now().Truncate(24*time.Hour)))

{ 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) }

} }
@@ -71,10 +100,7 @@ templ dayComponent(workDay models.WorkDay, submitted bool) {
@lineComponent()
- if (workDay.Absence != models.Absence{}) { -

{ 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 + } + templ_7745c5c3_Err = timeGaugeComponent(100, false).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_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 + } + templ_7745c5c3_Err = lineComponent().Render(ctx, templ_7745c5c3_Buffer) + 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_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, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = changeButtonComponent("time-"+absentDay.Date().Format("2006-01-02")).Render(ctx, templ_7745c5c3_Buffer) + 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 + } + } + return nil + }) +} + +func workDayComponent(workDay models.WorkDay, submitted 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 { + 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_Var13 := templ.GetChildren(ctx) + if templ_7745c5c3_Var13 == nil { + templ_7745c5c3_Var13 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + + // work, pause := workDay.GetWorkTimeString() user := ctx.Value("user").(models.User) - overtime := helper.FormatDuration(workDay.CalcOvertime(user)) + work, pause, overtime := workDay.GetAllWorkTimesReal(user) + // overtime := helper.FormatDuration(workDay.CalcOvertime(user)) justify := "" if len(workDay.Bookings) <= 1 { justify = "justify-content: center" } - var templ_7745c5c3_Var7 = []any{"grid-sub divide-x-1 hover:bg-neutral-200 transition-colors", templ.KV("bg-neutral-100", submitted)} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...) + var templ_7745c5c3_Var14 = []any{"grid-sub divide-x-1 hover:bg-neutral-200 transition-colors", templ.KV("bg-neutral-100", submitted)} + 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, 7, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "\">
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = timeGaugeComponent(workDay.GetWorkDayProgress(ctx.Value("user").(models.User)), workDay.Day.Equal(time.Now().Truncate(24*time.Hour)), workDay.RequiresAction()).Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = timeGaugeComponent(workDay.GetDayProgress(user), workDay.Day.Equal(time.Now().Truncate(24*time.Hour))).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 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, "

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - if work != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "

Arbeitszeit:

") + if workDay.RequiresAction() { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "

Bitte anpassen

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - if workDay.RequiresAction() { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "

Bitte anpassen

") + } else { + if work > 0 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "

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 } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "

") + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if pause > 0 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "

") 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_Var19 string + templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(pause)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 92, Col: 172} } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, " ") + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - if overtime != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var13 string - templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(overtime) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timeComponents.templ`, Line: 65, Col: 134} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "

") + 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 + } + if overtime > 0 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "

") + 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 } } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -274,57 +409,38 @@ 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, 22, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "\" method=\"post\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - if (workDay.Absence != models.Absence{}) { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "

") - 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, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -368,7 +494,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, 31, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -392,25 +518,25 @@ func changeButtonComponent(id string) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var17 := templ.GetChildren(ctx) - if templ_7745c5c3_Var17 == nil { - templ_7745c5c3_Var17 = templ.NopComponent + templ_7745c5c3_Var23 := templ.GetChildren(ctx) + if templ_7745c5c3_Var23 == nil { + templ_7745c5c3_Var23 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, templ.JSFuncCall("editDay", templ.JSExpression("this"), templ.JSExpression("event"), id)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "\">

Ä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, 43, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var20 = []any{"flex w-full items-center justify-center overflow-hidden rounded-full", bgColor} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...) + var templ_7745c5c3_Var26 = []any{"flex w-full items-center justify-center overflow-hidden rounded-full", bgColor} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var26...) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "\">
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - var templ_7745c5c3_Var23 = []any{"w-2 h-full bg-accent rounded-md flex-shrink-0", bgColor} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var23...) + var templ_7745c5c3_Var29 = []any{"w-2 h-full bg-accent rounded-md flex-shrink-0", bgColor} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var29...) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "\">
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -542,12 +668,12 @@ func lineComponent() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var25 := templ.GetChildren(ctx) - if templ_7745c5c3_Var25 == nil { - templ_7745c5c3_Var25 = templ.NopComponent + templ_7745c5c3_Var31 := templ.GetChildren(ctx) + if templ_7745c5c3_Var31 == nil { + templ_7745c5c3_Var31 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -571,12 +697,12 @@ func absenceComponent(d models.WorkDay) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var26 := templ.GetChildren(ctx) - if templ_7745c5c3_Var26 == nil { - templ_7745c5c3_Var26 = templ.NopComponent + templ_7745c5c3_Var32 := templ.GetChildren(ctx) + if templ_7745c5c3_Var32 == nil { + templ_7745c5c3_Var32 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -653,58 +779,58 @@ func newBookingComponent(d models.WorkDay) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var30 := templ.GetChildren(ctx) - if templ_7745c5c3_Var30 == nil { - templ_7745c5c3_Var30 = templ.NopComponent + templ_7745c5c3_Var36 := templ.GetChildren(ctx) + if templ_7745c5c3_Var36 == nil { + templ_7745c5c3_Var36 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, ">Gehen
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -728,64 +854,64 @@ func bookingComponent(booking models.Booking) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var33 := templ.GetChildren(ctx) - if templ_7745c5c3_Var33 == nil { - templ_7745c5c3_Var33 = templ.NopComponent + templ_7745c5c3_Var39 := templ.GetChildren(ctx) + if templ_7745c5c3_Var39 == nil { + templ_7745c5c3_Var39 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "

") + 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, "

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -809,12 +935,12 @@ func LegendComponent() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var38 := templ.GetChildren(ctx) - if templ_7745c5c3_Var38 == nil { - templ_7745c5c3_Var38 = templ.NopComponent + templ_7745c5c3_Var44 := templ.GetChildren(ctx) + if templ_7745c5c3_Var44 == nil { + templ_7745c5c3_Var44 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "
Fehler
Arbeitszeit unter regulär
Arbeitszeit vollständig
Überstunden
Keine Buchungen
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "
Fehler
Arbeitszeit unter regulär
Arbeitszeit vollständig
Überstunden
Keine Buchungen
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/DB/initdb/01_schema.sql b/DB/initdb/01_schema.sql index b08fad3..56b52d9 100644 --- a/DB/initdb/01_schema.sql +++ b/DB/initdb/01_schema.sql @@ -91,7 +91,8 @@ CREATE TABLE "abwesenheit" ( "counter_id" bigserial PRIMARY KEY, "card_uid" varchar(255), "abwesenheit_typ" int2, - "datum" timestamptz(6) DEFAULT NOW()::DATE + "datum_from" timestamptz DEFAULT NOW()::DATE, + "datum_to" timestamptz ); DROP TABLE IF EXISTS "s_abwesenheit_typen"; diff --git a/migrations/20250916093608.down.sql b/migrations/20250916093608.down.sql new file mode 100644 index 0000000..697259f --- /dev/null +++ b/migrations/20250916093608.down.sql @@ -0,0 +1,13 @@ +-- reverse: modify "wochen_report" table +ALTER TABLE "wochen_report" ALTER COLUMN "personal_nummer" DROP NOT NULL; +-- reverse: modify "s_personal_daten" table +ALTER TABLE "s_personal_daten" ALTER COLUMN "arbeitszeit_per_woche" DROP NOT NULL, ALTER COLUMN "vorgesetzter_pers_nr" DROP NOT NULL, ALTER COLUMN "arbeitszeit_per_tag" DROP NOT NULL; +-- reverse: modify "s_anwesenheit_typen" table +ALTER TABLE "s_anwesenheit_typen" ALTER COLUMN "anwesenheit_name" DROP NOT NULL; +-- reverse: set comment to column: "arbeitszeit_equivalent" on table: "s_abwesenheit_typen" +COMMENT ON COLUMN "s_abwesenheit_typen"."arbeitszeit_equivalent" IS NULL; +-- reverse: modify "s_abwesenheit_typen" table +ALTER TABLE "s_abwesenheit_typen" ALTER COLUMN "arbeitszeit_equivalent" DROP NOT NULL, ALTER COLUMN "abwesenheit_name" DROP NOT NULL; +-- reverse: modify "abwesenheit" table +ALTER TABLE "abwesenheit" DROP COLUMN "datum_to", ALTER COLUMN "datum_from" DROP NOT NULL, ALTER COLUMN "abwesenheit_typ" DROP NOT NULL, ALTER COLUMN "card_uid" DROP NOT NULL; +ALTER TABLE "abwesenheit" RENAME COLUMN "datum_from" TO "datum"; diff --git a/migrations/20250916093608.up.sql b/migrations/20250916093608.up.sql new file mode 100644 index 0000000..b944343 --- /dev/null +++ b/migrations/20250916093608.up.sql @@ -0,0 +1,13 @@ +-- modify "abwesenheit" table +ALTER TABLE "abwesenheit" RENAME COLUMN "datum" TO "datum_from"; +ALTER TABLE "abwesenheit" ALTER COLUMN "card_uid" SET NOT NULL, ALTER COLUMN "abwesenheit_typ" SET NOT NULL, ALTER COLUMN "datum_from" SET NOT NULL, ADD COLUMN "datum_to" timestamptz; +-- modify "s_abwesenheit_typen" table +ALTER TABLE "s_abwesenheit_typen" ALTER COLUMN "abwesenheit_name" SET NOT NULL, ALTER COLUMN "arbeitszeit_equivalent" SET NOT NULL; +-- set comment to column: "arbeitszeit_equivalent" on table: "s_abwesenheit_typen" +COMMENT ON COLUMN "s_abwesenheit_typen"."arbeitszeit_equivalent" IS '0=keine Arbeitszeit; 1=Arbeitszeit auffüllen; 2=Arbeitszeit austauschen'; +-- modify "s_anwesenheit_typen" table +ALTER TABLE "s_anwesenheit_typen" ALTER COLUMN "anwesenheit_name" SET NOT NULL; +-- modify "s_personal_daten" table +ALTER TABLE "s_personal_daten" ALTER COLUMN "arbeitszeit_per_tag" SET NOT NULL, ALTER COLUMN "vorgesetzter_pers_nr" SET NOT NULL, ALTER COLUMN "arbeitszeit_per_woche" SET NOT NULL; +-- modify "wochen_report" table +ALTER TABLE "wochen_report" ALTER COLUMN "personal_nummer" SET NOT NULL;