This commit is contained in:
2026-03-10 14:39:11 +01:00
parent bf578a8d87
commit d4a544164b
7 changed files with 217 additions and 51 deletions

View File

@@ -20,6 +20,11 @@ function registerTimesheetRoutes(app) {
overtime_taken_hours, vacation_type, sick_status, weekend_travel
} = req.body;
const userId = req.session.userId;
const hasExplicitBreakMinutes = break_minutes !== undefined && break_minutes !== null && break_minutes !== '';
const parsedRequestedBreakMinutes = hasExplicitBreakMinutes ? parseInt(break_minutes, 10) : null;
const requestedBreakMinutes = Number.isFinite(parsedRequestedBreakMinutes) && parsedRequestedBreakMinutes >= 0
? parsedRequestedBreakMinutes
: null;
// Normalisiere end_time: Leere Strings werden zu null
const normalizedEndTime = (end_time && typeof end_time === 'string' && end_time.trim() !== '') ? end_time.trim() : (end_time || null);
@@ -55,7 +60,7 @@ function registerTimesheetRoutes(app) {
}
// User-Daten laden (für Überstunden-Berechnung)
db.get('SELECT wochenstunden, arbeitstage FROM users WHERE id = ?', [userId], (err, user) => {
db.get('SELECT wochenstunden, arbeitstage, default_break_minutes FROM users WHERE id = ?', [userId], (err, user) => {
if (err) {
console.error('Fehler beim Laden der User-Daten:', err);
return res.status(500).json({ error: 'Fehler beim Laden der User-Daten' });
@@ -63,6 +68,10 @@ function registerTimesheetRoutes(app) {
const wochenstunden = user?.wochenstunden || 0;
const arbeitstage = user?.arbeitstage || 5;
const defaultBreakMinutes = Number.isInteger(user?.default_break_minutes) && user.default_break_minutes >= 0
? user.default_break_minutes
: 30;
let effectiveBreakMinutes = requestedBreakMinutes !== null ? requestedBreakMinutes : defaultBreakMinutes;
const overtimeValue = overtime_taken_hours ? parseFloat(overtime_taken_hours) : 0;
const fullDayHours = wochenstunden > 0 && arbeitstage > 0 ? wochenstunden / arbeitstage : 0;
@@ -106,7 +115,7 @@ function registerTimesheetRoutes(app) {
const start = new Date(`2000-01-01T${normalizedStartTime}`);
const end = new Date(`2000-01-01T${normalizedEndTime}`);
const diffMs = end - start;
total_hours = (diffMs / (1000 * 60 * 60)) - (break_minutes / 60);
total_hours = (diffMs / (1000 * 60 * 60)) - (effectiveBreakMinutes / 60);
// Wochenend-Prozentsatz anwenden (nur wenn weekend_travel aktiviert UND es ist ein Wochenendtag)
if (isWeekend && isWeekendTravel && total_hours > 0 && !isSick && vacation_type !== 'full') {
@@ -124,9 +133,26 @@ function registerTimesheetRoutes(app) {
// Sie werden über overtime_taken_hours in der PDF angezeigt
// Prüfen ob Eintrag existiert - verwende den neuesten Eintrag falls mehrere existieren
db.get('SELECT id, applied_weekend_percentage FROM timesheet_entries WHERE user_id = ? AND date = ? ORDER BY updated_at DESC, id DESC LIMIT 1',
db.get('SELECT id, break_minutes, applied_weekend_percentage FROM timesheet_entries WHERE user_id = ? AND date = ? ORDER BY updated_at DESC, id DESC LIMIT 1',
[userId, date], (err, row) => {
if (row) {
if (requestedBreakMinutes === null && row.break_minutes !== null && row.break_minutes !== undefined) {
effectiveBreakMinutes = row.break_minutes;
}
if (normalizedStartTime && normalizedEndTime && !isSick && vacation_type !== 'full' && !isFullDayOvertime) {
const start = new Date(`2000-01-01T${normalizedStartTime}`);
const end = new Date(`2000-01-01T${normalizedEndTime}`);
const diffMs = end - start;
total_hours = (diffMs / (1000 * 60 * 60)) - (effectiveBreakMinutes / 60);
if (isWeekend && isWeekendTravel && total_hours > 0) {
const weekendPercentage = getWeekendPercentage(date);
if (weekendPercentage >= 100) {
total_hours = total_hours * (weekendPercentage / 100);
}
}
}
// Wenn bereits ein gespeicherter Prozentsatz existiert, diesen verwenden (historische Einträge bleiben unverändert)
let finalAppliedPercentage = appliedWeekendPercentage;
if (row.applied_weekend_percentage !== null && row.applied_weekend_percentage !== undefined) {
@@ -138,7 +164,7 @@ function registerTimesheetRoutes(app) {
const start = new Date(`2000-01-01T${normalizedStartTime}`);
const end = new Date(`2000-01-01T${normalizedEndTime}`);
const diffMs = end - start;
const baseHours = (diffMs / (1000 * 60 * 60)) - (break_minutes / 60);
const baseHours = (diffMs / (1000 * 60 * 60)) - (effectiveBreakMinutes / 60);
if (baseHours > 0 && finalAppliedPercentage >= 100) {
total_hours = baseHours * (finalAppliedPercentage / 100);
}
@@ -165,7 +191,7 @@ function registerTimesheetRoutes(app) {
updated_at = CURRENT_TIMESTAMP
WHERE id = ?`,
[
finalStartTime, finalEndTime, break_minutes, total_hours, notes,
finalStartTime, finalEndTime, effectiveBreakMinutes, total_hours, notes,
finalActivity1Desc || null, finalActivity1Hours, activity1_project_number || null,
finalActivity2Desc || null, parseFloat(activity2_hours) || 0, activity2_project_number || null,
finalActivity3Desc || null, parseFloat(activity3_hours) || 0, activity3_project_number || null,
@@ -197,7 +223,7 @@ function registerTimesheetRoutes(app) {
overtime_taken_hours, vacation_type, sick_status, weekend_travel, applied_weekend_percentage)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
[
userId, date, finalStartTime, finalEndTime, break_minutes, total_hours, notes,
userId, date, finalStartTime, finalEndTime, effectiveBreakMinutes, total_hours, notes,
finalActivity1Desc || null, finalActivity1Hours, activity1_project_number || null,
finalActivity2Desc || null, parseFloat(activity2_hours) || 0, activity2_project_number || null,
finalActivity3Desc || null, parseFloat(activity3_hours) || 0, activity3_project_number || null,