Refactoring
This commit is contained in:
195
routes/verwaltung.js
Normal file
195
routes/verwaltung.js
Normal file
@@ -0,0 +1,195 @@
|
||||
// Verwaltung Routes
|
||||
|
||||
const { db } = require('../database');
|
||||
const { requireVerwaltung } = require('../middleware/auth');
|
||||
|
||||
// Routes registrieren
|
||||
function registerVerwaltungRoutes(app) {
|
||||
// Verwaltungs-Bereich
|
||||
app.get('/verwaltung', requireVerwaltung, (req, res) => {
|
||||
db.all(`
|
||||
SELECT wt.*, u.firstname, u.lastname, u.username, u.personalnummer, u.wochenstunden, u.urlaubstage,
|
||||
dl.firstname as downloaded_by_firstname,
|
||||
dl.lastname as downloaded_by_lastname,
|
||||
(SELECT COUNT(*) FROM weekly_timesheets wt2
|
||||
WHERE wt2.user_id = wt.user_id
|
||||
AND wt2.week_start = wt.week_start
|
||||
AND wt2.week_end = wt.week_end) as total_versions
|
||||
FROM weekly_timesheets wt
|
||||
JOIN users u ON wt.user_id = u.id
|
||||
LEFT JOIN users dl ON wt.pdf_downloaded_by = dl.id
|
||||
WHERE wt.status = 'eingereicht'
|
||||
ORDER BY wt.week_start DESC, wt.user_id, wt.version DESC
|
||||
`, (err, timesheets) => {
|
||||
// Gruppiere nach Mitarbeiter, dann nach Kalenderwoche
|
||||
// Struktur: { [user_id]: { user: {...}, weeks: { [week_key]: {...} } } }
|
||||
const groupedByEmployee = {};
|
||||
|
||||
(timesheets || []).forEach(ts => {
|
||||
const userId = ts.user_id;
|
||||
const weekKey = `${ts.week_start}_${ts.week_end}`;
|
||||
|
||||
// Level 1: Mitarbeiter
|
||||
if (!groupedByEmployee[userId]) {
|
||||
groupedByEmployee[userId] = {
|
||||
user: {
|
||||
id: ts.user_id,
|
||||
firstname: ts.firstname,
|
||||
lastname: ts.lastname,
|
||||
username: ts.username,
|
||||
personalnummer: ts.personalnummer,
|
||||
wochenstunden: ts.wochenstunden,
|
||||
urlaubstage: ts.urlaubstage
|
||||
},
|
||||
weeks: {}
|
||||
};
|
||||
}
|
||||
|
||||
// Level 2: Kalenderwoche
|
||||
if (!groupedByEmployee[userId].weeks[weekKey]) {
|
||||
groupedByEmployee[userId].weeks[weekKey] = {
|
||||
week_start: ts.week_start,
|
||||
week_end: ts.week_end,
|
||||
total_versions: ts.total_versions,
|
||||
versions: []
|
||||
};
|
||||
}
|
||||
|
||||
// Level 3: Versionen
|
||||
groupedByEmployee[userId].weeks[weekKey].versions.push(ts);
|
||||
});
|
||||
|
||||
// Sortierung: Mitarbeiter nach Name, Wochen nach Datum (neueste zuerst)
|
||||
const sortedEmployees = Object.values(groupedByEmployee).map(employee => {
|
||||
// Wochen innerhalb jedes Mitarbeiters sortieren
|
||||
const sortedWeeks = Object.values(employee.weeks).sort((a, b) => {
|
||||
return new Date(b.week_start) - new Date(a.week_start);
|
||||
});
|
||||
|
||||
return {
|
||||
...employee,
|
||||
weeks: sortedWeeks
|
||||
};
|
||||
}).sort((a, b) => {
|
||||
// Mitarbeiter nach Nachname, dann Vorname sortieren
|
||||
const nameA = `${a.user.lastname} ${a.user.firstname}`.toLowerCase();
|
||||
const nameB = `${b.user.lastname} ${b.user.firstname}`.toLowerCase();
|
||||
return nameA.localeCompare(nameB);
|
||||
});
|
||||
|
||||
res.render('verwaltung', {
|
||||
groupedByEmployee: sortedEmployees,
|
||||
user: {
|
||||
firstname: req.session.firstname,
|
||||
lastname: req.session.lastname,
|
||||
roles: req.session.roles || [],
|
||||
currentRole: req.session.currentRole || 'verwaltung'
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// API: Überstunden- und Urlaubsstatistiken für einen User abrufen
|
||||
app.get('/api/verwaltung/user/:id/stats', requireVerwaltung, (req, res) => {
|
||||
const userId = req.params.id;
|
||||
const { week_start, week_end } = req.query;
|
||||
|
||||
// User-Daten abrufen
|
||||
db.get('SELECT wochenstunden, urlaubstage FROM users WHERE id = ?', [userId], (err, user) => {
|
||||
if (err || !user) {
|
||||
return res.status(500).json({ error: 'Fehler beim Abrufen der User-Daten' });
|
||||
}
|
||||
|
||||
const wochenstunden = user.wochenstunden || 0;
|
||||
const urlaubstage = user.urlaubstage || 0;
|
||||
|
||||
// Einträge für die Woche abrufen
|
||||
db.all(`SELECT date, total_hours, overtime_taken_hours, vacation_type
|
||||
FROM timesheet_entries
|
||||
WHERE user_id = ? AND date >= ? AND date <= ?
|
||||
ORDER BY date`,
|
||||
[userId, week_start, week_end],
|
||||
(err, entries) => {
|
||||
if (err) {
|
||||
return res.status(500).json({ error: 'Fehler beim Abrufen der Einträge' });
|
||||
}
|
||||
|
||||
// Berechnungen
|
||||
let totalHours = 0;
|
||||
let overtimeTaken = 0;
|
||||
let vacationDays = 0;
|
||||
let vacationHours = 0;
|
||||
|
||||
entries.forEach(entry => {
|
||||
if (entry.total_hours) {
|
||||
totalHours += entry.total_hours;
|
||||
}
|
||||
if (entry.overtime_taken_hours) {
|
||||
overtimeTaken += entry.overtime_taken_hours;
|
||||
}
|
||||
if (entry.vacation_type === 'full') {
|
||||
vacationDays += 1;
|
||||
vacationHours += 8; // Ganzer Tag = 8 Stunden
|
||||
} else if (entry.vacation_type === 'half') {
|
||||
vacationDays += 0.5;
|
||||
vacationHours += 4; // Halber Tag = 4 Stunden
|
||||
}
|
||||
});
|
||||
|
||||
// Anzahl Werktage berechnen (Montag-Freitag)
|
||||
const startDate = new Date(week_start);
|
||||
const endDate = new Date(week_end);
|
||||
let workdays = 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++;
|
||||
}
|
||||
}
|
||||
|
||||
// Sollstunden berechnen
|
||||
const sollStunden = (wochenstunden / 5) * workdays;
|
||||
|
||||
// Überstunden berechnen: Urlaub zählt als normale Arbeitszeit
|
||||
// Überstunden = (Tatsächliche Stunden + Urlaubsstunden) - Sollstunden
|
||||
const totalHoursWithVacation = totalHours + vacationHours;
|
||||
const overtimeHours = totalHoursWithVacation - sollStunden;
|
||||
const remainingOvertime = overtimeHours - overtimeTaken;
|
||||
|
||||
// Verbleibende Urlaubstage
|
||||
const remainingVacation = urlaubstage - vacationDays;
|
||||
|
||||
res.json({
|
||||
wochenstunden,
|
||||
urlaubstage,
|
||||
totalHours,
|
||||
sollStunden,
|
||||
overtimeHours,
|
||||
overtimeTaken,
|
||||
remainingOvertime,
|
||||
vacationDays,
|
||||
remainingVacation,
|
||||
workdays
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// API: Admin-Kommentar speichern
|
||||
app.put('/api/verwaltung/timesheet/:id/comment', requireVerwaltung, (req, res) => {
|
||||
const timesheetId = req.params.id;
|
||||
const { comment } = req.body;
|
||||
|
||||
db.run('UPDATE weekly_timesheets SET admin_comment = ? WHERE id = ?',
|
||||
[comment ? comment.trim() : null, timesheetId],
|
||||
(err) => {
|
||||
if (err) {
|
||||
console.error('Fehler beim Speichern des Kommentars:', err);
|
||||
return res.status(500).json({ error: 'Fehler beim Speichern des Kommentars' });
|
||||
}
|
||||
res.json({ success: true });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = registerVerwaltungRoutes;
|
||||
Reference in New Issue
Block a user