Anpassung in der Verwaltung mit der Berechnung
This commit is contained in:
@@ -243,12 +243,19 @@ function registerVerwaltungRoutes(app) {
|
||||
|
||||
// Nur Wochen bis Ende der angezeigten Kalenderwoche (Stand Urlaub = Ende dieser KW)
|
||||
const weeksUpToDisplayed = (weeks || []).filter((w) => w.week_end <= week_end);
|
||||
// Wochen VOR der aktuellen Woche für kumulative Überstunden-Berechnung
|
||||
const weeksBeforeCurrent = (weeks || []).filter((w) => w.week_end < week_end);
|
||||
let processedWeeks = 0;
|
||||
let totalVacationDays = 0;
|
||||
const vacationByDate = {};
|
||||
|
||||
// Kumulative Überstunden über alle Wochen VOR der aktuellen Woche
|
||||
let cumulativeOvertimeHours = 0;
|
||||
let cumulativeOvertimeTaken = 0;
|
||||
|
||||
// Urlaubstage für alle Wochen bis zur aktuellen Woche (inklusive)
|
||||
if (weeksUpToDisplayed.length === 0) {
|
||||
processCurrentWeek(0);
|
||||
processCurrentWeek(0, 0, 0);
|
||||
} else {
|
||||
weeksUpToDisplayed.forEach((week) => {
|
||||
db.all(`SELECT date, vacation_type, updated_at, id
|
||||
@@ -285,13 +292,111 @@ function registerVerwaltungRoutes(app) {
|
||||
totalVacationDays += 0.5;
|
||||
}
|
||||
});
|
||||
processCurrentWeek(totalVacationDays);
|
||||
|
||||
// Berechne Überstunden für alle Wochen VOR der aktuellen Woche
|
||||
if (weeksBeforeCurrent.length === 0) {
|
||||
processCurrentWeek(totalVacationDays, 0, 0);
|
||||
} else {
|
||||
let processedOvertimeWeeks = 0;
|
||||
weeksBeforeCurrent.forEach((week) => {
|
||||
calculateWeekOvertime(week.week_start, week.week_end, (weekOvertime, weekOvertimeTaken) => {
|
||||
cumulativeOvertimeHours += weekOvertime;
|
||||
cumulativeOvertimeTaken += weekOvertimeTaken;
|
||||
|
||||
processedOvertimeWeeks++;
|
||||
if (processedOvertimeWeeks === weeksBeforeCurrent.length) {
|
||||
processCurrentWeek(totalVacationDays, cumulativeOvertimeHours, cumulativeOvertimeTaken);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function processCurrentWeek(totalVacationDays) {
|
||||
function calculateWeekOvertime(weekStart, weekEnd, callback) {
|
||||
db.all(`SELECT id, date, updated_at, total_hours, overtime_taken_hours, vacation_type, sick_status
|
||||
FROM timesheet_entries
|
||||
WHERE user_id = ? AND date >= ? AND date <= ?
|
||||
ORDER BY date, updated_at DESC, id DESC`,
|
||||
[userId, weekStart, weekEnd],
|
||||
(err, allEntries) => {
|
||||
if (err) {
|
||||
return callback(0, 0);
|
||||
}
|
||||
|
||||
// Nur neuesten Eintrag pro Tag zählen
|
||||
const entriesByDate = {};
|
||||
(allEntries || []).forEach(entry => {
|
||||
const existing = entriesByDate[entry.date];
|
||||
if (!existing) {
|
||||
entriesByDate[entry.date] = entry;
|
||||
} else {
|
||||
const existingTime = existing.updated_at ? new Date(existing.updated_at).getTime() : 0;
|
||||
const currentTime = entry.updated_at ? new Date(entry.updated_at).getTime() : 0;
|
||||
if (currentTime > existingTime || (currentTime === existingTime && entry.id > existing.id)) {
|
||||
entriesByDate[entry.date] = entry;
|
||||
}
|
||||
}
|
||||
});
|
||||
const entries = Object.values(entriesByDate);
|
||||
|
||||
let weekTotalHours = 0;
|
||||
let weekOvertimeTaken = 0;
|
||||
let weekVacationHours = 0;
|
||||
|
||||
entries.forEach(entry => {
|
||||
if (entry.overtime_taken_hours) {
|
||||
weekOvertimeTaken += parseFloat(entry.overtime_taken_hours) || 0;
|
||||
}
|
||||
|
||||
if (entry.vacation_type === 'full') {
|
||||
weekVacationHours += fullDayHours;
|
||||
} else if (entry.vacation_type === 'half') {
|
||||
weekVacationHours += fullDayHours / 2;
|
||||
if (entry.total_hours) {
|
||||
weekTotalHours += parseFloat(entry.total_hours) || 0;
|
||||
}
|
||||
} else {
|
||||
if (entry.total_hours) {
|
||||
weekTotalHours += parseFloat(entry.total_hours) || 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
getHolidaysForDateRange(weekStart, weekEnd)
|
||||
.catch(() => new Set())
|
||||
.then((holidaySet) => {
|
||||
const startDate = new Date(weekStart);
|
||||
const endDate = new Date(weekEnd);
|
||||
let workdays = 0;
|
||||
let holidayDays = 0;
|
||||
let holidayHours = 0;
|
||||
for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
|
||||
const day = d.getDay();
|
||||
if (day >= 1 && day <= 5) {
|
||||
workdays++;
|
||||
const dateStr = d.toISOString().split('T')[0];
|
||||
if (holidaySet.has(dateStr)) {
|
||||
holidayDays++;
|
||||
// Feiertagsstunden für alle Feiertage hinzufügen (wie im PDF)
|
||||
holidayHours += fullDayHours;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sollstunden = Wochenstunden (Feiertage reduzieren Soll nicht, da bezahlt)
|
||||
const sollStunden = wochenstunden;
|
||||
const totalHoursWithVacation = weekTotalHours + weekVacationHours + holidayHours;
|
||||
const weekOvertimeHours = totalHoursWithVacation - sollStunden;
|
||||
|
||||
callback(weekOvertimeHours, weekOvertimeTaken);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function processCurrentWeek(totalVacationDays, cumulativeOvertimeHours, cumulativeOvertimeTaken) {
|
||||
// Einträge für die Woche abrufen (id/updated_at für neuesten pro Tag)
|
||||
db.all(`SELECT id, date, updated_at, total_hours, overtime_taken_hours, vacation_type, sick_status
|
||||
FROM timesheet_entries
|
||||
@@ -366,23 +471,35 @@ function registerVerwaltungRoutes(app) {
|
||||
const startDate = new Date(week_start);
|
||||
const endDate = new Date(week_end);
|
||||
let workdays = 0;
|
||||
let holidayDays = 0;
|
||||
let holidayHours = 0;
|
||||
for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
|
||||
const day = d.getDay();
|
||||
if (day >= 1 && day <= 5) { // Montag bis Freitag
|
||||
workdays++;
|
||||
const dateStr = d.toISOString().split('T')[0];
|
||||
if (holidaySet.has(dateStr)) holidayHours += fullDayHours;
|
||||
if (holidaySet.has(dateStr)) {
|
||||
holidayDays++;
|
||||
// Feiertagsstunden für alle Feiertage hinzufügen (wie im PDF)
|
||||
holidayHours += fullDayHours;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sollstunden berechnen
|
||||
const sollStunden = (wochenstunden / arbeitstage) * workdays;
|
||||
// Sollstunden = Wochenstunden (Feiertage reduzieren Soll nicht, da bezahlt)
|
||||
const sollStunden = wochenstunden;
|
||||
|
||||
// Überstunden: (Tatsächliche Stunden + Urlaubsstunden + Feiertagsstunden) - Sollstunden
|
||||
// Überstunden für die aktuelle Woche: (Tatsächliche Stunden + Urlaubsstunden + Feiertagsstunden) - Sollstunden
|
||||
const totalHoursWithVacation = totalHours + vacationHours + holidayHours;
|
||||
const overtimeHours = totalHoursWithVacation - sollStunden;
|
||||
const remainingOvertime = overtimeHours - overtimeTaken;
|
||||
const weekOvertimeHours = totalHoursWithVacation - sollStunden;
|
||||
|
||||
// Kumulative Überstunden: Summe aller Wochen bis zur aktuellen Woche
|
||||
// cumulativeOvertimeHours enthält bereits alle vorherigen Wochen
|
||||
const totalCumulativeOvertimeHours = cumulativeOvertimeHours + weekOvertimeHours;
|
||||
const totalCumulativeOvertimeTaken = cumulativeOvertimeTaken + overtimeTaken;
|
||||
|
||||
// Verbleibende Überstunden = kumulative Überstunden - kumulative genommene Überstunden
|
||||
const remainingOvertime = totalCumulativeOvertimeHours - totalCumulativeOvertimeTaken;
|
||||
const remainingOvertimeWithOffset = remainingOvertime + overtimeOffsetHours;
|
||||
|
||||
// Verbleibende Urlaubstage (berücksichtigt alle eingereichten Wochen, nicht nur die aktuelle)
|
||||
@@ -393,8 +510,9 @@ function registerVerwaltungRoutes(app) {
|
||||
urlaubstage,
|
||||
totalHours,
|
||||
sollStunden,
|
||||
overtimeHours,
|
||||
overtimeTaken,
|
||||
weekOvertimeHours, // Überstunden nur für diese Woche
|
||||
overtimeHours: totalCumulativeOvertimeHours, // Kumulative Überstunden
|
||||
overtimeTaken: totalCumulativeOvertimeTaken, // Kumulative genommene Überstunden
|
||||
remainingOvertime,
|
||||
overtimeOffsetHours,
|
||||
remainingOvertimeWithOffset,
|
||||
|
||||
Reference in New Issue
Block a user