diff --git a/backend/src/services/TimeEntryService.js b/backend/src/services/TimeEntryService.js index c3b5ed9..aa23563 100644 --- a/backend/src/services/TimeEntryService.js +++ b/backend/src/services/TimeEntryService.js @@ -324,6 +324,8 @@ class TimeEntryService { } // Berechne "Offen" basierend auf timewish (oder Standard: 8 Stunden) + // WICHTIG: Diese Zeit wird OHNE fehlende Pausen berechnet + // Das Frontend addiert die fehlenden Pausen dann zur "Normales Arbeitsende" Berechnung let open = null; const { Timewish } = database.getModels(); @@ -458,6 +460,23 @@ class TimeEntryService { // Fehlende Pausenzeit const missingBreakMinutes = Math.max(0, requiredBreakMinutes - alreadyTakenBreakMinutes); + // Addiere fehlende Pausen zur "Offen" Zeit + if (open && open !== '—' && open !== 'Arbeitsende erreicht') { + const openParts = open.split(':'); + const openH = parseInt(openParts[0]); + const openM = parseInt(openParts[1]); + const openS = parseInt(openParts[2] || 0); + const openMinutes = openH * 60 + openM + missingBreakMinutes; + + const newOpenH = Math.floor(openMinutes / 60); + const newOpenM = openMinutes % 60; + const newOpenS = openS; + + console.log(`🔍 DEBUG Offen-Berechnung: Original=${open}, Fehlende Pausen=${missingBreakMinutes}min, Neu=${newOpenH}:${newOpenM.toString().padStart(2, '0')}:${newOpenS.toString().padStart(2, '0')}`); + + open = `${newOpenH.toString().padStart(2, '0')}:${newOpenM.toString().padStart(2, '0')}:${newOpenS.toString().padStart(2, '0')}`; + } + // Berechne Überstunden über den gesamten Zeitraum (alle Wochen) // Neue Berechnung: Timewish-basiert const totalOvertimeResult = await this._calculateTotalOvertime(uid, runningEntry); diff --git a/frontend/src/components/StatusBox.vue b/frontend/src/components/StatusBox.vue index aec59c3..1be592f 100644 --- a/frontend/src/components/StatusBox.vue +++ b/frontend/src/components/StatusBox.vue @@ -247,19 +247,26 @@ const updateOpenTime = () => { openTime.value = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}` - // Berechne "Normales Arbeitsende" = Jetzt + Offen + fehlende Pausen - const totalRemainingSeconds = remainingSeconds + (missingBreakMinutes.value * 60) + // Berechne "Normales Arbeitsende" = Jetzt + Offen (Pausen sind bereits in Offen enthalten) + const totalRemainingSeconds = remainingSeconds const endTimestamp = now + (totalRemainingSeconds * 1000) const endDate = new Date(endTimestamp) const endHours = endDate.getHours() const endMinutes = endDate.getMinutes() const endSeconds = endDate.getSeconds() - // Zeige auch fehlende Pausen an (falls vorhanden) - if (missingBreakMinutes.value > 0) { - regularEndTime.value = `${endHours.toString().padStart(2, '0')}:${endMinutes.toString().padStart(2, '0')}:${endSeconds.toString().padStart(2, '0')} (+${missingBreakMinutes.value}min Pause)` - } else { - regularEndTime.value = `${endHours.toString().padStart(2, '0')}:${endMinutes.toString().padStart(2, '0')}:${endSeconds.toString().padStart(2, '0')}` + // Ausgabe ohne zusätzlichen Pausen-Hinweis; Zeit stammt bereits inkl. Pausen aus Backend + regularEndTime.value = `${endHours.toString().padStart(2, '0')}:${endMinutes.toString().padStart(2, '0')}:${endSeconds.toString().padStart(2, '0')} Uhr` + + // Override: Berechne Normales Arbeitsende deterministisch aus Start + 8h + fehlende Pausen + if (workStartTime.value) { + const baseDailyMinutes = 8 * 60 // Fallback auf 8h + const endTs = workStartTime.value + (baseDailyMinutes + (missingBreakMinutes.value || 0)) * 60 * 1000 + const endDt = new Date(endTs) + const eh = endDt.getHours() + const em = endDt.getMinutes() + const es = endDt.getSeconds() + regularEndTime.value = `${eh.toString().padStart(2, '0')}:${em.toString().padStart(2, '0')}:${es.toString().padStart(2, '0')} Uhr` } } else { openTime.value = 'Arbeitsende erreicht' @@ -384,9 +391,9 @@ onBeforeUnmount(() => { const displayRows = computed(() => { const rows = { - 'Derzeit gearbeitet': currentlyWorkedTime.value, // Verwende berechneten Wert - 'Offen': openTime.value, // Verwende berechneten Wert - 'Normales Arbeitsende': regularEndTime.value // Verwende berechneten Wert + 'Derzeit gearbeitet': currentlyWorkedTime.value === '—' ? currentlyWorkedTime.value : currentlyWorkedTime.value + ' h', + 'Offen': openTime.value === '—' ? openTime.value : openTime.value + ' h', + 'Normales Arbeitsende': regularEndTime.value // Verwende berechneten Wert (hat bereits "Uhr") } // Füge andere Stats hinzu @@ -416,16 +423,19 @@ const displayRows = computed(() => { if (key === 'overtime') { const isNegative = val.startsWith('-'); const displayLabel = isNegative ? 'Fehlzeit (Woche)' : 'Überstunden (Woche)'; - const displayValue = isNegative ? val.substring(1) : val; // Entferne Minus-Zeichen + const displayValue = isNegative ? val.substring(1) + ' h' : val + ' h'; // Entferne Minus-Zeichen, füge " h" hinzu rows[displayLabel] = displayValue; } else if (key === 'totalOvertime') { const isNegative = val.startsWith('-'); const displayLabel = isNegative ? 'Fehlzeit (Gesamt)' : 'Überstunden (Gesamt)'; - const displayValue = isNegative ? val.substring(1) : val; // Entferne Minus-Zeichen + const displayValue = isNegative ? val.substring(1) + ' h' : val + ' h'; // Entferne Minus-Zeichen, füge " h" hinzu rows[displayLabel] = displayValue; } else if (key === 'adjustedEndTodayGeneral' || key === 'adjustedEndTodayWeek') { // Füge " Uhr" zu Uhrzeiten hinzu rows[label] = val + ' Uhr'; + } else if (key === 'weekWorktime' || key === 'openForWeek' || key === 'nonWorkingHours') { + // Füge " h" zu Zeiten hinzu (außer bei "—") + rows[label] = val === '—' ? val : val + ' h'; } else { rows[label] = val; }