diff --git a/Backend/endpoints/pdf.go b/Backend/endpoints/pdf.go index 50f7130..ce27116 100644 --- a/Backend/endpoints/pdf.go +++ b/Backend/endpoints/pdf.go @@ -29,7 +29,7 @@ func PDFHandler(w http.ResponseWriter, r *http.Request) { //TODO: only accepted weeks - weeks := models.GetWorkDays(user, startDate, endDate) + weeks := models.GetDays(user, startDate, endDate, false) // log.Printf("Using Dates: %s - %s\n", startDate.String(), endDate.String()) templates.PDFReportEmploye(user, weeks, startDate, endDate).Render(r.Context(), w) diff --git a/Backend/endpoints/team.go b/Backend/endpoints/team.go index 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..b92d3b5 100644 --- a/Backend/endpoints/time.go +++ b/Backend/endpoints/time.go @@ -5,6 +5,7 @@ import ( "arbeitszeitmessung/models" "arbeitszeitmessung/templates" "context" + "database/sql" "encoding/json" "log" "net/http" @@ -30,6 +31,22 @@ func TimeHandler(w http.ResponseWriter, r *http.Request) { } } +func AbsencHandler(w http.ResponseWriter, r *http.Request) { + helper.RequiresLogin(Session, w, r) + helper.SetCors(w) + switch r.Method { + case http.MethodPost: + err := updateAbsence(r) + if err != nil { + http.Error(w, "Internal error", http.StatusInternalServerError) + return + } + http.Redirect(w, r, "/time", 301) + default: + http.Error(w, "Method not allowed!", http.StatusMethodNotAllowed) + } +} + func parseTimestamp(r *http.Request, getKey string, fallback string) (time.Time, error) { getTimestamp := r.URL.Query().Get(getKey) if getTimestamp == "" { @@ -66,18 +83,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, true) + 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 +105,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) { @@ -164,6 +182,84 @@ func updateBooking(w http.ResponseWriter, r *http.Request) { getBookings(w, r) } +func updateAbsence(r *http.Request) error { + r.ParseForm() + var loc *time.Location + loc, err := time.LoadLocation(helper.GetEnv("TZ", "Europe/Berlin")) + if err != nil { + log.Println("Error loading location", err) + loc = time.Local + } + + dateFrom, err := time.ParseInLocation("2006-01-02", r.FormValue("date_from"), loc) + if err != nil { + log.Println("Error parsing date_from input for absence", err) + return err + } + + dateTo, err := time.ParseInLocation("2006-01-02", r.FormValue("date_to"), loc) + if err != nil { + log.Println("Error parsing date_to input for absence", err) + return err + } + + absenceTypeId, err := strconv.Atoi(r.FormValue("aw_type")) + if err != nil { + log.Println("Error parsing aw_type", err) + return err + } + + absenceId, err := strconv.Atoi(r.FormValue("aw_id")) + if err != nil && r.FormValue("aw_id") == "" { + absenceId = 0 + } else if err != nil { + log.Println("Error parsing aw_id", err) + return err + } + + absenceType, err := models.GetAbsenceTypeById(int8(absenceTypeId)) + if err != nil { + log.Println("No matching absence type found!") + return err + } + + newAbsence := models.Absence{DateFrom: dateFrom, DateTo: dateTo, AbwesenheitTyp: absenceType} + + absence, err := models.GetAbsenceById(absenceId) + if err == sql.ErrNoRows { + err = nil + log.Println("Absence not found creating new!") + + user, err := models.GetUserFromSession(Session, r.Context()) + if err != nil { + log.Println("No user found!", err) + return err + } + newAbsence.CardUID = user.CardUID + newAbsence.Insert() + } + if err != nil { + log.Println("Cannot get Absence for id: ", absenceId, err) + return err + } + if r.FormValue("action") == "delete" { + log.Println("Deleting Absence!", "Not implemented") + // TODO + //absence.Delete() + return nil + } + + if absence.Update(newAbsence) { + err = absence.Save() + if err != nil { + log.Println("Error saving updated absence!", err) + return err + } + } + return nil + +} + func createAbsence(absenceType int, user models.User, loc *time.Location, r *http.Request) { absenceDate, err := time.ParseInLocation("2006-01-02", r.FormValue("date"), loc) if err != nil { diff --git a/Backend/main.go b/Backend/main.go index 98a5e22..35395e2 100644 --- a/Backend/main.go +++ b/Backend/main.go @@ -43,6 +43,7 @@ func main() { // handles the different http routes server.HandleFunc("/time/new", endpoints.TimeCreateHandler) + server.Handle("/absence", ParamsMiddleware(endpoints.AbsencHandler)) server.Handle("/time", ParamsMiddleware(endpoints.TimeHandler)) server.HandleFunc("/logout", endpoints.LogoutHandler) server.HandleFunc("/user/{action}", endpoints.UserHandler) diff --git a/Backend/models/absence.go b/Backend/models/absence.go index 08919f4..7d9e913 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,71 @@ 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) GetAllWorkTimesVirtual(u User) (work, pause, overtime time.Duration) { + if a.AbwesenheitTyp.WorkTime > 1 { + return u.ArbeitszeitProTag(), 0, 0 + } + return 0, 0, 0 +} + 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 @@ -53,14 +109,31 @@ func (a *Absence) Insert() error { return nil } +func (a *Absence) Save() error { + qStr, err := DB.Prepare(` + UPDATE abwesenheit SET card_uid = $2, abwesenheit_typ = $3, datum_from = $4, datum_to = $5 WHERE counter_id = $1; + `) + if err != nil { + log.Println("Error preparing sql Statement (Absence Save)", err) + return err + } + defer qStr.Close() + _, err = qStr.Query(a.CounterId, a.CardUID, a.AbwesenheitTyp.Id, a.DateFrom, a.DateTo) + if err != nil { + log.Println("Error executing update statement", err) + return err + } + return nil +} + 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 +142,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 +179,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 @@ -97,6 +196,27 @@ func GetAbsencesByCardUID(card_uid string, tsFrom time.Time, tsTo time.Time) ([] return absences, nil } +func (a *Absence) Update(na Absence) bool { + change := false + if a.CardUID != na.CardUID && na.CardUID != "" { + a.CardUID = na.CardUID + change = true + } + if a.AbwesenheitTyp != na.AbwesenheitTyp && na.AbwesenheitTyp.Id != 0 { + a.AbwesenheitTyp = na.AbwesenheitTyp + change = true + } + if !a.DateFrom.Equal(na.DateFrom) && !na.DateFrom.IsZero() { + a.DateFrom = na.DateFrom + change = true + } + if !a.DateTo.Equal(na.DateTo) && !na.DateTo.IsZero() { + a.DateTo = na.DateTo + change = true + } + return change +} + func GetAbsenceTypes() (map[int8]AbsenceType, error) { var types = make(map[int8]AbsenceType) qStr, err := DB.Prepare("SELECT abwesenheit_id, abwesenheit_name, arbeitszeit_equivalent FROM s_abwesenheit_typen;") 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..5a99af4 100644 --- a/Backend/models/workDay.go +++ b/Backend/models/workDay.go @@ -2,21 +2,161 @@ package models import ( "arbeitszeitmessung/helper" - "database/sql" "encoding/json" "log" + "sort" "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 + GetAllWorkTimesVirtual(User) (work, pause, overtime 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 + kurzArbeitAbsence Absence +} + +func GetDays(user User, tsFrom, tsTo time.Time, orderedForward bool) []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 + workDay.kurzArbeitAbsence = day + } + } else { + allDays[day.Date().Format("2006-01-02")] = &day + } + } + + for _, day := range allDays { + sortedDays = append(sortedDays, day) + } + if orderedForward { + sort.Slice(sortedDays, func(i, j int) bool { + return sortedDays[i].Date().After(sortedDays[j].Date()) + }) + } else { + sort.Slice(sortedDays, func(i, j int) bool { + return sortedDays[i].Date().Before(sortedDays[j].Date()) + }) + } + 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) GetKurzArbeit() Absence { + return d.kurzArbeitAbsence +} + +func (d *WorkDay) TimeWorkReal(u User) time.Duration { + d.realWorkTime, d.realPauseTime = 0, 0 + var lastBooking Booking + for _, booking := range d.Bookings { + if booking.CheckInOut%2 == 1 { + if !lastBooking.Timestamp.IsZero() { + d.realPauseTime += booking.Timestamp.Sub(lastBooking.Timestamp) + } + } else { + d.realWorkTime += booking.Timestamp.Sub(lastBooking.Timestamp) + } + lastBooking = booking + } + if helper.IsSameDate(d.Date(), time.Now()) && len(d.Bookings)%2 == 1 { + d.realWorkTime += time.Since(lastBooking.Timestamp.Local()) + } + 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 +164,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 +235,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 +250,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 +261,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 +281,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..7144b8e 100644 --- a/Backend/models/workWeek.go +++ b/Backend/models/workWeek.go @@ -1,7 +1,6 @@ package models import ( - "arbeitszeitmessung/helper" "database/sql" "errors" "log" @@ -14,6 +13,7 @@ type WorkWeek struct { Id int WorkDays []WorkDay Absences []Absence + Days []IWorkDay User User WeekStart time.Time Worktime time.Duration @@ -39,20 +39,18 @@ 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), false) + + 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 +97,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 +132,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 +190,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/src/main.css b/Backend/src/main.css index 85ae31e..9afdfb3 100644 --- a/Backend/src/main.css +++ b/Backend/src/main.css @@ -1,120 +1,127 @@ @import "tailwindcss"; @source "../templates/*.templ"; @plugin "@iconify/tailwind4" { - scale: 1.25; + scale: 1.25; } @theme { - --color-accent-50: #e7fdea; - --color-accent-100: #cbfbd1; - --color-accent-200: #9cf7a8; - --color-accent-300: #68f37a; - --color-accent-400: #33ef4d; - --color-accent-500: #11db2d; - --color-accent-600: #0eaf23; - --color-accent-700: #0a851b; - --color-accent-800: #075a12; - --color-accent-900: #032b09; - --color-accent-950: #021805; - --color-accent: #0eaf23; - --color-text-50: #f7f8f7; - --color-text-100: #f2f3f2; - --color-text-200: #e2e4e2; - --color-text-300: #d2d6d2; - --color-text-400: #c2c7c2; - --color-text-500: #afb6af; - --color-text-600: #97a097; - --color-text-700: #7d877d; - --color-text-800: #5a625a; - --color-text-900: #161816; - --color-text-950: #000000; + --color-accent-50: #e7fdea; + --color-accent-100: #cbfbd1; + --color-accent-200: #9cf7a8; + --color-accent-300: #68f37a; + --color-accent-400: #33ef4d; + --color-accent-500: #11db2d; + --color-accent-600: #0eaf23; + --color-accent-700: #0a851b; + --color-accent-800: #075a12; + --color-accent-900: #032b09; + --color-accent-950: #021805; + --color-accent: #0eaf23; + --color-text-50: #f7f8f7; + --color-text-100: #f2f3f2; + --color-text-200: #e2e4e2; + --color-text-300: #d2d6d2; + --color-text-400: #c2c7c2; + --color-text-500: #afb6af; + --color-text-600: #97a097; + --color-text-700: #7d877d; + --color-text-800: #5a625a; + --color-text-900: #161816; + --color-text-950: #000000; } @layer base { - body { - -webkit-print-color-adjust: exact !important; - print-color-adjust: exact !important; - } + body { + -webkit-print-color-adjust: exact !important; + print-color-adjust: exact !important; + background-color: white; + } } @layer components { - .grid-main { - display: grid; - grid-template-columns: 2fr auto 1fr; - align-items: stretch; - } - - .grid-sub { - display: grid; - grid-template-columns: subgrid; - grid-column: 1 / -1; - border-color: var(--color-neutral-400); - transition: background-color 0.2s ease-in-out; - } - - .grid-sub.responsive { - display: flex; - flex-direction: column; - } - - .grid-sub:hover { - background-color: var(--color-neutral-200); - } - - .grid-cell { - padding: calc(var(--spacing) * 2); - border-color: var(--color-neutral-400); - } - - .btn { - width: 100%; - cursor: pointer; - border-radius: var(--radius-md); - color: var(--color-neutral-800); - font-size: var(--text-sm); - text-align: center; - padding: calc(var(--spacing) * 2); - border-style: var(--tw-border-style); - border-width: 1px; - border-color: var(--color-neutral-800); - transition-property: - color, background-color, border-color, outline-color, - text-decoration-color, fill, stroke, --tw-gradient-from, - --tw-gradient-via, --tw-gradient-to; - transition-timing-function: var( - --tw-ease, - var(--default-transition-timing-function) - ); - transition-duration: var(--tw-duration, var(--default-transition-duration)); - } - - .btn:hover { - color: var(--color-white); - background-color: var(--color-neutral-700); - } - - .btn:disabled { - opacity: 50%; - pointer-events: none; - } - - .btn:active, - .btn:focus { - background-color: var(--color-neutral-700); - } - - @media (width >=48rem) { .grid-main { - grid-template-columns: repeat(5, 1fr); - margin: 0 10%; + display: grid; + grid-template-columns: 4fr 6fr 1fr; + align-items: stretch; + } + + .grid-sub { + display: grid; + grid-template-columns: subgrid; + grid-column: 1 / -1; + border-color: var(--color-neutral-400); + transition: background-color 0.2s ease-in-out; } .grid-sub.responsive { - display: grid; + display: flex; + flex-direction: column; + } + + .grid-sub:hover { + background-color: var(--color-neutral-200); + } + + .grid-cell { + padding: calc(var(--spacing) * 2); + border-color: var(--color-neutral-400); } .btn { - padding-inline: calc(var(--spacing) * 4); + width: 100%; + cursor: pointer; + border-radius: var(--radius-md); + color: var(--color-neutral-800); + font-size: var(--text-sm); + text-align: center; + padding: calc(var(--spacing) * 2); + border-style: var(--tw-border-style); + border-width: 1px; + border-color: var(--color-neutral-800); + transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to; + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); + transition-duration: var(--tw-duration, var(--default-transition-duration)); + } + + input.btn, + select.btn { + transition-duration: 300ms; + } + + .btn:hover { + color: var(--color-white); + background-color: var(--color-neutral-700); + } + + .btn:disabled { + opacity: 50%; + pointer-events: none; + } + + input.btn, + select.btn { + text-align: left; + } + + input.btn:hover, + select.btn:hover { + border-color: var(--color-neutral-300); + background-color: var(--color-neutral-100); + color: var(--color-neutral-800); + } + + @media (width >=48rem) { + .grid-main { + grid-template-columns: repeat(5, 1fr); + margin: 0 10%; + } + + .grid-sub.responsive { + display: grid; + } + + .btn { + padding-inline: calc(var(--spacing) * 4); + } } - } } diff --git a/Backend/static/css/styles.css b/Backend/static/css/styles.css index 53202ab..1e919bf 100644 --- a/Backend/static/css/styles.css +++ b/Backend/static/css/styles.css @@ -9,8 +9,10 @@ "Courier New", monospace; --color-red-500: oklch(63.7% 0.237 25.331); --color-red-600: oklch(57.7% 0.245 27.325); + --color-red-700: oklch(50.5% 0.213 27.518); --color-orange-500: oklch(70.5% 0.213 47.604); --color-purple-600: oklch(55.8% 0.288 302.321); + --color-slate-700: oklch(37.2% 0.044 257.287); --color-neutral-100: oklch(97% 0 0); --color-neutral-200: oklch(92.2% 0 0); --color-neutral-300: oklch(87% 0 0); @@ -190,9 +192,24 @@ .\@container { container-type: inline-size; } + .absolute { + position: absolute; + } .relative { position: relative; } + .top-2 { + top: calc(var(--spacing) * 2); + } + .top-2\.5 { + top: calc(var(--spacing) * 2.5); + } + .right-2 { + right: calc(var(--spacing) * 2); + } + .right-2\.5 { + right: calc(var(--spacing) * 2.5); + } .col-span-2 { grid-column: span 2 / span 2; } @@ -211,9 +228,15 @@ .mt-1 { margin-top: calc(var(--spacing) * 1); } + .mb-1 { + margin-bottom: calc(var(--spacing) * 1); + } .mb-2 { margin-bottom: calc(var(--spacing) * 2); } + .ml-1 { + margin-left: calc(var(--spacing) * 1); + } .icon-\[material-symbols-light--add-circle-outline\] { display: inline-block; width: 1.25em; @@ -253,6 +276,19 @@ mask-size: 100% 100%; --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M12.003 21q-1.866 0-3.51-.708q-1.643-.709-2.859-1.924t-1.925-2.856T3 12.003t.709-3.51Q4.417 6.85 5.63 5.634t2.857-1.925T11.997 3t3.51.709q1.643.708 2.859 1.922t1.925 2.857t.709 3.509t-.708 3.51t-1.924 2.859t-2.856 1.925t-3.509.709M12 20q3.35 0 5.675-2.325T20 12t-2.325-5.675T12 4T6.325 6.325T4 12t2.325 5.675T12 20m0-8'/%3E%3C/svg%3E"); } + .icon-\[material-symbols-light--delete-outline\] { + display: inline-block; + width: 1.25em; + height: 1.25em; + background-color: currentColor; + -webkit-mask-image: var(--svg); + mask-image: var(--svg); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-size: 100% 100%; + mask-size: 100% 100%; + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M7.616 20q-.672 0-1.144-.472T6 18.385V6H5V5h4v-.77h6V5h4v1h-1v12.385q0 .69-.462 1.153T16.384 20zM17 6H7v12.385q0 .269.173.442t.443.173h8.769q.23 0 .423-.192t.192-.424zM9.808 17h1V8h-1zm3.384 0h1V8h-1zM7 6v13z'/%3E%3C/svg%3E"); + } .icon-\[material-symbols-light--more-time\] { display: inline-block; width: 1.25em; @@ -292,6 +328,22 @@ mask-size: 100% 100%; --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M14.935 16.223L11.5 12.789V7.923h1v4.464l3.123 3.123zM11.5 6V4h1v2zm6.5 6.5v-1h2v1zM11.5 20v-2h1v2zM4 12.5v-1h2v1zm8.003 8.5q-1.867 0-3.51-.708q-1.643-.709-2.859-1.924t-1.925-2.856T3 12.003t.709-3.51Q4.417 6.85 5.63 5.634t2.857-1.925T11.997 3t3.51.709q1.643.708 2.859 1.922t1.925 2.857t.709 3.509t-.708 3.51t-1.924 2.859t-2.856 1.925t-3.509.709M12 20q3.35 0 5.675-2.325T20 12t-2.325-5.675T12 4T6.325 6.325T4 12t2.325 5.675T12 20m0-8'/%3E%3C/svg%3E"); } + .icon-\[material-symbols-light--schedule-outline\] { + display: inline-block; + width: 1.25em; + height: 1.25em; + background-color: currentColor; + -webkit-mask-image: var(--svg); + mask-image: var(--svg); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-size: 100% 100%; + mask-size: 100% 100%; + --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='m15.646 16.354l.708-.708l-3.854-3.854V7h-1v5.208zM12.003 21q-1.866 0-3.51-.708q-1.643-.709-2.859-1.924t-1.925-2.856T3 12.003t.709-3.51Q4.417 6.85 5.63 5.634t2.857-1.925T11.997 3t3.51.709q1.643.708 2.859 1.922t1.925 2.857t.709 3.509t-.708 3.51t-1.924 2.859t-2.856 1.925t-3.509.709M12 20q3.325 0 5.663-2.337T20 12t-2.337-5.663T12 4T6.337 6.338T4 12t2.338 5.663T12 20'/%3E%3C/svg%3E"); + } + .block { + display: block; + } .flex { display: flex; } @@ -315,12 +367,27 @@ width: calc(var(--spacing) * 4); height: calc(var(--spacing) * 4); } + .size-5 { + width: calc(var(--spacing) * 5); + height: calc(var(--spacing) * 5); + } + .size-6 { + width: calc(var(--spacing) * 6); + height: calc(var(--spacing) * 6); + } + .size-7 { + width: calc(var(--spacing) * 7); + height: calc(var(--spacing) * 7); + } .h-2 { height: calc(var(--spacing) * 2); } .h-4 { height: calc(var(--spacing) * 4); } + .h-5 { + height: calc(var(--spacing) * 5); + } .h-8 { height: calc(var(--spacing) * 8); } @@ -330,15 +397,18 @@ .h-full { height: 100%; } - .w-1\/7 { - width: calc(1/7 * 100%); - } .w-2 { width: calc(var(--spacing) * 2); } .w-4 { width: calc(var(--spacing) * 4); } + .w-5 { + width: calc(var(--spacing) * 5); + } + .w-9 { + width: calc(var(--spacing) * 9); + } .w-9\/10 { width: calc(9/10 * 100%); } @@ -351,9 +421,15 @@ .w-full { width: 100%; } + .flex-shrink { + flex-shrink: 1; + } .flex-shrink-0 { flex-shrink: 0; } + .shrink { + flex-shrink: 1; + } .flex-grow { flex-grow: 1; } @@ -363,12 +439,27 @@ .grow-1 { flex-grow: 1; } + .basis-\[content\] { + flex-basis: content; + } + .basis-auto { + flex-basis: auto; + } .border-collapse { border-collapse: collapse; } .cursor-pointer { cursor: pointer; } + .resize { + resize: both; + } + .scroll-m-2 { + scroll-margin: calc(var(--spacing) * 2); + } + .appearance-none { + appearance: none; + } .break-after-page { break-after: page; } @@ -405,6 +496,9 @@ .items-center { align-items: center; } + .items-end { + align-items: flex-end; + } .justify-around { justify-content: space-around; } @@ -448,6 +542,9 @@ .overflow-hidden { overflow: hidden; } + .rounded { + border-radius: 0.25rem; + } .rounded-full { border-radius: calc(infinity * 1px); } @@ -458,14 +555,6 @@ 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; @@ -511,6 +600,9 @@ .bg-red-600 { background-color: var(--color-red-600); } + .mask-repeat { + mask-repeat: repeat; + } .p-1 { padding: calc(var(--spacing) * 1); } @@ -572,9 +664,19 @@ .text-red-600 { color: var(--color-red-600); } + .text-slate-700 { + color: var(--color-slate-700); + } .uppercase { text-transform: uppercase; } + .underline { + text-decoration-line: underline; + } + .outline { + outline-style: var(--tw-outline-style); + outline-width: 1px; + } .filter { filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,); } @@ -592,16 +694,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; @@ -681,10 +773,17 @@ } } } - .hover\:bg-red-600 { + .hover\:bg-red-500 { &:hover { @media (hover: hover) { - background-color: var(--color-red-600); + background-color: var(--color-red-500); + } + } + } + .hover\:bg-red-700 { + &:hover { + @media (hover: hover) { + background-color: var(--color-red-700); } } } @@ -733,11 +832,6 @@ opacity: 50%; } } - .max-md\:flex { - @media (width < 48rem) { - display: flex; - } - } .max-md\:grid { @media (width < 48rem) { display: grid; @@ -748,11 +842,6 @@ display: none; } } - .max-md\:flex-col { - @media (width < 48rem) { - flex-direction: column; - } - } .max-md\:divide-y-1 { @media (width < 48rem) { :where(& > :not(:last-child)) { @@ -878,12 +967,13 @@ body { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; + background-color: white; } } @layer components { .grid-main { display: grid; - grid-template-columns: 2fr auto 1fr; + grid-template-columns: 4fr 6fr 1fr; align-items: stretch; } .grid-sub { @@ -916,9 +1006,12 @@ border-width: 1px; border-color: var(--color-neutral-800); transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to; - transition-timing-function: var( --tw-ease, var(--default-transition-timing-function) ); + transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); transition-duration: var(--tw-duration, var(--default-transition-duration)); } + input.btn, select.btn { + transition-duration: 300ms; + } .btn:hover { color: var(--color-white); background-color: var(--color-neutral-700); @@ -927,8 +1020,13 @@ opacity: 50%; pointer-events: none; } - .btn:active, .btn:focus { - background-color: var(--color-neutral-700); + input.btn, select.btn { + text-align: left; + } + input.btn:hover, select.btn:hover { + border-color: var(--color-neutral-300); + background-color: var(--color-neutral-100); + color: var(--color-neutral-800); } @media (width >=48rem) { .grid-main { @@ -962,6 +1060,11 @@ syntax: "*"; inherits: false; } +@property --tw-outline-style { + syntax: "*"; + inherits: false; + initial-value: solid; +} @property --tw-blur { syntax: "*"; inherits: false; @@ -1026,6 +1129,7 @@ --tw-border-style: solid; --tw-divide-y-reverse: 0; --tw-font-weight: initial; + --tw-outline-style: solid; --tw-blur: initial; --tw-brightness: initial; --tw-contrast: initial; diff --git a/Backend/static/script.js b/Backend/static/script.js index 520ec52..e5f27bd 100644 --- a/Backend/static/script.js +++ b/Backend/static/script.js @@ -12,6 +12,30 @@ function editDay(element, event, formId) { } } +function editAbsence(element, event, absenceId) { + var form = document.getElementById("absence_form"); + console.log(absenceId); + + if (absenceId != 0) { + const fieldsToSync = ["date_from", "date_to", "aw_type", "aw_id"]; + + var dataForm = document.getElementById(absenceId); + + fieldsToSync.forEach((name) => { + const src = dataForm.querySelector(`[name=${name}]`); + const target = form.querySelector(`[name=${name}]`); + if (!src || !target) return; + target.value = src.value; + }); + } else { + var dataForm = element.closest(".grid-sub").querySelector(".all-booking-component > form"); + form.querySelector("[name=date_from]").value = dataForm.id.replace("time-", ""); + form.querySelector("[name=date_to]").value = dataForm.id.replace("time-", ""); + } + form.classList.remove("hidden"); + form.scrollIntoView({ behavior: "smooth", block: "start", inline: "nearest" }); +} + function editAbwesenheit(element, event) { var newBookingComponent = element.closest(".grid-sub").querySelector(".new-booking-component"); if (element.value == 0) { diff --git a/Backend/templates/headerComponent_templ.go b/Backend/templates/headerComponent_templ.go index 8e59160..aeef6ec 100644 --- a/Backend/templates/headerComponent_templ.go +++ b/Backend/templates/headerComponent_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.943 +// templ: version: v0.3.924 package templates //lint:file-ignore SA4006 This context is only used if a nested component is present. diff --git a/Backend/templates/pages.templ b/Backend/templates/pages.templ index b7865cf..8ca8aff 100644 --- a/Backend/templates/pages.templ +++ b/Backend/templates/pages.templ @@ -1,12 +1,6 @@ package templates -import ( - "arbeitszeitmessung/helper" - "arbeitszeitmessung/models" - "fmt" - "strconv" - "time" -) +import "arbeitszeitmessung/models" templ Base() { @@ -18,21 +12,6 @@ templ Base() { } -templ TimePage(workDays []models.WorkDay, lastSub time.Time) { - @Base() - @headerComponent() -
- @inputForm() - for _, day := range workDays { - @dayComponent(day, day.Day.Before(lastSub)) - if (day.Day.Weekday() == time.Monday) { -
- } - } -
- @LegendComponent() -} - templ LoginPage(success bool, errorMsg string) { @Base()
@@ -95,72 +74,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..3a54c9b 100644 --- a/Backend/templates/pages_templ.go +++ b/Backend/templates/pages_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.943 +// templ: version: v0.3.924 package templates //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -8,13 +8,7 @@ package templates import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -import ( - "arbeitszeitmessung/helper" - "arbeitszeitmessung/models" - "fmt" - "strconv" - "time" -) +import "arbeitszeitmessung/models" func Base() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { @@ -45,7 +39,7 @@ func Base() templ.Component { }) } -func TimePage(workDays []models.WorkDay, lastSub time.Time) templ.Component { +func LoginPage(success bool, errorMsg string) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -70,95 +64,30 @@ func TimePage(workDays []models.WorkDay, lastSub time.Time) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = headerComponent().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = inputForm().Render(ctx, templ_7745c5c3_Buffer) - 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) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if day.Day.Weekday() == time.Monday { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = LegendComponent().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -func LoginPage(success bool, errorMsg string) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var3 := templ.GetChildren(ctx) - if templ_7745c5c3_Var3 == nil { - templ_7745c5c3_Var3 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = Base().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "

Benutzer Anmelden

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

Benutzer Anmelden

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

Login fehlgeschlagen, bitte erneut versuchen!

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

Login fehlgeschlagen, bitte erneut versuchen!

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(errorMsg) + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, 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: 24, Col: 46} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "

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

