Compare commits
10 Commits
8b1a3368e2
...
6cc8903e06
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6cc8903e06 | ||
|
|
e71988e0b7 | ||
|
|
a1b5e191f3 | ||
|
|
1eff170a7b | ||
|
|
dfd169c78d | ||
|
|
363f4567c2 | ||
|
|
d99aa96270 | ||
|
|
0bcdec68ef | ||
|
|
1f20500b5f | ||
|
|
b16a09059f |
@@ -16,9 +16,7 @@ const unhashRequestIds = (req, res, next) => {
|
||||
|
||||
// Route-Parameter verarbeiten
|
||||
if (req.params && typeof req.params === 'object') {
|
||||
console.log('DEBUG unhashRequest: req.params before =', req.params);
|
||||
req.params = unhashRequestData(req.params);
|
||||
console.log('DEBUG unhashRequest: req.params after =', req.params);
|
||||
}
|
||||
|
||||
next();
|
||||
|
||||
@@ -232,6 +232,10 @@ class TimeEntryService {
|
||||
// Hole alle Einträge von heute (wird auch für Pausen verwendet)
|
||||
allEntries = await worklogRepository.findByDateRange(uid, todayStart, todayEnd);
|
||||
|
||||
// Hole Timefixes für alle Einträge von heute
|
||||
const allEntryIds = allEntries.map(e => e.id);
|
||||
const timefixMap = await worklogRepository.getTimefixesByWorklogIds(allEntryIds);
|
||||
|
||||
// Finde alle Start-Work-Paare von heute
|
||||
const workBlocks = [];
|
||||
const startWorks = {};
|
||||
@@ -249,14 +253,22 @@ class TimeEntryService {
|
||||
const action = state?.action || state;
|
||||
|
||||
if (action === 'start work') {
|
||||
// Prüfe auf Timefix-Korrektur
|
||||
const startFix = timefixMap.get(entry.id)?.find(f => f.fix_type === 'start work');
|
||||
const startTime = startFix?.fix_date_time || entry.tstamp;
|
||||
|
||||
startWorks[entry.id] = {
|
||||
id: entry.id,
|
||||
startTime: entry.tstamp,
|
||||
startTime: startTime,
|
||||
endTime: null,
|
||||
pauses: []
|
||||
};
|
||||
} else if (action === 'stop work' && entry.relatedTo_id && startWorks[entry.relatedTo_id]) {
|
||||
startWorks[entry.relatedTo_id].endTime = entry.tstamp;
|
||||
// Prüfe auf Timefix-Korrektur
|
||||
const endFix = timefixMap.get(entry.id)?.find(f => f.fix_type === 'stop work');
|
||||
const endTime = endFix?.fix_date_time || entry.tstamp;
|
||||
|
||||
startWorks[entry.relatedTo_id].endTime = endTime;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -274,9 +286,13 @@ class TimeEntryService {
|
||||
const action = state?.action || state;
|
||||
|
||||
if (action === 'start pause' && entry.relatedTo_id && startWorks[entry.relatedTo_id]) {
|
||||
// Prüfe auf Timefix-Korrektur
|
||||
const pauseStartFix = timefixMap.get(entry.id)?.find(f => f.fix_type === 'start pause');
|
||||
const pauseStartTime = pauseStartFix?.fix_date_time || entry.tstamp;
|
||||
|
||||
startWorks[entry.relatedTo_id].pauses.push({
|
||||
id: entry.id,
|
||||
startTime: entry.tstamp,
|
||||
startTime: pauseStartTime,
|
||||
endTime: null
|
||||
});
|
||||
} else if (action === 'stop pause' && entry.relatedTo_id) {
|
||||
@@ -284,7 +300,9 @@ class TimeEntryService {
|
||||
Object.values(startWorks).forEach(block => {
|
||||
const pause = block.pauses.find(p => p.id === entry.relatedTo_id);
|
||||
if (pause) {
|
||||
pause.endTime = entry.tstamp;
|
||||
// Prüfe auf Timefix-Korrektur
|
||||
const pauseEndFix = timefixMap.get(entry.id)?.find(f => f.fix_type === 'stop pause');
|
||||
pause.endTime = pauseEndFix?.fix_date_time || entry.tstamp;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -324,6 +342,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 +478,21 @@ 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;
|
||||
|
||||
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);
|
||||
@@ -465,6 +500,8 @@ class TimeEntryService {
|
||||
// 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
|
||||
let weekIstMinutes = 0; // Ist-Arbeitszeit für die Woche
|
||||
|
||||
@@ -549,13 +586,17 @@ class TimeEntryService {
|
||||
});
|
||||
|
||||
let daySollHours = userDailyHours; // Fallback: User's daily_hours
|
||||
console.log(` Tag ${day.date}: userDailyHours=${userDailyHours}, applicableTimewish=${applicableTimewish ? applicableTimewish.hours + 'h' : 'keine'}`);
|
||||
|
||||
if (applicableTimewish && applicableTimewish.wishtype === 2 && applicableTimewish.hours) {
|
||||
daySollHours = applicableTimewish.hours;
|
||||
console.log(` → Verwende Timewish: ${daySollHours}h`);
|
||||
}
|
||||
|
||||
// Bei halbem Urlaubstag: Soll halbiert
|
||||
if (day.vacation && day.vacation.halfDay) {
|
||||
daySollHours = daySollHours / 2;
|
||||
console.log(` → Halber Urlaubstag: ${daySollHours}h`);
|
||||
}
|
||||
|
||||
weekSollMinutes += daySollHours * 60;
|
||||
@@ -564,11 +605,15 @@ class TimeEntryService {
|
||||
if (day.netWorkTime) {
|
||||
const [h, m] = day.netWorkTime.split(':').map(Number);
|
||||
weekIstMinutes += h * 60 + m;
|
||||
console.log(` Tag ${day.date}: netWorkTime=${day.netWorkTime}, Soll=${daySollHours}h, Ist=${h}:${m}`);
|
||||
}
|
||||
});
|
||||
|
||||
// Überstunden = Ist - Soll
|
||||
const overtimeMinutes = weekIstMinutes - weekSollMinutes;
|
||||
|
||||
console.log(`🔍 Wochenüberstunden: weekIst=${weekIstMinutes}min (${Math.floor(weekIstMinutes/60)}:${weekIstMinutes%60}), weekSoll=${weekSollMinutes}min (${Math.floor(weekSollMinutes/60)}:${weekSollMinutes%60}), overtime=${overtimeMinutes}min`);
|
||||
|
||||
const overtimeHours = Math.floor(Math.abs(overtimeMinutes) / 60);
|
||||
const overtimeMins = Math.abs(overtimeMinutes) % 60;
|
||||
const overtimeSign = overtimeMinutes >= 0 ? '+' : '-';
|
||||
@@ -650,14 +695,18 @@ class TimeEntryService {
|
||||
const [h, m, s] = currentlyWorked.split(':').map(Number);
|
||||
dayIstMinutes = h * 60 + m;
|
||||
weekIstMinutesTotal += dayIstMinutes;
|
||||
console.log(` HEUTE ${day.date}: currentlyWorked=${currentlyWorked}, Soll=${daySollHours}h, Ist=${h}:${m}`);
|
||||
} else if (!isToday && day.netWorkTime) {
|
||||
// Für vergangene Tage: Verwende netWorkTime
|
||||
const [h, m] = day.netWorkTime.split(':').map(Number);
|
||||
dayIstMinutes = h * 60 + m;
|
||||
weekIstMinutesTotal += dayIstMinutes;
|
||||
console.log(` Vergangener Tag ${day.date}: netWorkTime=${day.netWorkTime}, Soll=${daySollHours}h, Ist=${h}:${m}`);
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`🔍 Offen für Woche: weekIstTotal=${weekIstMinutesTotal}min, weekSollTotal=${weekSollMinutesTotal}min`);
|
||||
|
||||
// Offen für Woche = Wochensoll - Wochenist (bisher)
|
||||
const openForWeekMinutes = weekSollMinutesTotal - weekIstMinutesTotal;
|
||||
|
||||
@@ -699,9 +748,10 @@ class TimeEntryService {
|
||||
const currentTime = new Date();
|
||||
|
||||
// ===== GENERELL =====
|
||||
// Verbleibende Zeit = Offen - Gesamt-Überstunden + fehlende Pausen
|
||||
// Verbleibende Zeit = Offen - Gesamt-Überstunden
|
||||
// WICHTIG: "open" enthält bereits die fehlenden Pausen!
|
||||
const generalOvertimeMinutes = totalOvertimeResult.minutes || 0;
|
||||
const generalRemainingMinutes = openMinutes - generalOvertimeMinutes + missingBreakMinutes;
|
||||
const generalRemainingMinutes = openMinutes - generalOvertimeMinutes;
|
||||
|
||||
if (generalRemainingMinutes <= 0) {
|
||||
adjustedEndTodayGeneral = 'Arbeitsende erreicht';
|
||||
@@ -714,9 +764,10 @@ class TimeEntryService {
|
||||
}
|
||||
|
||||
// ===== WOCHE =====
|
||||
// Verbleibende Zeit = Offen - Wochen-Über/Unterstunden + fehlende Pausen
|
||||
// Verbleibende Zeit = Offen - Wochen-Über/Unterstunden
|
||||
// WICHTIG: "open" enthält bereits die fehlenden Pausen!
|
||||
const weekOvertimeMinutes = overtimeMinutes; // Bereits berechnet
|
||||
const weekRemainingMinutes = openMinutes - weekOvertimeMinutes + missingBreakMinutes;
|
||||
const weekRemainingMinutes = openMinutes - weekOvertimeMinutes;
|
||||
|
||||
if (weekRemainingMinutes <= 0) {
|
||||
adjustedEndTodayWeek = 'Arbeitsende erreicht';
|
||||
|
||||
78
deploy.sh
78
deploy.sh
@@ -202,13 +202,8 @@ setup_backend() {
|
||||
npm config set audit false >/dev/null 2>&1 || true
|
||||
npm config set progress false >/dev/null 2>&1 || true
|
||||
npm config set loglevel warn >/dev/null 2>&1 || true
|
||||
# Schnelle, reproduzierbare Installation nur Prod-Dependencies
|
||||
timeout 600 bash -lc "npm ci --omit=dev --no-audit --no-fund --silent --loglevel=warn --no-progress" || {
|
||||
print_warning "npm ci ist fehlgeschlagen oder hat zu lange gedauert. Versuche fallback ohne timeout..."
|
||||
npm ci --omit=dev --no-audit --no-fund --silent --loglevel=warn --no-progress || {
|
||||
print_error "npm ci (Backend) fehlgeschlagen"; exit 1;
|
||||
}
|
||||
}
|
||||
# Backend braucht alle Dependencies (auch dev für Build-Tools)
|
||||
npm install --no-audit --no-fund --loglevel=warn
|
||||
|
||||
if [ ! -f .env ]; then
|
||||
print_warning ".env Datei nicht gefunden!"
|
||||
@@ -239,12 +234,8 @@ setup_frontend() {
|
||||
npm config set audit false >/dev/null 2>&1 || true
|
||||
npm config set progress false >/dev/null 2>&1 || true
|
||||
npm config set loglevel warn >/dev/null 2>&1 || true
|
||||
timeout 600 bash -lc "npm ci --omit=dev --no-audit --no-fund --silent --loglevel=warn --no-progress" || {
|
||||
print_warning "npm ci ist fehlgeschlagen oder hat zu lange gedauert. Versuche fallback ohne timeout..."
|
||||
npm ci --omit=dev --no-audit --no-fund --silent --loglevel=warn --no-progress || {
|
||||
print_error "npm ci (Frontend) fehlgeschlagen"; exit 1;
|
||||
}
|
||||
}
|
||||
# Frontend braucht dev-Dependencies für den Build (vite, etc.)
|
||||
npm install --no-audit --no-fund --loglevel=warn
|
||||
|
||||
# .env.production erstellen falls nicht vorhanden
|
||||
if [ ! -f ".env.production" ]; then
|
||||
@@ -486,16 +477,27 @@ do_update() {
|
||||
# Backend aktualisieren
|
||||
print_info "Aktualisiere Backend Dependencies..."
|
||||
cd $BACKEND_DIR
|
||||
npm config set fund false >/dev/null 2>&1 || true
|
||||
npm config set audit false >/dev/null 2>&1 || true
|
||||
npm config set progress false >/dev/null 2>&1 || true
|
||||
npm config set loglevel warn >/dev/null 2>&1 || true
|
||||
timeout 600 bash -lc "npm ci --omit=dev --no-audit --no-fund --silent --loglevel=warn --no-progress" || {
|
||||
print_warning "npm ci ist fehlgeschlagen oder hat zu lange gedauert. Versuche fallback ohne timeout..."
|
||||
npm ci --omit=dev --no-audit --no-fund --silent --loglevel=warn --no-progress || {
|
||||
print_error "npm ci (Backend Update) fehlgeschlagen"; exit 1;
|
||||
}
|
||||
}
|
||||
|
||||
# Prüfe ob package-lock.json existiert
|
||||
if [ ! -f "package-lock.json" ]; then
|
||||
print_warning "package-lock.json fehlt! Verwende npm install statt npm ci"
|
||||
npm install --no-audit --no-fund --loglevel=warn
|
||||
else
|
||||
npm config set fund false >/dev/null 2>&1 || true
|
||||
npm config set audit false >/dev/null 2>&1 || true
|
||||
npm config set progress false >/dev/null 2>&1 || true
|
||||
npm config set loglevel warn >/dev/null 2>&1 || true
|
||||
|
||||
# Backend braucht alle Dependencies (auch dev für Build-Tools)
|
||||
if ! npm ci --no-audit --no-fund --loglevel=warn 2>&1; then
|
||||
print_warning "npm ci fehlgeschlagen. Fallback auf npm install..."
|
||||
rm -rf node_modules
|
||||
npm install --no-audit --no-fund --loglevel=warn || {
|
||||
print_error "npm install (Backend Update) fehlgeschlagen"
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
fi
|
||||
|
||||
# Frontend aktualisieren
|
||||
print_info "Aktualisiere Frontend..."
|
||||
@@ -510,16 +512,26 @@ VITE_API_URL=/api
|
||||
EOF
|
||||
fi
|
||||
|
||||
npm config set fund false >/dev/null 2>&1 || true
|
||||
npm config set audit false >/dev/null 2>&1 || true
|
||||
npm config set progress false >/dev/null 2>&1 || true
|
||||
npm config set loglevel warn >/dev/null 2>&1 || true
|
||||
timeout 600 bash -lc "npm ci --omit=dev --no-audit --no-fund --silent --loglevel=warn --no-progress" || {
|
||||
print_warning "npm ci ist fehlgeschlagen oder hat zu lange gedauert. Versuche fallback ohne timeout..."
|
||||
npm ci --omit=dev --no-audit --no-fund --silent --loglevel=warn --no-progress || {
|
||||
print_error "npm ci (Frontend Update) fehlgeschlagen"; exit 1;
|
||||
}
|
||||
}
|
||||
# Prüfe ob package-lock.json existiert
|
||||
if [ ! -f "package-lock.json" ]; then
|
||||
print_warning "package-lock.json fehlt! Verwende npm install statt npm ci"
|
||||
npm install --no-audit --no-fund --loglevel=warn
|
||||
else
|
||||
npm config set fund false >/dev/null 2>&1 || true
|
||||
npm config set audit false >/dev/null 2>&1 || true
|
||||
npm config set progress false >/dev/null 2>&1 || true
|
||||
npm config set loglevel warn >/dev/null 2>&1 || true
|
||||
|
||||
# Frontend braucht dev-Dependencies für den Build (vite, etc.)
|
||||
if ! npm ci --no-audit --no-fund --loglevel=warn 2>&1; then
|
||||
print_warning "npm ci fehlgeschlagen. Fallback auf npm install..."
|
||||
rm -rf node_modules
|
||||
npm install --no-audit --no-fund --loglevel=warn || {
|
||||
print_error "npm install (Frontend Update) fehlgeschlagen"
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
fi
|
||||
|
||||
# Sauberer Build
|
||||
rm -rf dist/
|
||||
|
||||
@@ -117,16 +117,12 @@ const fetchWorklogData = async () => {
|
||||
if (response.ok) {
|
||||
const result = await response.json()
|
||||
|
||||
console.log('DEBUG fetchWorklogData: result =', result)
|
||||
console.log('DEBUG fetchWorklogData: currentState =', currentState.value)
|
||||
|
||||
// Das Backend gibt direkt das Entry-Objekt zurück, nicht { entry: ... }
|
||||
if (result && result.startTime && (currentState.value === 'start work' || currentState.value === 'stop pause')) {
|
||||
// Arbeit läuft
|
||||
workStartTime.value = new Date(result.startTime).getTime()
|
||||
pauseDurations.value = result.pauses || []
|
||||
lastPauseStartTime.value = null
|
||||
console.log('DEBUG: Arbeit läuft, startTime:', result.startTime, 'pauses:', pauseDurations.value.length)
|
||||
} else if (result && result.startTime && currentState.value === 'start pause') {
|
||||
// In Pause
|
||||
workStartTime.value = new Date(result.startTime).getTime()
|
||||
@@ -135,13 +131,11 @@ const fetchWorklogData = async () => {
|
||||
if (result.currentPauseStart) {
|
||||
lastPauseStartTime.value = new Date(result.currentPauseStart).getTime()
|
||||
}
|
||||
console.log('DEBUG: In Pause, startTime:', result.startTime, 'currentPauseStart:', result.currentPauseStart)
|
||||
} else {
|
||||
// Nicht am Arbeiten
|
||||
workStartTime.value = null
|
||||
lastPauseStartTime.value = null
|
||||
pauseDurations.value = []
|
||||
console.log('DEBUG: Nicht am Arbeiten')
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -247,19 +241,46 @@ 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 aus Server "open" Zeit
|
||||
// Nur überschreiben wenn wir Server-Daten haben
|
||||
if (serverOpenTime.value && serverTimestamp.value) {
|
||||
// Parse Server-Offen-Zeit
|
||||
const openParts = serverOpenTime.value.split(':')
|
||||
const openSeconds = parseInt(openParts[0]) * 3600 + parseInt(openParts[1]) * 60 + parseInt(openParts[2] || 0)
|
||||
|
||||
// Berechne vergangene Zeit seit Server-Timestamp
|
||||
const now = Date.now()
|
||||
const elapsedMs = now - serverTimestamp.value
|
||||
let elapsedSeconds = Math.floor(elapsedMs / 1000)
|
||||
|
||||
// Wenn in Pause, zähle die Zeit nicht
|
||||
if (currentState.value === 'start pause') {
|
||||
elapsedSeconds = 0
|
||||
}
|
||||
|
||||
const remainingSeconds = openSeconds - elapsedSeconds
|
||||
|
||||
if (remainingSeconds > 0) {
|
||||
const endTs = now + (remainingSeconds * 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 {
|
||||
regularEndTime.value = 'Erreicht'
|
||||
}
|
||||
}
|
||||
} else {
|
||||
openTime.value = 'Arbeitsende erreicht'
|
||||
@@ -297,11 +318,9 @@ const handleAction = async (action) => {
|
||||
}
|
||||
|
||||
// Aktualisiere Status und Worklog-Daten sofort
|
||||
console.log('DEBUG: Lade Daten nach Stempel-Aktion neu...')
|
||||
await fetchCurrentState()
|
||||
await fetchWorklogData()
|
||||
await fetchStats()
|
||||
console.log('DEBUG: Daten neu geladen, stats =', stats.value)
|
||||
|
||||
// Event auslösen für andere Komponenten (z.B. WeekOverview)
|
||||
window.dispatchEvent(new CustomEvent('worklog-updated'))
|
||||
@@ -347,7 +366,6 @@ const rightButton = computed(() => {
|
||||
|
||||
// Event-Handler für Login
|
||||
const handleLoginCompleted = async () => {
|
||||
console.log('DEBUG: Login completed, lade Daten neu...')
|
||||
await fetchCurrentState()
|
||||
await fetchWorklogData()
|
||||
await fetchStats()
|
||||
@@ -383,17 +401,21 @@ onBeforeUnmount(() => {
|
||||
})
|
||||
|
||||
const displayRows = computed(() => {
|
||||
// Verwende Server-Wert für "Derzeit gearbeitet" wenn verfügbar (zeigt gesamte Tagesarbeitszeit)
|
||||
const workedDisplay = (stats.value?.currentlyWorked && stats.value.currentlyWorked !== '—')
|
||||
? stats.value.currentlyWorked + ' h'
|
||||
: (currentlyWorkedTime.value === '—' ? currentlyWorkedTime.value : currentlyWorkedTime.value + ' h');
|
||||
|
||||
const rows = {
|
||||
'Derzeit gearbeitet': currentlyWorkedTime.value, // Verwende berechneten Wert
|
||||
'Offen': openTime.value, // Verwende berechneten Wert
|
||||
'Normales Arbeitsende': regularEndTime.value // Verwende berechneten Wert
|
||||
'Derzeit gearbeitet': workedDisplay,
|
||||
'Offen': openTime.value === '—' || openTime.value.includes('erreicht') ? openTime.value : openTime.value + ' h',
|
||||
'Normales Arbeitsende': regularEndTime.value // Verwende berechneten Wert (hat bereits "Uhr")
|
||||
}
|
||||
|
||||
// Füge andere Stats hinzu
|
||||
const map = [
|
||||
['overtime', 'overtime'], // Label wird dynamisch gesetzt
|
||||
['totalOvertime', 'totalOvertime'], // Label wird dynamisch gesetzt
|
||||
// ['Überstunden (Alt-Style)', 'totalOvertimeOldStyle'], // DEBUG: Versteckt, da getWeekOverview nicht korrekte Zeiten liefert
|
||||
['Wochenarbeitszeit', 'weekWorktime'],
|
||||
['Arbeitsfreie Stunden', 'nonWorkingHours'],
|
||||
['Offen für Woche', 'openForWeek'],
|
||||
@@ -416,16 +438,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';
|
||||
// Füge " Uhr" zu Uhrzeiten hinzu (außer bei "Arbeitsende erreicht")
|
||||
rows[label] = val.includes('erreicht') ? val : 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;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,9 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useAuthStore } from '../stores/authStore'
|
||||
import { API_BASE_URL } from '@/config/api'
|
||||
|
||||
const API_URL = API_BASE_URL
|
||||
const authStore = useAuthStore()
|
||||
const now = new Date()
|
||||
const selectedMonth = ref(now.getMonth() + 1)
|
||||
|
||||
@@ -89,7 +89,9 @@ import { ref } from 'vue'
|
||||
import { useAuthStore } from '../stores/authStore'
|
||||
import { useModal } from '../composables/useModal'
|
||||
import Modal from '../components/Modal.vue'
|
||||
import { API_BASE_URL } from '@/config/api'
|
||||
|
||||
const API_URL = API_BASE_URL
|
||||
const authStore = useAuthStore()
|
||||
const loading = ref(false)
|
||||
|
||||
|
||||
@@ -48,7 +48,9 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useAuthStore } from '../stores/authStore'
|
||||
import { API_BASE_URL } from '@/config/api'
|
||||
|
||||
const API_URL = API_BASE_URL
|
||||
const authStore = useAuthStore()
|
||||
const selectedYear = ref(new Date().getFullYear())
|
||||
const statistics = ref(null)
|
||||
|
||||
Reference in New Issue
Block a user