Implementierung Datenbank pflege wegen doppelten einträgen
This commit is contained in:
@@ -322,6 +322,96 @@ function registerAdminRoutes(app) {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Timesheet-Duplikate (mehr als ein Eintrag pro Benutzer und Datum) als Übersicht
|
||||
app.get('/admin/api/timesheet-duplicates', requireAdmin, (req, res) => {
|
||||
const sql = `
|
||||
SELECT
|
||||
te.*,
|
||||
dup.entry_count,
|
||||
u.firstname,
|
||||
u.lastname,
|
||||
u.username
|
||||
FROM timesheet_entries te
|
||||
INNER JOIN (
|
||||
SELECT user_id, date, COUNT(*) AS entry_count
|
||||
FROM timesheet_entries
|
||||
GROUP BY user_id, date
|
||||
HAVING COUNT(*) > 1
|
||||
) dup
|
||||
ON dup.user_id = te.user_id
|
||||
AND dup.date = te.date
|
||||
INNER JOIN users u
|
||||
ON u.id = te.user_id
|
||||
ORDER BY te.user_id, te.date, te.id
|
||||
`;
|
||||
|
||||
db.all(sql, [], (err, rows) => {
|
||||
if (err) {
|
||||
console.error('Fehler beim Laden der Timesheet-Duplikate:', err);
|
||||
return res.status(500).json({ error: 'Fehler beim Laden der Timesheet-Duplikate' });
|
||||
}
|
||||
|
||||
const groupsMap = new Map();
|
||||
|
||||
(rows || []).forEach(row => {
|
||||
const key = `${row.user_id}|${row.date}`;
|
||||
if (!groupsMap.has(key)) {
|
||||
const userNameParts = [];
|
||||
if (row.firstname) userNameParts.push(row.firstname);
|
||||
if (row.lastname) userNameParts.push(row.lastname);
|
||||
const user_name = userNameParts.join(' ') || row.username || `User #${row.user_id}`;
|
||||
|
||||
groupsMap.set(key, {
|
||||
user_id: row.user_id,
|
||||
user_name,
|
||||
username: row.username,
|
||||
date: row.date,
|
||||
entry_count: row.entry_count,
|
||||
entries: []
|
||||
});
|
||||
}
|
||||
|
||||
const group = groupsMap.get(key);
|
||||
group.entries.push({
|
||||
id: row.id,
|
||||
start_time: row.start_time,
|
||||
end_time: row.end_time,
|
||||
break_minutes: row.break_minutes,
|
||||
total_hours: row.total_hours,
|
||||
status: row.status,
|
||||
notes: row.notes,
|
||||
created_at: row.created_at,
|
||||
updated_at: row.updated_at
|
||||
});
|
||||
});
|
||||
|
||||
const groups = Array.from(groupsMap.values());
|
||||
res.json({ groups });
|
||||
});
|
||||
});
|
||||
|
||||
// Einzelnen Timesheet-Eintrag löschen (zur manuellen Bereinigung von Duplikaten)
|
||||
app.delete('/admin/api/timesheet-entry/:id', requireAdmin, (req, res) => {
|
||||
const entryId = parseInt(req.params.id, 10);
|
||||
|
||||
if (!Number.isInteger(entryId) || entryId <= 0) {
|
||||
return res.status(400).json({ error: 'Ungültige Eintrags-ID' });
|
||||
}
|
||||
|
||||
db.run('DELETE FROM timesheet_entries WHERE id = ?', [entryId], function(err) {
|
||||
if (err) {
|
||||
console.error('Fehler beim Löschen des Timesheet-Eintrags:', err);
|
||||
return res.status(500).json({ error: 'Fehler beim Löschen des Timesheet-Eintrags' });
|
||||
}
|
||||
|
||||
if (this.changes === 0) {
|
||||
return res.status(404).json({ error: 'Timesheet-Eintrag nicht gefunden' });
|
||||
}
|
||||
|
||||
res.json({ success: true });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = registerAdminRoutes;
|
||||
|
||||
Reference in New Issue
Block a user