") 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, 5, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -182,9 +111,9 @@ func UserPage(status int) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var5 := templ.GetChildren(ctx) - if templ_7745c5c3_Var5 == nil { - templ_7745c5c3_Var5 = templ.NopComponent + templ_7745c5c3_Var4 := templ.GetChildren(ctx) + if templ_7745c5c3_Var4 == nil { + templ_7745c5c3_Var4 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = Base().Render(ctx, templ_7745c5c3_Buffer) @@ -195,28 +124,28 @@ func UserPage(status int) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

Passwort ändern

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

Passwort ändern

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } switch { case status == 401: - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "

Aktuelles Passwort nicht korrekt!

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

Aktuelles Passwort nicht korrekt!

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } case status >= 400: - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "

Passwortwechsel fehlgeschlagen, bitte erneut versuchen!

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

Passwortwechsel fehlgeschlagen, bitte erneut versuchen!

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } case status == 202: - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "

Passwortänderung erfolgreich

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

Passwortänderung erfolgreich

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

Nutzer abmelden

Nutzer von Weboberfläche abmelden.

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

Nutzer abmelden

Nutzer von Weboberfläche abmelden.

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -240,18 +169,18 @@ func statusCheckMark(status models.WeekStatus, target models.WeekStatus) templ.C }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var6 := templ.GetChildren(ctx) - if templ_7745c5c3_Var6 == nil { - templ_7745c5c3_Var6 = templ.NopComponent + templ_7745c5c3_Var5 := templ.GetChildren(ctx) + if templ_7745c5c3_Var5 == nil { + templ_7745c5c3_Var5 = templ.NopComponent } ctx = templ.ClearChildren(ctx) if status >= target { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -261,6 +190,63 @@ func statusCheckMark(status models.WeekStatus, target models.WeekStatus) templ.C } func TeamPage(weeks []models.WorkWeek, userWeek models.WorkWeek) 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 = Base().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = headerComponent().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "

Eigene Abrechnung

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + 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, 14, "

Abrechnung Mitarbeiter

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + for _, week := range weeks { + 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, 15, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func TeamPresencePage(teamPresence map[bool][]models.User) 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 { @@ -289,218 +275,7 @@ 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

") - 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
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if len(weeks) > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "

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) - 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 - } - return nil - }) -} - -func TeamPresencePage(teamPresence map[bool][]models.User) 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) - templ_7745c5c3_Err = Base().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = headerComponent().Render(ctx, templ_7745c5c3_Buffer) - 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, 16, "

