From 530d1e8683cc2dc977a9a99ebc5d13e646f51941 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Mon, 7 Sep 2026 14:40:03 +0200 Subject: [PATCH] =?UTF-8?q?Ber=C3=BCcksichtige=20Abwesenheiten=20bei=20der?= =?UTF-8?q?=20Berechnung=20der=20Restarbeitszeit=20und=20der=20Pausenanfor?= =?UTF-8?q?derungen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/services/TimeEntryService.js | 34 +++++++++++++++--------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/backend/src/services/TimeEntryService.js b/backend/src/services/TimeEntryService.js index 596b489..be85f4e 100755 --- a/backend/src/services/TimeEntryService.js +++ b/backend/src/services/TimeEntryService.js @@ -325,6 +325,20 @@ class TimeEntryService { }, raw: true }); + + // Die Abwesenheit des heutigen Tages reduziert das Soll für die + // Restarbeitszeit (z. B. 8 h Tagesziel - 4 h Urlaub = 4 h Arbeit). + const weekData = await this.getWeekOverview(uid, 0); + const todayIso = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`; + const today = weekData.days.find(day => day.date === todayIso); + const nonWorkingHoursToday = today?.sick?.hours + ?? today?.holiday?.hours + ?? today?.vacation?.hours + ?? 0; + const plannedWorkHours = timewish?.wishtype === 2 && timewish.hours + ? timewish.hours + : userDailyHours; + const targetWorkSeconds = Math.max(0, plannedWorkHours - nonWorkingHoursToday) * 3600; // Berechne "Offen" nur wenn aktuell gearbeitet wird if (currentlyWorked) { @@ -336,6 +350,8 @@ class TimeEntryService { // Parse end_time (HH:MM:SS) const [endHour, endMinute] = timewish.end_time.split(':').map(Number); const endTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), endHour, endMinute, 0); + // Ein Uhrzeit-Wunsch endet bei einer Teilabwesenheit entsprechend früher. + endTime.setHours(endTime.getHours() - nonWorkingHoursToday); const remainingMs = endTime.getTime() - now.getTime(); @@ -355,7 +371,7 @@ class TimeEntryService { // Parse currentlyWorked const [workedH, workedM, workedS] = currentlyWorked.split(':').map(Number); const workedSeconds = workedH * 3600 + workedM * 60 + workedS; - const wishSeconds = Math.floor(timewish.hours * 3600); + const wishSeconds = targetWorkSeconds; const remainingSeconds = wishSeconds - workedSeconds; @@ -370,10 +386,10 @@ class TimeEntryService { } } } else { - // Kein Timewish - Standard: 8 Stunden + // Kein Timewish - Tagesziel aus dem Profil, abzüglich Abwesenheit const [workedH, workedM, workedS] = currentlyWorked.split(':').map(Number); const workedSeconds = workedH * 3600 + workedM * 60 + workedS; - const standardSeconds = 8 * 3600; // 8 Stunden + const standardSeconds = targetWorkSeconds; const remainingSeconds = standardSeconds - workedSeconds; @@ -394,16 +410,12 @@ class TimeEntryService { if (currentlyWorked) { // Geplante Arbeitszeit - let plannedWorkHours = 8; // Standard - - if (timewish && timewish.wishtype === 2 && timewish.hours) { - plannedWorkHours = timewish.hours; - } + const plannedWorkHoursForBreak = Math.max(0, plannedWorkHours - nonWorkingHoursToday); // Gesetzliche Pausen: ab 6h -> 30min, ab 9h -> 45min - if (plannedWorkHours >= 9) { + if (plannedWorkHoursForBreak >= 9) { requiredBreakMinutes = 45; - } else if (plannedWorkHours >= 6) { + } else if (plannedWorkHoursForBreak >= 6) { requiredBreakMinutes = 30; } @@ -464,8 +476,6 @@ class TimeEntryService { const totalOvertimeResult = await this._calculateTotalOvertime(uid, runningEntry); // Berechne Überstunden für die aktuelle Woche - const weekData = await this.getWeekOverview(uid, 0); - console.log(`🔍 Wochenüberstunden-Berechnung START: userDailyHours=${userDailyHours}`); let weekSollMinutes = 0; // Soll-Arbeitszeit für die Woche