Refactoring
This commit is contained in:
182
services/ping-service.js
Normal file
182
services/ping-service.js
Normal file
@@ -0,0 +1,182 @@
|
||||
// Ping-Service für IP-basierte automatische Zeiterfassung
|
||||
|
||||
const ping = require('ping');
|
||||
const { db } = require('../database');
|
||||
const { getCurrentDate, getCurrentTime, updateTotalHours } = require('../helpers/utils');
|
||||
|
||||
// Ping-Funktion für einen User
|
||||
async function pingUserIP(userId, ip, currentDate, currentTime) {
|
||||
try {
|
||||
const result = await ping.promise.probe(ip, {
|
||||
timeout: 3,
|
||||
min_reply: 1
|
||||
});
|
||||
|
||||
const isReachable = result.alive;
|
||||
const now = new Date().toISOString();
|
||||
|
||||
// Hole oder erstelle Ping-Status für heute
|
||||
db.get('SELECT * FROM ping_status WHERE user_id = ? AND date = ?',
|
||||
[userId, currentDate], (err, pingStatus) => {
|
||||
if (err) {
|
||||
console.error(`Fehler beim Abrufen des Ping-Status für User ${userId}:`, err);
|
||||
return;
|
||||
}
|
||||
|
||||
// Hole aktuellen Eintrag für heute
|
||||
db.get('SELECT * FROM timesheet_entries WHERE user_id = ? AND date = ? ORDER BY updated_at DESC, id DESC LIMIT 1',
|
||||
[userId, currentDate], (err, entry) => {
|
||||
if (err) {
|
||||
console.error(`Fehler beim Abrufen des Eintrags für User ${userId}:`, err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isReachable) {
|
||||
// IP ist erreichbar
|
||||
if (!pingStatus) {
|
||||
// Erstelle neuen Ping-Status
|
||||
db.run(`INSERT INTO ping_status (user_id, date, last_successful_ping, failed_ping_count, start_time_set)
|
||||
VALUES (?, ?, ?, 0, 0)`,
|
||||
[userId, currentDate, now], (err) => {
|
||||
if (err) console.error(`Fehler beim Erstellen des Ping-Status:`, err);
|
||||
});
|
||||
} else {
|
||||
// Update Ping-Status: Reset failed_ping_count, update last_successful_ping
|
||||
db.run(`UPDATE ping_status
|
||||
SET last_successful_ping = ?, failed_ping_count = 0, first_failed_ping_time = NULL
|
||||
WHERE user_id = ? AND date = ?`,
|
||||
[now, userId, currentDate], (err) => {
|
||||
if (err) console.error(`Fehler beim Aktualisieren des Ping-Status:`, err);
|
||||
});
|
||||
}
|
||||
|
||||
// Start-Zeit setzen wenn noch nicht vorhanden
|
||||
if (entry && !entry.start_time) {
|
||||
db.run('UPDATE timesheet_entries SET start_time = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
[currentTime, entry.id], (err) => {
|
||||
if (err) {
|
||||
console.error(`Fehler beim Setzen der Start-Zeit für User ${userId}:`, err);
|
||||
} else {
|
||||
console.log(`Start-Zeit gesetzt für User ${userId} um ${currentTime}`);
|
||||
// Markiere dass Start-Zeit gesetzt wurde
|
||||
db.run('UPDATE ping_status SET start_time_set = 1 WHERE user_id = ? AND date = ?',
|
||||
[userId, currentDate], (err) => {
|
||||
if (err) console.error(`Fehler beim Aktualisieren von start_time_set:`, err);
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (!entry) {
|
||||
// Kein Eintrag existiert → Erstelle neuen mit start_time
|
||||
db.run(`INSERT INTO timesheet_entries (user_id, date, start_time, updated_at)
|
||||
VALUES (?, ?, ?, CURRENT_TIMESTAMP)`,
|
||||
[userId, currentDate, currentTime], (err) => {
|
||||
if (err) {
|
||||
console.error(`Fehler beim Erstellen des Eintrags für User ${userId}:`, err);
|
||||
} else {
|
||||
console.log(`Eintrag erstellt und Start-Zeit gesetzt für User ${userId} um ${currentTime}`);
|
||||
// Markiere dass Start-Zeit gesetzt wurde
|
||||
db.run('UPDATE ping_status SET start_time_set = 1 WHERE user_id = ? AND date = ?',
|
||||
[userId, currentDate], (err) => {
|
||||
if (err) {
|
||||
// Falls kein Ping-Status existiert, erstelle einen
|
||||
db.run(`INSERT INTO ping_status (user_id, date, last_successful_ping, failed_ping_count, start_time_set)
|
||||
VALUES (?, ?, ?, 0, 1)`,
|
||||
[userId, currentDate, now], (err) => {
|
||||
if (err) console.error(`Fehler beim Erstellen des Ping-Status:`, err);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// IP ist nicht erreichbar
|
||||
if (!pingStatus) {
|
||||
// Erstelle neuen Ping-Status mit failed_ping_count = 1
|
||||
db.run(`INSERT INTO ping_status (user_id, date, failed_ping_count, first_failed_ping_time)
|
||||
VALUES (?, ?, 1, ?)`,
|
||||
[userId, currentDate, now], (err) => {
|
||||
if (err) console.error(`Fehler beim Erstellen des Ping-Status:`, err);
|
||||
});
|
||||
} else {
|
||||
// Erhöhe failed_ping_count
|
||||
const newFailedCount = (pingStatus.failed_ping_count || 0) + 1;
|
||||
const firstFailedTime = pingStatus.first_failed_ping_time || now;
|
||||
|
||||
db.run(`UPDATE ping_status
|
||||
SET failed_ping_count = ?, first_failed_ping_time = ?
|
||||
WHERE user_id = ? AND date = ?`,
|
||||
[newFailedCount, firstFailedTime, userId, currentDate], (err) => {
|
||||
if (err) console.error(`Fehler beim Aktualisieren des Ping-Status:`, err);
|
||||
});
|
||||
|
||||
// Wenn 3 oder mehr fehlgeschlagene Pings UND Start-Zeit existiert UND keine End-Zeit
|
||||
if (newFailedCount >= 3 && entry && entry.start_time && !entry.end_time) {
|
||||
// Setze End-Zeit auf Zeit des ersten fehlgeschlagenen Pings
|
||||
const firstFailedDate = new Date(firstFailedTime);
|
||||
const endTime = `${String(firstFailedDate.getHours()).padStart(2, '0')}:${String(firstFailedDate.getMinutes()).padStart(2, '0')}`;
|
||||
|
||||
// Berechne total_hours
|
||||
const breakMinutes = entry.break_minutes || 0;
|
||||
const totalHours = updateTotalHours(entry.start_time, endTime, breakMinutes);
|
||||
|
||||
db.run('UPDATE timesheet_entries SET end_time = ?, total_hours = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
||||
[endTime, totalHours, entry.id], (err) => {
|
||||
if (err) {
|
||||
console.error(`Fehler beim Setzen der End-Zeit für User ${userId}:`, err);
|
||||
} else {
|
||||
console.log(`End-Zeit gesetzt für User ${userId} um ${endTime} (nach ${newFailedCount} fehlgeschlagenen Pings)`);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Fehler beim Ping für User ${userId} (IP: ${ip}):`, error);
|
||||
// Behandle als nicht erreichbar
|
||||
const now = new Date().toISOString();
|
||||
db.get('SELECT * FROM ping_status WHERE user_id = ? AND date = ?',
|
||||
[userId, currentDate], (err, pingStatus) => {
|
||||
if (!err && pingStatus) {
|
||||
const newFailedCount = (pingStatus.failed_ping_count || 0) + 1;
|
||||
const firstFailedTime = pingStatus.first_failed_ping_time || now;
|
||||
|
||||
db.run(`UPDATE ping_status
|
||||
SET failed_ping_count = ?, first_failed_ping_time = ?
|
||||
WHERE user_id = ? AND date = ?`,
|
||||
[newFailedCount, firstFailedTime, userId, currentDate], (err) => {
|
||||
if (err) console.error(`Fehler beim Aktualisieren des Ping-Status:`, err);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Ping-Service Setup
|
||||
function setupPingService() {
|
||||
setInterval(async () => {
|
||||
const currentDate = getCurrentDate();
|
||||
const currentTime = getCurrentTime();
|
||||
|
||||
// Hole alle User mit IP-Adresse
|
||||
db.all('SELECT id, ping_ip FROM users WHERE ping_ip IS NOT NULL AND ping_ip != ""', (err, users) => {
|
||||
if (err) {
|
||||
console.error('Fehler beim Abrufen der User mit IP-Adressen:', err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!users || users.length === 0) {
|
||||
return; // Keine User mit IP-Adressen
|
||||
}
|
||||
|
||||
// Ping alle User parallel
|
||||
users.forEach(user => {
|
||||
pingUserIP(user.id, user.ping_ip, currentDate, currentTime);
|
||||
});
|
||||
});
|
||||
}, 60000); // Jede Minute
|
||||
}
|
||||
|
||||
module.exports = { setupPingService };
|
||||
Reference in New Issue
Block a user