Anwesend

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -510,7 +285,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, 17, "

Nicht Anwesend

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -520,7 +295,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, 18, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -544,12 +319,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_Var8 := templ.GetChildren(ctx) + if templ_7745c5c3_Var8 == nil { + templ_7745c5c3_Var8 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/Backend/templates/pdf.templ b/Backend/templates/pdf.templ index 7779608..2b92d10 100644 --- a/Backend/templates/pdf.templ +++ b/Backend/templates/pdf.templ @@ -6,7 +6,7 @@ import ( "time" ) -templ PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Time, tsEnd time.Time) { +templ PDFReportEmploye(e models.User, workDays []models.IWorkDay, tsStart time.Time, tsEnd time.Time) { {{ _, kw := tsStart.ISOWeek() noBorder := "" @@ -33,23 +33,32 @@ templ PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Ti noBorder = "border-b-0" } }} -

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

- +

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

- for bookingI := 0; bookingI < len(day.Bookings); bookingI+= 2 { -

{ day.Bookings[bookingI].Timestamp.Format("15:04") }

-

{ day.Bookings[bookingI+1].Timestamp.Format("15:04") }

-

{ day.Bookings[bookingI].BookingType.Name }

- } - if (day.Absence != models.Absence{}) { -

{ day.Absence.AbwesenheitTyp.Name }

+ if day.IsWorkDay() { + {{ + workDay, _ := day.(*models.WorkDay) + }} + for bookingI := 0; bookingI < len(workDay.Bookings); bookingI+= 2 { +

{ workDay.Bookings[bookingI].Timestamp.Format("15:04") }

+

{ workDay.Bookings[bookingI+1].Timestamp.Format("15:04") }

+

{ workDay.Bookings[bookingI].BookingType.Name }

+ } + if workDay.IsKurzArbeit() { +

Kurzarbeit

+ } + } else { + {{ + absentDay, _ := day.(*models.Absence) + }} +

{ absentDay.AbwesenheitTyp.Name }

}
- {{ work, pause, overtime := day.GetAllWorkTimes(e) }} + {{ work, pause, overtime := day.GetAllWorkTimesVirtual(e) }} @ColorDuration(work, noBorder) @ColorDuration(pause, noBorder) - @ColorDuration(overtime, noBorder + " border-r-0") - if day.Day.Weekday() == time.Friday { + @ColorDuration(overtime, noBorder+" border-r-0") + if day.Date().Weekday() == time.Friday {

Wochenende

} } @@ -57,144 +66,12 @@ templ PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Ti } -templ PDFReportEmployeTable(e models.User, workDays []models.WorkDay, tsStart time.Time, tsEnd time.Time) { +templ ColorDuration(d time.Duration, classes string) { {{ - _, kw := tsStart.ISOWeek() - noBorder := "" - }} - @Base() - -
-

Kim Mustermensch

-

Zeitraum: { tsStart.Format("02.01.2006") } - { tsEnd.Format("02.01.2006") }

-

Arbeitszeit:

-

Überstunden:

-
- - - - - - - - - - - for index, day := range workDays { - {{ - if index == len(workDays)-1 { - noBorder = "border-b-0" - } - }} - - - - {{ work, pause, overtime := day.GetAllWorkTimes(e) }} - @ColorDuration(work, noBorder) - @ColorDuration(pause, noBorder) - @ColorDuration(overtime, noBorder + " border-r-0") - if day.Day.Weekday() == time.Friday { - - - - } - - } -
{ kw }KommenGehenArbeitsartStundenPauseÜberstunden
{ day.Day.Format("02.01.2006") } - - for bookingI := 0; bookingI < len(day.Bookings); bookingI+= 2 { - - - - - - } - if (day.Absence != models.Absence{}) { - if len(day.Bookings) > 0 { - - - - } - else { - - - - } - - } -
{ day.Bookings[bookingI].Timestamp.Format("15:04") }{ day.Bookings[bookingI+1].Timestamp.Format("15:04") }{ day.Bookings[bookingI].BookingType.Name }
{ day.Absence.AbwesenheitTyp.Name }
{ day.Absence.AbwesenheitTyp.Name }
-
Wochenende
-
-
-
-

Kim Mustermensch

-

Zeitraum: { tsStart.Format("02.01.2006") } - { tsEnd.Format("02.01.2006") }

-

Arbeitszeit:

-

Überstunden:

-
- - - - - - - - - - - for index, day := range workDays { - {{ - if index == len(workDays)-1 { - noBorder = "border-b-0" - } - }} - - - - {{ work, pause, overtime := day.GetAllWorkTimes(e) }} - @ColorDuration(work, noBorder) - @ColorDuration(pause, noBorder) - @ColorDuration(overtime, noBorder + " border-r-0") - if day.Day.Weekday() == time.Friday { - - - - } - - } -
{ kw }KommenGehenArbeitsartStundenPauseÜberstunden
{ day.Day.Format("02.01.2006") } - - for bookingI := 0; bookingI < len(day.Bookings); bookingI+= 2 { - - - - - - } - if (day.Absence != models.Absence{}) { - if len(day.Bookings) > 0 { - - - - } - else { - - - - } - - } -
{ day.Bookings[bookingI].Timestamp.Format("15:04") }{ day.Bookings[bookingI+1].Timestamp.Format("15:04") }{ day.Bookings[bookingI].BookingType.Name }
{ day.Absence.AbwesenheitTyp.Name }
{ day.Absence.AbwesenheitTyp.Name }
-
Wochenende
-
-} - -templ ColorDuration(d time.Duration, classes string){ -{{ color := "" - if d.Abs() < time.Minute{ + if d.Abs() < time.Minute { color = "text-neutral-300" } -}} -

{ helper.FormatDurationFill(d, true) }

+ }} +

{ helper.FormatDurationFill(d, true) }

} diff --git a/Backend/templates/pdf_templ.go b/Backend/templates/pdf_templ.go index 1f429a0..d9c5e51 100644 --- a/Backend/templates/pdf_templ.go +++ b/Backend/templates/pdf_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.943 +// templ: version: v0.3.924 package templates //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -14,7 +14,7 @@ import ( "time" ) -func PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Time, tsEnd time.Time) templ.Component { +func PDFReportEmploye(e models.User, workDays []models.IWorkDay, tsStart time.Time, tsEnd time.Time) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -113,9 +113,9 @@ func PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Tim return templ_7745c5c3_Err } var templ_7745c5c3_Var7 string - templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(day.Day.Format("02.01.2006")) + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(day.Date().Format("02.01.2006")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 36, Col: 56} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 36, Col: 59} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { @@ -147,585 +147,122 @@ func PDFReportEmploye(e models.User, workDays []models.WorkDay, tsStart time.Tim if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - for bookingI := 0; bookingI < len(day.Bookings); bookingI += 2 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

") + if day.IsWorkDay() { + + workDay, _ := day.(*models.WorkDay) + for bookingI := 0; bookingI < len(workDay.Bookings); bookingI += 2 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var10 string + templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Bookings[bookingI].Timestamp.Format("15:04")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 43, Col: 64} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var11 string + templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Bookings[bookingI+1].Timestamp.Format("15:04")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 44, Col: 66} + } + _, 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, 12, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var12 string + templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(workDay.Bookings[bookingI].BookingType.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 45, Col: 55} + } + _, 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, 13, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var10 string - templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(day.Bookings[bookingI].Timestamp.Format("15:04")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 40, Col: 59} + if workDay.IsKurzArbeit() { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "

Kurzarbeit

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var11 string - templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(day.Bookings[bookingI+1].Timestamp.Format("15:04")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 41, Col: 61} - } - _, 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, 12, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var12 string - templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(day.Bookings[bookingI].BookingType.Name) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 42, Col: 50} - } - _, 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, 13, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if (day.Absence != models.Absence{}) { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "

") + } else { + + absentDay, _ := day.(*models.Absence) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "

") 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) + 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/pdf.templ`, Line: 45, Col: 64} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 54, Col: 62} } _, 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, "

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

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - work, pause, overtime := day.GetAllWorkTimes(e) + work, pause, overtime := day.GetAllWorkTimesVirtual(e) templ_7745c5c3_Err = ColorDuration(work, noBorder).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = ColorDuration(pause, noBorder).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = ColorDuration(overtime, noBorder+" border-r-0").Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, " ") 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

