Refactor TimeEntryService to enhance time calculations by incorporating missing break minutes into remaining time calculations. Update pause duration handling to account for timefix corrections, ensuring accurate representation of start and end times. Improve server value usage logic in StatusBox component for better handling of worked time display.

This commit is contained in:
Torsten Schulz (local)
2025-10-20 09:41:50 +02:00
parent 4c9189865f
commit 834df97c65
2 changed files with 61 additions and 11 deletions

View File

@@ -699,9 +699,9 @@ class TimeEntryService {
const currentTime = new Date();
// ===== GENERELL =====
// Verbleibende Zeit = Offen - Gesamt-Überstunden
// Verbleibende Zeit = Offen - Gesamt-Überstunden + fehlende Pausen
const generalOvertimeMinutes = totalOvertimeResult.minutes || 0;
const generalRemainingMinutes = openMinutes - generalOvertimeMinutes;
const generalRemainingMinutes = openMinutes - generalOvertimeMinutes + missingBreakMinutes;
if (generalRemainingMinutes <= 0) {
adjustedEndTodayGeneral = 'Arbeitsende erreicht';
@@ -714,9 +714,9 @@ class TimeEntryService {
}
// ===== WOCHE =====
// Verbleibende Zeit = Offen - Wochen-Über/Unterstunden
// Verbleibende Zeit = Offen - Wochen-Über/Unterstunden + fehlende Pausen
const weekOvertimeMinutes = overtimeMinutes; // Bereits berechnet
const weekRemainingMinutes = openMinutes - weekOvertimeMinutes;
const weekRemainingMinutes = openMinutes - weekOvertimeMinutes + missingBreakMinutes;
if (weekRemainingMinutes <= 0) {
adjustedEndTodayWeek = 'Arbeitsende erreicht';
@@ -2220,8 +2220,13 @@ class TimeEntryService {
return eDate >= startDate;
});
const pauseStarts = {};
// Hole Timefixes für alle relevanten Einträge (inklusive Pausen)
const allEntryIds = relevantEntries.map(e => e.id);
const pauseTimefixMap = await worklogRepository.getTimefixesByWorklogIds(allEntryIds);
relevantEntries.forEach(entry => {
let eState = entry.state;
if (typeof eState === 'string') {
@@ -2239,7 +2244,15 @@ class TimeEntryService {
} else if (eAction === 'stop pause' && entry.relatedTo_id) {
const startPause = pauseStarts[entry.relatedTo_id];
if (startPause) {
const duration = new Date(entry.tstamp).getTime() - new Date(startPause.tstamp).getTime();
// Prüfe auf Timefix-Korrekturen für Pausen
const pauseStartFix = pauseTimefixMap.get(startPause.id)?.find(f => f.fix_type === 'start pause');
const pauseEndFix = pauseTimefixMap.get(entry.id)?.find(f => f.fix_type === 'stop pause');
// Verwende korrigierte Zeiten falls vorhanden
const pStartTime = pauseStartFix?.fix_date_time || startPause.tstamp;
const pEndTime = pauseEndFix?.fix_date_time || entry.tstamp;
const duration = new Date(pEndTime).getTime() - new Date(pStartTime).getTime();
pauseDurations.push(duration);
delete pauseStarts[entry.relatedTo_id];
}
@@ -2250,12 +2263,47 @@ class TimeEntryService {
const runningPauseIds = Object.keys(pauseStarts);
if (runningPauseIds.length > 0) {
const pauseId = parseInt(runningPauseIds[0]);
currentPauseStart = pauseStarts[pauseId].tstamp;
const pauseEntry = pauseStarts[pauseId];
// Prüfe auf Timefix-Korrektur für laufende Pause
const currentPauseTimefix = pauseTimefixMap.get(pauseId)?.find(f => f.fix_type === 'start pause');
currentPauseStart = currentPauseTimefix?.fix_date_time || pauseEntry.tstamp;
}
// Prüfe auf Timefix-Korrektur für die Start-Zeit (timefixMap bereits geholt in pauseTimefixMap)
const startTimefix = pauseTimefixMap.get(startWorkId)?.find(f => f.fix_type === 'start work');
let displayStartTime = startWorkEntry.tstamp;
if (startTimefix && startTimefix.fix_date_time) {
// Verwende korrigierte Zeit
displayStartTime = startTimefix.fix_date_time;
}
// Stelle sicher, dass startTime ein String ist (kein Date-Objekt)
// Konvertiere UTC zu lokaler Zeit für Frontend
let startTimeStr;
if (typeof displayStartTime === 'string') {
// Wenn es ein UTC-String ist, konvertiere zu lokaler Zeit
const utcDate = new Date(displayStartTime);
const year = utcDate.getFullYear();
const month = String(utcDate.getMonth() + 1).padStart(2, '0');
const day = String(utcDate.getDate()).padStart(2, '0');
const hours = String(utcDate.getHours()).padStart(2, '0');
const minutes = String(utcDate.getMinutes()).padStart(2, '0');
const seconds = String(utcDate.getSeconds()).padStart(2, '0');
startTimeStr = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
} else {
startTimeStr = displayStartTime.toISOString();
}
// Stelle sicher, dass currentPauseStart auch ein String ist
const currentPauseStartStr = currentPauseStart
? (typeof currentPauseStart === 'string' ? currentPauseStart : currentPauseStart.toISOString())
: null;
const result = {
id: startWorkId,
startTime: startWorkEntry.tstamp,
startTime: startTimeStr, // Explizit als String
endTime: null,
description: (state?.description || ''),
project: (state?.project || 'Allgemein'),
@@ -2263,7 +2311,7 @@ class TimeEntryService {
isRunning: true,
userId: uid,
pauses: pauseDurations,
currentPauseStart: currentPauseStart
currentPauseStart: currentPauseStartStr
};
return result;

View File

@@ -157,8 +157,10 @@ const updateCurrentlyWorkedTime = () => {
return
}
// Wenn wir einen Server-Wert haben, nutze diesen als Basis
if (serverWorkedTime.value && serverTimestamp.value) {
// Verwende Server-Werte nur, wenn NICHT gearbeitet wird (oder kein laufender Start vorhanden)
const shouldUseServerSummary = !workStartTime.value
if (shouldUseServerSummary && serverWorkedTime.value && serverTimestamp.value) {
// Parse Server-Zeit (HH:MM:SS)
const parts = serverWorkedTime.value.split(':')
const serverSeconds = parseInt(parts[0]) * 3600 + parseInt(parts[1]) * 60 + parseInt(parts[2])
@@ -181,7 +183,7 @@ const updateCurrentlyWorkedTime = () => {
currentlyWorkedTime.value = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
} else {
// Fallback: Wenn kein Server-Wert, aber workStartTime vorhanden
// Fallback/Standard: Aus Startzeit berechnen (bevorzugt bei laufender Arbeit)
if (!workStartTime.value) {
currentlyWorkedTime.value = '—'
return