To-DO abgearbeitet
This commit is contained in:
@@ -10,8 +10,8 @@
|
|||||||
- Wenn bereits heruntergeladen wurde und neue version da ist Meldung an Verwaltung. -> DONE Muss getestet werden
|
- Wenn bereits heruntergeladen wurde und neue version da ist Meldung an Verwaltung. -> DONE Muss getestet werden
|
||||||
- Wenn ganzer Tag Urlaub gesetzt wird steht erst 8h (Urlaub) und dann nur noch 8h
|
- Wenn ganzer Tag Urlaub gesetzt wird steht erst 8h (Urlaub) und dann nur noch 8h
|
||||||
|
|
||||||
- Feiertage im PDF anzeigen -> DONE Testen noch nicht depoyed
|
- Feiertage im PDF anzeigen -> DONE Testen noch nicht depoyed
|
||||||
- Oben wenn woche eingereicht anzeigen als hilfestellung
|
- Oben wenn woche eingereicht anzeigen als hilfestellung -> DONE
|
||||||
- Ausgefüllte Tage anhand der Tage pro woche gültig setzten
|
- Ausgefüllte Tage anhand der Tage pro woche gültig setzten -> DONE Testen
|
||||||
- Überstunden müssen anhand der Tagesstunden auch auf gültig setzten (Tag ausgefüllt wenn weniger als 8h)
|
- Überstunden müssen anhand der Tagesstunden auch auf gültig setzten (Tag ausgefüllt wenn weniger als 8h) -> DONE sollte passen
|
||||||
- Verplante Urlaubstage müssen auf abgezogen werden, wenn die Woche die gepalnt war eingereicht wurde.
|
- Verplante Urlaubstage müssen auf abgezogen werden, wenn die Woche die gepalnt war eingereicht wurde. -> DONE Testen
|
||||||
@@ -117,6 +117,21 @@ function getWeekDatesFromCalendarWeek(year, weekNumber) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper: Berechnet week_start (Montag) aus einem Datum
|
||||||
|
function getWeekStart(dateStr) {
|
||||||
|
const date = new Date(dateStr);
|
||||||
|
const day = date.getDay(); // 0 = Sonntag, 1 = Montag, ..., 6 = Samstag
|
||||||
|
const diff = day === 0 ? -6 : 1 - day; // Montag = 1, Sonntag = 0
|
||||||
|
const monday = new Date(date);
|
||||||
|
monday.setDate(date.getDate() + diff);
|
||||||
|
|
||||||
|
// Format: YYYY-MM-DD
|
||||||
|
const year = monday.getFullYear();
|
||||||
|
const month = String(monday.getMonth() + 1).padStart(2, '0');
|
||||||
|
const dayOfMonth = String(monday.getDate()).padStart(2, '0');
|
||||||
|
return `${year}-${month}-${dayOfMonth}`;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
hasRole,
|
hasRole,
|
||||||
getDefaultRole,
|
getDefaultRole,
|
||||||
@@ -127,5 +142,6 @@ module.exports = {
|
|||||||
formatDate,
|
formatDate,
|
||||||
formatDateTime,
|
formatDateTime,
|
||||||
getCalendarWeek,
|
getCalendarWeek,
|
||||||
getWeekDatesFromCalendarWeek
|
getWeekDatesFromCalendarWeek,
|
||||||
|
getWeekStart
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -374,8 +374,11 @@ function renderWeek() {
|
|||||||
endDate.setDate(endDate.getDate() + 6);
|
endDate.setDate(endDate.getDate() + 6);
|
||||||
|
|
||||||
const calendarWeek = getCalendarWeek(currentWeekStart);
|
const calendarWeek = getCalendarWeek(currentWeekStart);
|
||||||
|
const submittedText = currentEntries._weekSubmitted === true
|
||||||
|
? `<br><span style="color: #28a745;">(bereits Abgegeben)</span>`
|
||||||
|
: '';
|
||||||
document.getElementById('weekTitle').innerHTML =
|
document.getElementById('weekTitle').innerHTML =
|
||||||
`Kalenderwoche ${calendarWeek}<br>${formatDateDE(currentWeekStart)} - ${formatDateDE(formatDate(endDate))}`;
|
`Kalenderwoche ${calendarWeek}<br>${formatDateDE(currentWeekStart)} - ${formatDateDE(formatDate(endDate))}${submittedText}`;
|
||||||
|
|
||||||
let html = `
|
let html = `
|
||||||
<div class="timesheet-grid">
|
<div class="timesheet-grid">
|
||||||
@@ -1410,9 +1413,10 @@ function checkWeekComplete() {
|
|||||||
let allWeekdaysFilled = true;
|
let allWeekdaysFilled = true;
|
||||||
const missingFields = [];
|
const missingFields = [];
|
||||||
|
|
||||||
// Prüfe nur Werktage (Montag-Freitag, i < 5)
|
// Prüfe nur so viele Tage wie Arbeitstage pro Woche festgelegt sind
|
||||||
// Samstag und Sonntag (i >= 5) sind optional
|
// Samstag und Sonntag sind optional
|
||||||
for (let i = 0; i < 5; i++) {
|
const requiredDays = userArbeitstage || 5; // Fallback auf 5 wenn nicht gesetzt
|
||||||
|
for (let i = 0; i < requiredDays; i++) {
|
||||||
const date = new Date(startDate);
|
const date = new Date(startDate);
|
||||||
date.setDate(date.getDate() + i);
|
date.setDate(date.getDate() + i);
|
||||||
const dateStr = formatDate(date);
|
const dateStr = formatDate(date);
|
||||||
@@ -1482,16 +1486,19 @@ function checkWeekComplete() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prüfe ob die Woche bereits eingereicht wurde (nicht der Status einzelner Einträge!)
|
// Prüfe ob die Woche bereits eingereicht wurde (für Anzeige, aber Button bleibt aktiv für neue Versionen)
|
||||||
const weekIsSubmitted = currentEntries._weekSubmitted === true;
|
const weekIsSubmitted = currentEntries._weekSubmitted === true;
|
||||||
const submitButton = document.getElementById('submitWeek');
|
const submitButton = document.getElementById('submitWeek');
|
||||||
if (submitButton) {
|
if (submitButton) {
|
||||||
submitButton.disabled = weekIsSubmitted || !allWeekdaysFilled;
|
// Button nur deaktivieren wenn nicht alle Felder ausgefüllt sind
|
||||||
|
// Resubmission ist erlaubt, da Versionierung unterstützt wird
|
||||||
|
submitButton.disabled = !allWeekdaysFilled;
|
||||||
|
|
||||||
if (weekIsSubmitted) {
|
if (!allWeekdaysFilled) {
|
||||||
submitButton.title = 'Diese Woche wurde bereits eingereicht und kann nicht mehr geändert werden.';
|
const requiredDaysText = requiredDays === 1 ? '1 Tag' : `${requiredDays} Tage`;
|
||||||
} else if (!allWeekdaysFilled) {
|
submitButton.title = `Bitte füllen Sie alle ${requiredDaysText} (Start- und Endzeit) aus. Wochenende ist optional. Fehlend: ${missingFields.join(', ')}`;
|
||||||
submitButton.title = `Bitte füllen Sie alle Werktage (Montag bis Freitag) aus (Start- und Endzeit). Wochenende ist optional. Fehlend: ${missingFields.join(', ')}`;
|
} else if (weekIsSubmitted) {
|
||||||
|
submitButton.title = 'Diese Woche wurde bereits eingereicht. Beim erneuten Abschicken wird eine neue Version erstellt.';
|
||||||
} else {
|
} else {
|
||||||
submitButton.title = '';
|
submitButton.title = '';
|
||||||
}
|
}
|
||||||
@@ -1545,7 +1552,7 @@ async function submitWeek() {
|
|||||||
|
|
||||||
console.log('Prüfe Validierung für Woche:', currentWeekStart);
|
console.log('Prüfe Validierung für Woche:', currentWeekStart);
|
||||||
|
|
||||||
// Frontend-Validierung: Prüfen ob alle Werktage (Montag-Freitag) ausgefüllt sind
|
// Frontend-Validierung: Prüfen ob so viele Tage ausgefüllt sind wie Arbeitstage pro Woche festgelegt sind
|
||||||
let missingFields = [];
|
let missingFields = [];
|
||||||
let firstMissingInput = null;
|
let firstMissingInput = null;
|
||||||
|
|
||||||
@@ -1556,7 +1563,8 @@ async function submitWeek() {
|
|||||||
el.style.backgroundColor = '';
|
el.style.backgroundColor = '';
|
||||||
});
|
});
|
||||||
|
|
||||||
for (let i = 0; i < 5; i++) {
|
const requiredDays = userArbeitstage || 5; // Fallback auf 5 wenn nicht gesetzt
|
||||||
|
for (let i = 0; i < requiredDays; i++) {
|
||||||
const date = new Date(startDate);
|
const date = new Date(startDate);
|
||||||
date.setDate(date.getDate() + i);
|
date.setDate(date.getDate() + i);
|
||||||
const dateStr = formatDate(date);
|
const dateStr = formatDate(date);
|
||||||
@@ -1644,7 +1652,8 @@ async function submitWeek() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Detaillierte Fehlermeldung
|
// Detaillierte Fehlermeldung
|
||||||
const message = `❌ Bitte füllen Sie alle Werktage (Montag bis Freitag) vollständig aus!\n\n` +
|
const requiredDaysText = requiredDays === 1 ? '1 Tag' : `${requiredDays} Tage`;
|
||||||
|
const message = `❌ Bitte füllen Sie alle ${requiredDaysText} vollständig aus!\n\n` +
|
||||||
`Fehlende Eingaben:\n${missingFields.map((field, index) => `\n${index + 1}. ${field}`).join('')}\n\n` +
|
`Fehlende Eingaben:\n${missingFields.map((field, index) => `\n${index + 1}. ${field}`).join('')}\n\n` +
|
||||||
`Die fehlenden Felder wurden rot markiert.\n` +
|
`Die fehlenden Felder wurden rot markiert.\n` +
|
||||||
`Hinweis: Samstag und Sonntag sind optional.`;
|
`Hinweis: Samstag und Sonntag sind optional.`;
|
||||||
|
|||||||
@@ -262,7 +262,7 @@ function registerTimesheetRoutes(app) {
|
|||||||
// Füge Status-Info hinzu (Bearbeitung ist immer möglich)
|
// Füge Status-Info hinzu (Bearbeitung ist immer möglich)
|
||||||
const entriesWithStatus = (entries || []).map(entry => ({
|
const entriesWithStatus = (entries || []).map(entry => ({
|
||||||
...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,
|
latest_version: latestVersion,
|
||||||
has_existing_version: latestVersion > 0
|
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
|
// Samstag und Sonntag sind optional
|
||||||
// Bei ganztägigem Urlaub (vacation_type = 'full') ist der Tag als ausgefüllt zu betrachten
|
// 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
|
// Bei 8 Überstunden (ganzer Tag) ist der Tag auch als ausgefüllt zu betrachten
|
||||||
@@ -330,7 +330,7 @@ function registerTimesheetRoutes(app) {
|
|||||||
.then((holidaySet) => {
|
.then((holidaySet) => {
|
||||||
let missingDays = [];
|
let missingDays = [];
|
||||||
|
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < arbeitstage; i++) {
|
||||||
// Datum direkt berechnen ohne Zeitzonenprobleme
|
// Datum direkt berechnen ohne Zeitzonenprobleme
|
||||||
const date = new Date(startYear, startMonth, startDay + i);
|
const date = new Date(startYear, startMonth, startDay + i);
|
||||||
const year = date.getFullYear();
|
const year = date.getFullYear();
|
||||||
@@ -380,8 +380,9 @@ function registerTimesheetRoutes(app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (missingDays.length > 0) {
|
if (missingDays.length > 0) {
|
||||||
|
const requiredDaysText = arbeitstage === 1 ? '1 Tag' : `${arbeitstage} Tage`;
|
||||||
return res.status(400).json({
|
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 });
|
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) => {
|
app.get('/api/user/planned-vacation', requireAuth, (req, res) => {
|
||||||
const userId = req.session.userId;
|
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
|
// Zuerst alle eingereichten Wochen abrufen
|
||||||
WHERE user_id = ? AND vacation_type IS NOT NULL AND vacation_type != ''`,
|
db.all(`SELECT DISTINCT week_start FROM weekly_timesheets
|
||||||
|
WHERE user_id = ? AND status = 'eingereicht'`,
|
||||||
[userId],
|
[userId],
|
||||||
(err, entries) => {
|
(err, submittedWeeks) => {
|
||||||
if (err) {
|
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;
|
// Set für schnelle Suche nach eingereichten Wochen
|
||||||
const weeksMap = {}; // { KW: { year: YYYY, week: KW, days: X } }
|
const submittedWeekStarts = new Set(
|
||||||
|
(submittedWeeks || []).map(w => w.week_start)
|
||||||
|
);
|
||||||
|
|
||||||
entries.forEach(entry => {
|
// Alle Urlaubseinträge abrufen
|
||||||
const dayValue = entry.vacation_type === 'full' ? 1 : 0.5;
|
db.all(`SELECT date, vacation_type FROM timesheet_entries
|
||||||
plannedDays += dayValue;
|
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
|
let plannedDays = 0;
|
||||||
const date = new Date(entry.date);
|
const weeksMap = {}; // { KW: { year: YYYY, week: KW, days: X } }
|
||||||
const year = date.getFullYear();
|
|
||||||
const week = getCalendarWeek(entry.date);
|
|
||||||
const weekKey = `${year}-KW${week}`;
|
|
||||||
|
|
||||||
if (!weeksMap[weekKey]) {
|
entries.forEach(entry => {
|
||||||
weeksMap[weekKey] = { year, week, days: 0 };
|
// 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 overtimeOffsetHours = user.overtime_offset_hours ? parseFloat(user.overtime_offset_hours) : 0;
|
||||||
const vacationOffsetDays = user.vacation_offset_days ? parseFloat(user.vacation_offset_days) : 0;
|
const vacationOffsetDays = user.vacation_offset_days ? parseFloat(user.vacation_offset_days) : 0;
|
||||||
|
|
||||||
// Verplante Urlaubstage berechnen (alle Wochen, auch nicht-eingereichte)
|
// Verplante Urlaubstage berechnen (nur nicht-eingereichte Wochen)
|
||||||
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, week_end
|
||||||
|
FROM weekly_timesheets
|
||||||
|
WHERE user_id = ? AND status = 'eingereicht'
|
||||||
|
ORDER BY week_start`,
|
||||||
[userId],
|
[userId],
|
||||||
(err, allVacationEntries) => {
|
(err, weeks) => {
|
||||||
if (err) {
|
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;
|
// Set für schnelle Suche nach eingereichten Wochen
|
||||||
const weeksMap = {}; // { KW: { year: YYYY, week: KW, days: X } }
|
const submittedWeekStarts = new Set(
|
||||||
|
(weeks || []).map(w => w.week_start)
|
||||||
|
);
|
||||||
|
|
||||||
(allVacationEntries || []).forEach(entry => {
|
// Alle Urlaubseinträge abrufen
|
||||||
const dayValue = entry.vacation_type === 'full' ? 1 : 0.5;
|
db.all(`SELECT date, vacation_type FROM timesheet_entries
|
||||||
plannedVacationDays += dayValue;
|
WHERE user_id = ? AND vacation_type IS NOT NULL AND vacation_type != ''`,
|
||||||
|
|
||||||
// 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`,
|
|
||||||
[userId],
|
[userId],
|
||||||
(err, weeks) => {
|
(err, allVacationEntries) => {
|
||||||
if (err) {
|
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
|
// Wenn keine Wochen vorhanden
|
||||||
if (!weeks || weeks.length === 0) {
|
if (!weeks || weeks.length === 0) {
|
||||||
return res.json({
|
return res.json({
|
||||||
|
|||||||
Reference in New Issue
Block a user