") - 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 - } - return nil - }) -} - -func PDFReportEmployeTable(e models.User, workDays []models.WorkDay, tsStart time.Time, tsEnd time.Time) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var14 := templ.GetChildren(ctx) - if templ_7745c5c3_Var14 == nil { - templ_7745c5c3_Var14 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - - _, kw := tsStart.ISOWeek() - noBorder := "" - templ_7745c5c3_Err = Base().Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "

Kim Mustermensch

Zeitraum: ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var15 string - templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(tsStart.Format("02.01.2006")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 69, Col: 52} - } - _, 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, 23, " - ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var16 string - templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(tsEnd.Format("02.01.2006")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 69, Col: 98} - } - _, 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, 24, "

Arbeitszeit:

Überstunden:

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for index, day := range workDays { - - if index == len(workDays)-1 { - noBorder = "border-b-0" - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var18 = []any{noBorder} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var18...) - 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 - } - work, pause, overtime := day.GetAllWorkTimes(e) - templ_7745c5c3_Err = ColorDuration(work, noBorder).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } templ_7745c5c3_Err = ColorDuration(pause, noBorder).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } templ_7745c5c3_Err = ColorDuration(overtime, noBorder+" border-r-0").Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - if day.Day.Weekday() == time.Friday { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if day.Date().Weekday() == time.Friday { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "

Wochenende

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "") - 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 - } - var templ_7745c5c3_Var17 string - templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(kw) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 75, Col: 60} - } - _, 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, 25, "KommenGehenArbeitsartStundenPauseÜberstunden
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var20 string - templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(day.Day.Format("02.01.2006")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 90, Col: 58} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var21 = []any{"w-full border-collapse" + noBorder} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var21...) - 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 - } - for bookingI := 0; bookingI < len(day.Bookings); bookingI += 2 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if (day.Absence != models.Absence{}) { - if len(day.Bookings) > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var23 string - templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(day.Bookings[bookingI].Timestamp.Format("15:04")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 95, Col: 85} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var24 string - templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(day.Bookings[bookingI+1].Timestamp.Format("15:04")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 96, Col: 87} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var25 string - templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(day.Bookings[bookingI].BookingType.Name) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 97, Col: 65} - } - _, 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, 35, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var26 string - templ_7745c5c3_Var26, 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: 103, Col: 78} - } - _, 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, 37, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var27 string - templ_7745c5c3_Var27, 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: 108, Col: 78} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
Wochenende

