To-DO abgearbeitet
This commit is contained in:
@@ -262,7 +262,7 @@ function registerTimesheetRoutes(app) {
|
||||
// Füge Status-Info hinzu (Bearbeitung ist immer möglich)
|
||||
const entriesWithStatus = (entries || []).map(entry => ({
|
||||
...entry,
|
||||
week_submitted: false, // Immer false, damit Bearbeitung möglich ist
|
||||
week_submitted: hasSubmittedVersion, // Woche wurde eingereicht wenn weekly_timesheet existiert
|
||||
latest_version: latestVersion,
|
||||
has_existing_version: latestVersion > 0
|
||||
}));
|
||||
@@ -304,7 +304,7 @@ function registerTimesheetRoutes(app) {
|
||||
}
|
||||
});
|
||||
|
||||
// Prüfe nur Werktage (Montag-Freitag, erste 5 Tage)
|
||||
// Prüfe nur so viele Tage wie Arbeitstage pro Woche festgelegt sind
|
||||
// Samstag und Sonntag sind optional
|
||||
// Bei ganztägigem Urlaub (vacation_type = 'full') ist der Tag als ausgefüllt zu betrachten
|
||||
// Bei 8 Überstunden (ganzer Tag) ist der Tag auch als ausgefüllt zu betrachten
|
||||
@@ -330,7 +330,7 @@ function registerTimesheetRoutes(app) {
|
||||
.then((holidaySet) => {
|
||||
let missingDays = [];
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
for (let i = 0; i < arbeitstage; i++) {
|
||||
// Datum direkt berechnen ohne Zeitzonenprobleme
|
||||
const date = new Date(startYear, startMonth, startDay + i);
|
||||
const year = date.getFullYear();
|
||||
@@ -380,8 +380,9 @@ function registerTimesheetRoutes(app) {
|
||||
}
|
||||
|
||||
if (missingDays.length > 0) {
|
||||
const requiredDaysText = arbeitstage === 1 ? '1 Tag' : `${arbeitstage} Tage`;
|
||||
return res.status(400).json({
|
||||
error: `Nicht alle Werktage (Montag bis Freitag) sind ausgefüllt. Fehlende Tage: ${missingDays.join(', ')}. Bitte füllen Sie alle Werktage mit Start- und Endzeit aus. Wochenende ist optional.`
|
||||
error: `Nicht alle ${requiredDaysText} sind ausgefüllt. Fehlende Tage: ${missingDays.join(', ')}. Bitte füllen Sie alle ${requiredDaysText} mit Start- und Endzeit aus. Wochenende ist optional.`
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -154,48 +154,73 @@ function registerUserRoutes(app) {
|
||||
res.json({ success: true, currentRole: role });
|
||||
});
|
||||
|
||||
// API: Verplante Urlaubstage (alle Wochen, auch nicht-eingereichte)
|
||||
// API: Verplante Urlaubstage (nur nicht-eingereichte Wochen)
|
||||
app.get('/api/user/planned-vacation', requireAuth, (req, res) => {
|
||||
const userId = req.session.userId;
|
||||
const { getCalendarWeek } = require('../helpers/utils');
|
||||
const { getCalendarWeek, getWeekStart } = require('../helpers/utils');
|
||||
|
||||
db.all(`SELECT date, vacation_type FROM timesheet_entries
|
||||
WHERE user_id = ? AND vacation_type IS NOT NULL AND vacation_type != ''`,
|
||||
// Zuerst alle eingereichten Wochen abrufen
|
||||
db.all(`SELECT DISTINCT week_start FROM weekly_timesheets
|
||||
WHERE user_id = ? AND status = 'eingereicht'`,
|
||||
[userId],
|
||||
(err, entries) => {
|
||||
(err, submittedWeeks) => {
|
||||
if (err) {
|
||||
return res.status(500).json({ error: 'Fehler beim Abrufen der verplanten Tage' });
|
||||
return res.status(500).json({ error: 'Fehler beim Abrufen der eingereichten Wochen' });
|
||||
}
|
||||
|
||||
let plannedDays = 0;
|
||||
const weeksMap = {}; // { KW: { year: YYYY, week: KW, days: X } }
|
||||
// Set für schnelle Suche nach eingereichten Wochen
|
||||
const submittedWeekStarts = new Set(
|
||||
(submittedWeeks || []).map(w => w.week_start)
|
||||
);
|
||||
|
||||
entries.forEach(entry => {
|
||||
const dayValue = entry.vacation_type === 'full' ? 1 : 0.5;
|
||||
plannedDays += dayValue;
|
||||
// Alle Urlaubseinträge abrufen
|
||||
db.all(`SELECT date, vacation_type FROM timesheet_entries
|
||||
WHERE user_id = ? AND vacation_type IS NOT NULL AND vacation_type != ''`,
|
||||
[userId],
|
||||
(err, entries) => {
|
||||
if (err) {
|
||||
return res.status(500).json({ error: 'Fehler beim Abrufen der verplanten Tage' });
|
||||
}
|
||||
|
||||
// Berechne Kalenderwoche
|
||||
const date = new Date(entry.date);
|
||||
const year = date.getFullYear();
|
||||
const week = getCalendarWeek(entry.date);
|
||||
const weekKey = `${year}-KW${week}`;
|
||||
let plannedDays = 0;
|
||||
const weeksMap = {}; // { KW: { year: YYYY, week: KW, days: X } }
|
||||
|
||||
if (!weeksMap[weekKey]) {
|
||||
weeksMap[weekKey] = { year, week, days: 0 };
|
||||
entries.forEach(entry => {
|
||||
// Berechne week_start für diesen Eintrag
|
||||
const weekStart = getWeekStart(entry.date);
|
||||
|
||||
// Überspringe Einträge aus eingereichten Wochen
|
||||
if (submittedWeekStarts.has(weekStart)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dayValue = entry.vacation_type === 'full' ? 1 : 0.5;
|
||||
plannedDays += dayValue;
|
||||
|
||||
// Berechne Kalenderwoche
|
||||
const date = new Date(entry.date);
|
||||
const year = date.getFullYear();
|
||||
const week = getCalendarWeek(entry.date);
|
||||
const weekKey = `${year}-KW${week}`;
|
||||
|
||||
if (!weeksMap[weekKey]) {
|
||||
weeksMap[weekKey] = { year, week, days: 0 };
|
||||
}
|
||||
weeksMap[weekKey].days += dayValue;
|
||||
});
|
||||
|
||||
// Konvertiere zu sortiertem Array
|
||||
const weeks = Object.values(weeksMap).sort((a, b) => {
|
||||
if (a.year !== b.year) return a.year - b.year;
|
||||
return a.week - b.week;
|
||||
});
|
||||
|
||||
res.json({
|
||||
plannedVacationDays: plannedDays,
|
||||
weeks: weeks
|
||||
});
|
||||
}
|
||||
weeksMap[weekKey].days += dayValue;
|
||||
});
|
||||
|
||||
// Konvertiere zu sortiertem Array
|
||||
const weeks = Object.values(weeksMap).sort((a, b) => {
|
||||
if (a.year !== b.year) return a.year - b.year;
|
||||
return a.week - b.week;
|
||||
});
|
||||
|
||||
res.json({
|
||||
plannedVacationDays: plannedDays,
|
||||
weeks: weeks
|
||||
});
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -237,52 +262,68 @@ function registerUserRoutes(app) {
|
||||
const overtimeOffsetHours = user.overtime_offset_hours ? parseFloat(user.overtime_offset_hours) : 0;
|
||||
const vacationOffsetDays = user.vacation_offset_days ? parseFloat(user.vacation_offset_days) : 0;
|
||||
|
||||
// Verplante Urlaubstage berechnen (alle Wochen, auch nicht-eingereichte)
|
||||
const { getCalendarWeek } = require('../helpers/utils');
|
||||
db.all(`SELECT date, vacation_type FROM timesheet_entries
|
||||
WHERE user_id = ? AND vacation_type IS NOT NULL AND vacation_type != ''`,
|
||||
// Verplante Urlaubstage berechnen (nur nicht-eingereichte Wochen)
|
||||
const { getCalendarWeek, getWeekStart } = require('../helpers/utils');
|
||||
|
||||
// Zuerst alle eingereichten Wochen abrufen
|
||||
db.all(`SELECT DISTINCT week_start, week_end
|
||||
FROM weekly_timesheets
|
||||
WHERE user_id = ? AND status = 'eingereicht'
|
||||
ORDER BY week_start`,
|
||||
[userId],
|
||||
(err, allVacationEntries) => {
|
||||
(err, weeks) => {
|
||||
if (err) {
|
||||
return res.status(500).json({ error: 'Fehler beim Abrufen der verplanten Tage' });
|
||||
return res.status(500).json({ error: 'Fehler beim Abrufen der Wochen' });
|
||||
}
|
||||
|
||||
let plannedVacationDays = 0;
|
||||
const weeksMap = {}; // { KW: { year: YYYY, week: KW, days: X } }
|
||||
// Set für schnelle Suche nach eingereichten Wochen
|
||||
const submittedWeekStarts = new Set(
|
||||
(weeks || []).map(w => w.week_start)
|
||||
);
|
||||
|
||||
(allVacationEntries || []).forEach(entry => {
|
||||
const dayValue = entry.vacation_type === 'full' ? 1 : 0.5;
|
||||
plannedVacationDays += dayValue;
|
||||
|
||||
// Berechne Kalenderwoche
|
||||
const date = new Date(entry.date);
|
||||
const year = date.getFullYear();
|
||||
const week = getCalendarWeek(entry.date);
|
||||
const weekKey = `${year}-KW${week}`;
|
||||
|
||||
if (!weeksMap[weekKey]) {
|
||||
weeksMap[weekKey] = { year, week, days: 0 };
|
||||
}
|
||||
weeksMap[weekKey].days += dayValue;
|
||||
});
|
||||
|
||||
// Konvertiere zu sortiertem Array
|
||||
const plannedWeeks = Object.values(weeksMap).sort((a, b) => {
|
||||
if (a.year !== b.year) return a.year - b.year;
|
||||
return a.week - b.week;
|
||||
});
|
||||
|
||||
// Alle eingereichten Wochen abrufen
|
||||
db.all(`SELECT DISTINCT week_start, week_end
|
||||
FROM weekly_timesheets
|
||||
WHERE user_id = ? AND status = 'eingereicht'
|
||||
ORDER BY week_start`,
|
||||
// Alle Urlaubseinträge abrufen
|
||||
db.all(`SELECT date, vacation_type FROM timesheet_entries
|
||||
WHERE user_id = ? AND vacation_type IS NOT NULL AND vacation_type != ''`,
|
||||
[userId],
|
||||
(err, weeks) => {
|
||||
(err, allVacationEntries) => {
|
||||
if (err) {
|
||||
return res.status(500).json({ error: 'Fehler beim Abrufen der Wochen' });
|
||||
return res.status(500).json({ error: 'Fehler beim Abrufen der verplanten Tage' });
|
||||
}
|
||||
|
||||
let plannedVacationDays = 0;
|
||||
const weeksMap = {}; // { KW: { year: YYYY, week: KW, days: X } }
|
||||
|
||||
(allVacationEntries || []).forEach(entry => {
|
||||
// Berechne week_start für diesen Eintrag
|
||||
const weekStart = getWeekStart(entry.date);
|
||||
|
||||
// Überspringe Einträge aus eingereichten Wochen
|
||||
if (submittedWeekStarts.has(weekStart)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dayValue = entry.vacation_type === 'full' ? 1 : 0.5;
|
||||
plannedVacationDays += dayValue;
|
||||
|
||||
// Berechne Kalenderwoche
|
||||
const date = new Date(entry.date);
|
||||
const year = date.getFullYear();
|
||||
const week = getCalendarWeek(entry.date);
|
||||
const weekKey = `${year}-KW${week}`;
|
||||
|
||||
if (!weeksMap[weekKey]) {
|
||||
weeksMap[weekKey] = { year, week, days: 0 };
|
||||
}
|
||||
weeksMap[weekKey].days += dayValue;
|
||||
});
|
||||
|
||||
// Konvertiere zu sortiertem Array
|
||||
const plannedWeeks = Object.values(weeksMap).sort((a, b) => {
|
||||
if (a.year !== b.year) return a.year - b.year;
|
||||
return a.week - b.week;
|
||||
});
|
||||
|
||||
// Weiter mit der Verarbeitung der eingereichten Wochen (weeks ist bereits verfügbar)
|
||||
// Wenn keine Wochen vorhanden
|
||||
if (!weeks || weeks.length === 0) {
|
||||
return res.json({
|
||||
|
||||
Reference in New Issue
Block a user