Kim Mustermensch

Zeitraum: ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var28 string - templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(tsStart.Format("02.01.2006")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 131, Col: 52} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, " - ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var29 string - templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(tsEnd.Format("02.01.2006")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 131, Col: 98} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "

Arbeitszeit:

Überstunden:

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for index, day := range workDays { - - if index == len(workDays)-1 { - noBorder = "border-b-0" - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var31 = []any{noBorder} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var31...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - work, pause, overtime := day.GetAllWorkTimes(e) - templ_7745c5c3_Err = ColorDuration(work, noBorder).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = ColorDuration(pause, noBorder).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = ColorDuration(overtime, noBorder+" border-r-0").Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if day.Day.Weekday() == time.Friday { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var30 string - templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(kw) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 137, Col: 60} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "KommenGehenArbeitsartStundenPauseÜberstunden
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var33 string - templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(day.Day.Format("02.01.2006")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 152, Col: 58} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var34 = []any{"w-full border-collapse" + noBorder} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var34...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for bookingI := 0; bookingI < len(day.Bookings); bookingI += 2 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if (day.Absence != models.Absence{}) { - if len(day.Bookings) > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var36 string - templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(day.Bookings[bookingI].Timestamp.Format("15:04")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 157, Col: 85} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var37 string - templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(day.Bookings[bookingI+1].Timestamp.Format("15:04")) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 158, Col: 87} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var38 string - templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(day.Bookings[bookingI].BookingType.Name) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 159, Col: 65} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var39 string - templ_7745c5c3_Var39, 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: 165, Col: 78} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var39)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var40 string - templ_7745c5c3_Var40, 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: 170, Col: 78} - } - _, 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, 60, "
Wochenende
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -749,9 +286,9 @@ func ColorDuration(d time.Duration, classes string) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var41 := templ.GetChildren(ctx) - if templ_7745c5c3_Var41 == nil { - templ_7745c5c3_Var41 = templ.NopComponent + templ_7745c5c3_Var14 := templ.GetChildren(ctx) + if templ_7745c5c3_Var14 == nil { + templ_7745c5c3_Var14 = templ.NopComponent } ctx = templ.ClearChildren(ctx) @@ -759,38 +296,38 @@ func ColorDuration(d time.Duration, classes string) templ.Component { if d.Abs() < time.Minute { color = "text-neutral-300" } - var templ_7745c5c3_Var42 = []any{color + " " + classes} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var42...) + var templ_7745c5c3_Var15 = []any{color + " " + classes} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var15...) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var44 string - templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDurationFill(d, true)) + 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: 199, Col: 71} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/pdf.templ`, Line: 76, Col: 72} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var44)) + _, 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, 67, "

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

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/Backend/templates/teamComponents.templ b/Backend/templates/teamComponents.templ index 71ed2bd..e5738b9 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..ec539f2 100644 --- a/Backend/templates/teamComponents_templ.go +++ b/Backend/templates/teamComponents_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.943 +// templ: version: v0.3.924 package templates //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -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..f50e3a3 100644 --- a/Backend/templates/timeComponents.templ +++ b/Backend/templates/timeComponents.templ @@ -1,101 +1,89 @@ package templates import ( - "arbeitszeitmessung/helper" "arbeitszeitmessung/models" "fmt" - "net/url" "strconv" "time" ) -templ inputForm() { - {{ - urlParams := ctx.Value("urlParams").(url.Values) - user := ctx.Value("user").(models.User) - }} -
-
-

{ user.Vorname + " " + user.Name }

-
-

Überstunden

-

{ user.Overtime }

-
-
-
- @lineComponent() -
- - -
-
-
- -
+templ lineComponent() { +
+ + + +
+ + +
} -templ dayComponent(workDay models.WorkDay, submitted bool) { +// templ workDayComponent(workDay models.WorkDay, submitted bool) { +// {{ +// // work, pause := workDay.GetWorkTimeString() +// user := ctx.Value("user").(models.User) +// work, pause, overtime := workDay.GetAllWorkTimesReal(user) +// // overtime := helper.FormatDuration(workDay.CalcOvertime(user)) +// justify := "" +// if len(workDay.Bookings) <= 1 { +// justify = "justify-content: center" +// } +// }} +//
+//
+// @timeGaugeComponent(workDay.GetDayProgress(user), workDay.Day.Equal(time.Now().Truncate(24*time.Hour))) +//
+//

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

+// 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) }

+// } +// } +//
+//
+//
+// @lineComponent() +//
+// if len(workDay.Bookings) < 1 { +//

Keine Buchung gefunden. Bitte Arbeitsstunden oder Grund der Abwesenheit eingeben!

+// @absenceComponent(workDay) +// @newBookingComponent(workDay) +// } else { +// @absenceComponent(workDay) +// for _, booking := range workDay.Bookings { +// @bookingComponent(booking) +// } +// if workDay.IsKurzArbeit() { +//

Kurzarbeit

+// } +// @newBookingComponent(workDay) +// } +// +//
+//
+//
+// @changeButtonComponent("time-" + workDay.Day.Format("2006-01-02")) +//
+//
+// } +templ changeButtonComponent(id string, workDay bool) { {{ - work, pause := workDay.GetWorkTimeString() - user := ctx.Value("user").(models.User) - overtime := helper.FormatDuration(workDay.CalcOvertime(user)) - justify := "" - if len(workDay.Bookings) <= 1 { - justify = "justify-content: center" + functionName := "editDay" + if !workDay { + functionName = "editAbsence" } }} -
-
- @timeGaugeComponent(workDay.GetWorkDayProgress(ctx.Value("user").(models.User)), workDay.Day.Equal(time.Now().Truncate(24*time.Hour)), workDay.RequiresAction()) -
-

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

- if work!="" { -

Arbeitszeit:

- if (workDay.RequiresAction()) { -

Bitte anpassen

- } else { -

{ work }

- if pause != "" { -

{ pause }

- } - if overtime != "" { -

{ overtime }

- } - } - } -
-
-
- @lineComponent() -
- if (workDay.Absence != models.Absence{}) { -

{ workDay.Absence.AbwesenheitTyp.Name }

- } - if len(workDay.Bookings) < 1 && (workDay.Absence == models.Absence{}) { -

Keine Buchung gefunden. Bitte Arbeitsstunden oder Grund der Abwesenheit eingeben!

- @absenceComponent(workDay) - @newBookingComponent(workDay) - } else { - @absenceComponent(workDay) - for _, booking := range workDay.Bookings { - @bookingComponent(booking) - } - @newBookingComponent(workDay) - } - -
-
-
- @changeButtonComponent("time-" + workDay.Day.Format("2006-01-02")) -
-
-} - -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): @@ -135,30 +123,15 @@ templ timeGaugeComponent(progress uint8, today bool, warning bool) { } } -templ lineComponent() { -
- - - -
- - - -
-} - -templ absenceComponent(d models.WorkDay) { +templ newAbsenceComponent() { } -templ newBookingComponent(d models.WorkDay) { +templ newBookingComponent(d *models.WorkDay) { ") 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_Var8 = []any{"w-2 h-full bg-accent rounded-md flex-shrink-0", bgColor} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...) 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, 9, "\">
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -526,7 +256,7 @@ func timeGaugeComponent(progress uint8, today bool, warning bool) templ.Componen }) } -func lineComponent() templ.Component { +func newAbsenceComponent() 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 { @@ -542,12 +272,29 @@ 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_Var10 := templ.GetChildren(ctx) + if templ_7745c5c3_Var10 == nil { + templ_7745c5c3_Var10 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -555,7 +302,7 @@ func lineComponent() templ.Component { }) } -func absenceComponent(d models.WorkDay) templ.Component { +func newBookingComponent(d *models.WorkDay) 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 { @@ -571,140 +318,58 @@ 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_Var12 := templ.GetChildren(ctx) + if templ_7745c5c3_Var12 == nil { + templ_7745c5c3_Var12 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -728,64 +393,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_Var15 := templ.GetChildren(ctx) + if templ_7745c5c3_Var15 == nil { + templ_7745c5c3_Var15 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "

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

") 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_Var16 string + templ_7745c5c3_Var16, 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: 150, 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_Var16)) 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, 23, "\" 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_Var19 string + templ_7745c5c3_Var19, 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: 152, 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_Var19)) 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, 24, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -809,12 +474,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_Var20 := templ.GetChildren(ctx) + if templ_7745c5c3_Var20 == nil { + templ_7745c5c3_Var20 = 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, 25, "
Fehler
Arbeitszeit unter regulär
Arbeitszeit vollständig
Überstunden
Keine Buchungen
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/Backend/templates/timePage.templ b/Backend/templates/timePage.templ new file mode 100644 index 0000000..323388d --- /dev/null +++ b/Backend/templates/timePage.templ @@ -0,0 +1,169 @@ +package templates + +import ( + "arbeitszeitmessung/helper" + "arbeitszeitmessung/models" + "net/url" + "strconv" + "time" +) + +templ TimePage(workDays []models.WorkDay, lastSub time.Time) { + {{ + allDays := ctx.Value("days").([]models.IWorkDay) + }} + @Base() + @headerComponent() +
+ @inputForm() + for _, day := range allDays { + @defaultDayComponent(day) + if (day.Date().Weekday() == time.Monday) { +
+ } + } +
+ @LegendComponent() +} + +templ inputForm() { + {{ + urlParams := ctx.Value("urlParams").(url.Values) + user := ctx.Value("user").(models.User) + }} +
+
+

{ user.Vorname + " " + user.Name }

+
+

Überstunden

+

{ user.Overtime }

+
+
+
+ @lineComponent() +
+ + +
+
+
+ +
+
+ +} + +templ defaultDayComponent(day models.IWorkDay) { + {{ + user := ctx.Value("user").(models.User) + justify := "justify-center" + if day.IsWorkDay() && len(day.(*models.WorkDay).Bookings) > 1 { + justify = "justify-between" + } + }} +
+
+ @timeGaugeComponent(day.GetDayProgress(user), day.Date().Equal(time.Now().Truncate(24*time.Hour))) +
+

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

+ if day.IsWorkDay() { + {{ + workDay, _ := day.(*models.WorkDay) + work, pause, overtime := workDay.GetAllWorkTimesVirtual(user) + }} + if day.RequiresAction() { +

Bitte anpassen

+ } else { + if work > 0 { +

Arbeitszeit:

+

{ helper.FormatDuration(work) }

+ } + if pause > 0 { +

{ helper.FormatDuration(pause) }

+ } + if overtime != 0 && len(workDay.Bookings) > 0 { +

+ + { helper.FormatDuration(overtime) } +

+ } + } + } +
+
+
+ @lineComponent() +
+ @newAbsenceComponent() + if day.IsWorkDay() { + {{ + workDay, _ := day.(*models.WorkDay) + }} + if len(workDay.Bookings) < 1 { +

Keine Buchung gefunden. Bitte Arbeitsstunden oder Grund der Abwesenheit eingeben!

+ } + for _, booking := range workDay.Bookings { + @bookingComponent(booking) + } + @newBookingComponent(workDay) + if workDay.IsKurzArbeit() { + @absentInput(workDay.GetKurzArbeit()) +

Kurzarbeit

+ } + } else { + {{ + absentDay, _ := day.(*models.Absence) + }} + @absentInput(*absentDay) +

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

+ } +
+
+
+ @changeButtonComponent("time-"+day.Date().Format("2006-01-02"), day.IsWorkDay()) +
+
+} + +templ absentInput(a models.Absence) { + + + + +} diff --git a/Backend/templates/timePage_templ.go b/Backend/templates/timePage_templ.go new file mode 100644 index 0000000..4582490 --- /dev/null +++ b/Backend/templates/timePage_templ.go @@ -0,0 +1,595 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.924 +package templates + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import ( + "arbeitszeitmessung/helper" + "arbeitszeitmessung/models" + "net/url" + "strconv" + "time" +) + +func TimePage(workDays []models.WorkDay, lastSub time.Time) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + + allDays := ctx.Value("days").([]models.IWorkDay) + templ_7745c5c3_Err = Base().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = headerComponent().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = inputForm().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + 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, 2, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if day.Date().Weekday() == time.Monday { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = LegendComponent().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func inputForm() 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_Var2 := templ.GetChildren(ctx) + if templ_7745c5c3_Var2 == nil { + templ_7745c5c3_Var2 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + + urlParams := ctx.Value("urlParams").(url.Values) + user := ctx.Value("user").(models.User) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(user.Vorname + " " + user.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 36, Col: 66} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "

Überstunden

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(user.Overtime) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 39, Col: 42} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "

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

Abwesenheit

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +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 { + 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_Var9 := templ.GetChildren(ctx) + if templ_7745c5c3_Var9 == nil { + templ_7745c5c3_Var9 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + + user := ctx.Value("user").(models.User) + justify := "justify-center" + if day.IsWorkDay() && len(day.(*models.WorkDay).Bookings) > 1 { + justify = "justify-between" + } + var templ_7745c5c3_Var10 = []any{"grid-sub divide-x-1 hover:bg-neutral-200 transition-colors"} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = timeGaugeComponent(day.GetDayProgress(user), day.Date().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, 17, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var13 string + templ_7745c5c3_Var13, 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/timePage.templ`, Line: 103, Col: 13} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if day.IsWorkDay() { + + workDay, _ := day.(*models.WorkDay) + work, pause, overtime := workDay.GetAllWorkTimesVirtual(user) + if day.RequiresAction() { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "

Bitte anpassen

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + if work > 0 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "

Arbeitszeit:

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var14 string + templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(work)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 115, Col: 155} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "

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

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var15 string + templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(pause)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 118, Col: 173} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "

") + 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 overtime != 0 && len(workDay.Bookings) > 0 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var16 string + templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(helper.FormatDuration(overtime)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 123, Col: 41} + } + _, 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, 28, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = lineComponent().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var17 = []any{"flex flex-col gap-2 group w-full ", justify} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var17...) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = newAbsenceComponent().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if day.IsWorkDay() { + + workDay, _ := day.(*models.WorkDay) + if len(workDay.Bookings) < 1 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "

Keine Buchung gefunden. Bitte Arbeitsstunden oder Grund der Abwesenheit eingeben!

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + for _, booking := range workDay.Bookings { + templ_7745c5c3_Err = bookingComponent(booking).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = newBookingComponent(workDay).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if workDay.IsKurzArbeit() { + templ_7745c5c3_Err = absentInput(workDay.GetKurzArbeit()).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "

Kurzarbeit

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + } else { + + absentDay, _ := day.(*models.Absence) + templ_7745c5c3_Err = absentInput(*absentDay).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var20 string + templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(absentDay.AbwesenheitTyp.Name) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/timePage.templ`, Line: 154, Col: 39} + } + _, 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, 38, " bis ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var21 string + templ_7745c5c3_Var21, 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/timePage.templ`, Line: 154, Col: 116} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = changeButtonComponent("time-"+day.Date().Format("2006-01-02"), day.IsWorkDay()).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func absentInput(a models.Absence) 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_Var22 := templ.GetChildren(ctx) + if templ_7745c5c3_Var22 == nil { + templ_7745c5c3_Var22 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate 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/db.sql b/db.sql index 4ba7830..cdc1beb 100644 --- a/db.sql +++ b/db.sql @@ -203,7 +203,7 @@ WITH params AS ( 14::int AS start_days_ago, -- how many days back to start 0::int AS end_days_ahead, -- how many days forward (0 = today) 0::float AS pause_probability, - 0.2::float AS absence_probability + 0.0::float AS absence_probability ), days AS ( SELECT gs::date AS work_date, p.card_uid, p.geraet_id, p.pause_probability, p.absence_probability diff --git a/migrations/20250903233030_non_null_contraints.down.sql b/migrations/20250903233030_non_null_contraints.down.sql index 120b393..1afb8f1 100644 --- a/migrations/20250903233030_non_null_contraints.down.sql +++ b/migrations/20250903233030_non_null_contraints.down.sql @@ -1,4 +1,4 @@ -- 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, ALTER COLUMN "nachname" DROP NOT NULL, ALTER COLUMN "vorname" DROP NOT NULL; +ALTER TABLE "s_personal_daten" ALTER COLUMN "nachname" DROP NOT NULL, ALTER COLUMN "vorname" DROP NOT NULL; -- reverse: modify "anwesenheit" table ALTER TABLE "anwesenheit" ALTER COLUMN "anwesenheit_typ" DROP NOT NULL, ALTER COLUMN "geraet_id" DROP NOT NULL, ALTER COLUMN "timestamp" DROP NOT NULL; diff --git a/migrations/20250903233030_non_null_contraints.up.sql b/migrations/20250903233030_non_null_contraints.up.sql index 066f92a..e033628 100644 --- a/migrations/20250903233030_non_null_contraints.up.sql +++ b/migrations/20250903233030_non_null_contraints.up.sql @@ -1,4 +1,4 @@ -- modify "anwesenheit" table ALTER TABLE "anwesenheit" ALTER COLUMN "timestamp" SET NOT NULL, ALTER COLUMN "geraet_id" SET NOT NULL, ALTER COLUMN "anwesenheit_typ" SET NOT NULL; -- modify "s_personal_daten" table -ALTER TABLE "s_personal_daten" ALTER COLUMN "vorname" SET NOT NULL, ALTER COLUMN "nachname" SET NOT NULL, ALTER COLUMN "arbeitszeit_per_tag" SET NOT NULL, ALTER COLUMN "vorgesetzter_pers_nr" SET NOT NULL, ALTER COLUMN "arbeitszeit_per_woche" SET NOT NULL; +ALTER TABLE "s_personal_daten" ALTER COLUMN "vorname" SET NOT NULL, ALTER COLUMN "nachname" SET NOT NULL; diff --git a/migrations/20250904114004_intervals.up.sql b/migrations/20250904114004_intervals.up.sql index 272ceb8..b3c6baf 100644 --- a/migrations/20250904114004_intervals.up.sql +++ b/migrations/20250904114004_intervals.up.sql @@ -1,13 +1,19 @@ ALTER TABLE wochen_report - ALTER COLUMN ueberstunden TYPE interval - USING - make_interval( - hours => floor(ueberstunden)::int, - mins => round((ueberstunden - floor(ueberstunden)) * 60)::int - ), - ALTER COLUMN arbeitszeit TYPE interval - USING - make_interval( - hours => floor(arbeitszeit)::int, - mins => round((arbeitszeit - floor(arbeitszeit)) * 60)::int - ); + ADD COLUMN ueberstunden_interval interval, + ADD COLUMN arbeitszeit_interval interval; + +UPDATE wochen_report +SET + ueberstunden_interval = CASE WHEN ueberstunden IS NULL THEN NULL ELSE (ueberstunden::double precision * INTERVAL '1 hour') END, + arbeitszeit_interval = CASE WHEN arbeitszeit IS NULL THEN NULL ELSE (arbeitszeit::double precision * INTERVAL '1 hour') END; + +-- when happy, drop old columns and rename new ones +ALTER TABLE wochen_report + DROP COLUMN ueberstunden, + DROP COLUMN arbeitszeit; + +ALTER TABLE wochen_report + RENAME COLUMN ueberstunden_interval TO ueberstunden; + +ALTER TABLE wochen_report + RENAME COLUMN arbeitszeit_interval TO arbeitszeit; diff --git a/migrations/20250916093608_kurzarbeit.down.sql b/migrations/20250916093608_kurzarbeit.down.sql new file mode 100644 index 0000000..697259f --- /dev/null +++ b/migrations/20250916093608_kurzarbeit.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_kurzarbeit.up.sql b/migrations/20250916093608_kurzarbeit.up.sql new file mode 100644 index 0000000..b944343 --- /dev/null +++ b/migrations/20250916093608_kurzarbeit.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; diff --git a/migrations/atlas.sum b/migrations/atlas.sum index d57ff83..4950d34 100644 --- a/migrations/atlas.sum +++ b/migrations/atlas.sum @@ -1,7 +1,15 @@ -h1:31y/DB0ca2cm603nNckNvVCwm+XuMaVsoGUB+JvrOKs= -20250901201159_initial.up.sql h1:Mb1RlVdFvcxqU9HrSK6oNeURqFa3O4KzB3rDa+6+3gc= -20250901201250_control_tables.up.sql h1:a5LATgR/CRiC4GsqxkJ94TyJOxeTcW74eCnodIy+c1E= -20250901201710_triggers_extension.up.sql h1:z9b6Hk9btE2Ns4mU7B16HjvYBP6EEwHAXVlvPpkn978= -20250903221313_overtime.up.sql h1:t/B435ShW5ZEnzC81jRABWVZ5gNm7tPZPnOO6/ZY6ow= -20250903233030_non_null_contraints.up.sql h1:e7d+6ZdpEjPh2cc65N3S06oD2e6diMuG7+klhgYsym8= -20250904114004_intervals.up.sql h1:Sz8FIVvvcCIS3aIuSjyzFYLs32fjMcMMHk62shj6Qpw= +h1:3AxgD8mnu/F+JGtJu9FZvA9Ro0UUtGPgyjskKtfTYUQ= +20250901201159_initial.down.sql h1:cmF5CvNGqEfcmbRgiqaqDWERdNNRaMzarbNLJ/Y35o4= +20250901201159_initial.up.sql h1:Yrak/+wfQ4Tu/dVR/cUZ/75DlAcv4G/OJXDqpgSw47U= +20250901201250_control_tables.down.sql h1:f/KmhO9pOI45J8ZRjFonvD3CypB+rOoGOPN2WMFHvOw= +20250901201250_control_tables.up.sql h1:of5E07p0N1aen9CdQNEOrO7ffbKZC6kp4oK5KPzU9+g= +20250901201710_triggers_extension.down.sql h1:a9va3FSfHBWzODJSJO+ywNa2hiZwjG/vmvYGb3L1lnM= +20250901201710_triggers_extension.up.sql h1:nUBPd2eDssi/TwMVF/nOJkIM5rUM0iINdg1K9pZRZN0= +20250903221313_overtime.down.sql h1:X+jJESqcZ6ZTd2H563z6kRaXb4dn4sA02D3ck2795v8= +20250903221313_overtime.up.sql h1:C3DSiNVpe9v0Un1DEQ0lsy5yToR8iqcggv91GSr6tRE= +20250903233030_non_null_contraints.down.sql h1:42TZzPsji2Ze50k6sLwgIuNo4Trk3m3ni/aIfQJ97dE= +20250903233030_non_null_contraints.up.sql h1:k6zR5YNSAP4fo5QEc58KZ0LxvEz1nl0X/AAcZ+TG3I4= +20250904114004_intervals.down.sql h1:SquJAPinzFIRN6fJjLLIRsz59Tyr4RwGiGuOFI/N1SQ= +20250904114004_intervals.up.sql h1:AFqncTGOiEZVBbhWFqN2zlQ7DyhybB5wJr6a36Atk1E= +20250916093608_kurzarbeit.down.sql h1:ljM1a1pQCxOQiXRaXU04GC4V9yy2y20x5eUNQ/zyx+o= +20250916093608_kurzarbeit.up.sql h1:pTiw0VfGaf26mhJg4wf98Fqwn1kShJ+PiN2PiM4q1kk=