zeiterfassung service update auf ajax
This commit is contained in:
1 parent
405b9c27e7
commit
26f5519888
3 files changed
+180
-57
No files matched your search
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
session_start();
|
||||
include_once(__DIR__ . '/../../../controller/DatabaseController.php');
|
||||
|
||||
header('Content-Type: application/json');
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', '0');
|
||||
|
||||
$daten = json_decode(file_get_contents('php://input'), true) ?? [];
|
||||
$action = $daten['action'] ?? '';
|
||||
|
||||
$erlaubteGruende = ['Abbau', 'Aufbau', 'Anderes'];
|
||||
|
||||
function istBerechtigt(): bool {
|
||||
$username = $_SESSION['username'] ?? '';
|
||||
return strtolower($username) === 'bruno';
|
||||
}
|
||||
|
||||
try {
|
||||
switch ($action) {
|
||||
|
||||
case 'get_stats': {
|
||||
include_once(__DIR__ . '/../../../controller/DatabaseConnect.php');
|
||||
$conn = db_connect();
|
||||
|
||||
$minuten_berichte = 0;
|
||||
$res1 = $conn->query("SELECT SUM(OVERTIME) AS summe FROM Firmenberichte");
|
||||
if ($row = $res1->fetch_object()) { $minuten_berichte = intval($row->summe); }
|
||||
|
||||
$minuten_abbau = 0;
|
||||
$res2 = $conn->query("SELECT SUM(MINUTEN) AS summe FROM Ueberstunden WHERE GRUND = 'Abbau'");
|
||||
if ($row = $res2->fetch_object()) { $minuten_abbau = intval($row->summe); }
|
||||
|
||||
$minuten_aufbau = 0;
|
||||
$res3 = $conn->query("SELECT SUM(MINUTEN) AS summe FROM Ueberstunden WHERE GRUND = 'Aufbau'");
|
||||
if ($row = $res3->fetch_object()) { $minuten_aufbau = intval($row->summe); }
|
||||
|
||||
$gesamt_minuten = $minuten_berichte - $minuten_abbau + $minuten_aufbau;
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'gesamtMinuten' => $gesamt_minuten,
|
||||
'istBerechtigt' => istBerechtigt(),
|
||||
]);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'add_overtime': {
|
||||
if (!istBerechtigt()) {
|
||||
http_response_code(403);
|
||||
echo json_encode(['error' => 'Keine Berechtigung für diese Aktion']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$datum = trim($daten['datum'] ?? '');
|
||||
$minuten = $daten['minuten'] ?? null;
|
||||
$grund = trim($daten['grund'] ?? '');
|
||||
|
||||
if ($datum === '' || !is_numeric($minuten) || $grund === '') {
|
||||
throw new InvalidArgumentException('Bitte alle Pflichtfelder korrekt ausfüllen.');
|
||||
}
|
||||
|
||||
if (!in_array($grund, $erlaubteGruende, true)) {
|
||||
throw new InvalidArgumentException('Ungültiger Grund.');
|
||||
}
|
||||
|
||||
DatabaseInsert(
|
||||
"Ueberstunden",
|
||||
"DATUM, MINUTEN, GRUND",
|
||||
$datum,
|
||||
intval($minuten),
|
||||
$grund
|
||||
);
|
||||
|
||||
echo json_encode(['success' => true, 'message' => 'Eintrag erfolgreich gespeichert!']);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new InvalidArgumentException("Unbekannte Aktion: $action");
|
||||
}
|
||||
|
||||
} catch (InvalidArgumentException $e) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => $e->getMessage()]);
|
||||
} catch (Throwable $e) {
|
||||
http_response_code(500);
|
||||
error_log($e->getMessage());
|
||||
echo json_encode(['error' => 'Serverfehler']);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
const OVERTIME_HANDLER_URL = '/api/js/handler/ZeiterfassungAjaxHandler';
|
||||
|
||||
async function overtimeAjaxRequest(payload) {
|
||||
try {
|
||||
const response = await fetch(OVERTIME_HANDLER_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
const data = await parseJsonResponse(response);
|
||||
|
||||
if (data.error) {
|
||||
throw new Error(data.error);
|
||||
}
|
||||
return data;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Overtime-Ajax-Fehler:', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function getOvertimeStats() {
|
||||
return overtimeAjaxRequest({ action: 'get_stats' });
|
||||
}
|
||||
|
||||
function addOvertimeEntry(datum, minuten, grund) {
|
||||
return overtimeAjaxRequest({ action: 'add_overtime', datum, minuten, grund });
|
||||
}
|
||||
@@ -1,73 +1,27 @@
|
||||
<?php
|
||||
include_once __DIR__ . '/../controller/DatabaseController.php';
|
||||
include_once __DIR__ . '/../controller/RoutesController.php';
|
||||
|
||||
$conn = db_connect();
|
||||
$view = $_GET['view'] ?? 'show';
|
||||
$selectedService = $_GET['service'];
|
||||
|
||||
// --- LOGIK: Überstunden-Eintrag (Abbau) speichern ---
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_overtime'])) {
|
||||
$datum = $_POST['ot_date'];
|
||||
$minuten = intval($_POST['ot_minutes']);
|
||||
$grund = $conn->real_escape_string($_POST['ot_reason']);
|
||||
|
||||
DatabaseInsert(
|
||||
"Ueberstunden",
|
||||
"DATUM, MINUTEN, GRUND",
|
||||
$datum,
|
||||
$minuten,
|
||||
$grund
|
||||
);
|
||||
|
||||
redirectToWebsite((new getSpecificData())->getReferer());
|
||||
exit;
|
||||
}
|
||||
|
||||
// --- Gesamtsumme berechnen ---
|
||||
$minuten_berichte = 0;
|
||||
$res1 = $conn->query("SELECT SUM(OVERTIME) AS summe FROM Firmenberichte");
|
||||
if ($row = $res1->fetch_object()) { $minuten_berichte = intval($row->summe); }
|
||||
|
||||
$minuten_abbau = 0;
|
||||
$res2 = $conn->query("SELECT SUM(MINUTEN) AS summe FROM Ueberstunden WHERE GRUND = 'Abbau'");
|
||||
if ($row = $res2->fetch_object()) { $minuten_abbau = intval($row->summe); }
|
||||
|
||||
$minuten_aufbau = 0;
|
||||
$res2 = $conn->query("SELECT SUM(MINUTEN) AS summe FROM Ueberstunden WHERE GRUND = 'Aufbau'");
|
||||
if ($row = $res2->fetch_object()) { $minuten_aufbau = intval($row->summe); }
|
||||
|
||||
$gesamt_minuten = $minuten_berichte - $minuten_abbau + $minuten_aufbau;
|
||||
?>
|
||||
|
||||
<div class="arbeitsberichte-wrapper">
|
||||
<div
|
||||
<div id="overtimeCard"
|
||||
style="background: rgba(150,150,150,0.05); padding: 25px; border-radius: 10px; margin-bottom: 25px; border: 1px solid rgba(150,150,150,0.2); border-left: 6px solid #007bff;">
|
||||
|
||||
<div style="margin-bottom: 20px;">
|
||||
<span style="color: #888; font-size: 0.8rem; font-weight: bold; text-transform: uppercase;">Aktueller
|
||||
Stand</span>
|
||||
<h2 style="margin: 5px 0 0 0; font-size: 2rem; color: <?= $gesamt_minuten >= 0 ? '#28a745' : '#dc3545' ?>;">
|
||||
<?= intdiv($gesamt_minuten, 60) ?>h <?= abs($gesamt_minuten % 60) ?>min
|
||||
</h2>
|
||||
<h2 id="standAnzeige" style="margin: 5px 0 0 0; font-size: 2rem;">Lädt...</h2>
|
||||
</div>
|
||||
<?php if ($_SESSION['username'] == "bruno" || $_SESSION['username'] == "Bruno"): ?>
|
||||
<form method="POST" style="display: flex; gap: 15px; flex-wrap: wrap; align-items: flex-end;">
|
||||
<input type="hidden" name="add_overtime" value="1">
|
||||
|
||||
<form id="overtimeForm" style="display: none; gap: 15px; flex-wrap: wrap; align-items: flex-end;">
|
||||
<div style="display: flex; flex-direction: column; gap: 5px;">
|
||||
<label style="font-size: 0.85rem; font-weight: 600; color: inherit;">Datum</label>
|
||||
<input type="date" name="ot_date" value="<?= date('Y-m-d') ?>" required
|
||||
<input type="date" id="ot-date" required
|
||||
style="padding: 8px; border: 1px solid rgba(150,150,150,0.3); border-radius: 4px; background: rgba(150,150,150,0.1); color: inherit;">
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 5px;">
|
||||
<label style="font-size: 0.85rem; font-weight: 600; color: inherit;">Minuten Abbau</label>
|
||||
<input type="number" name="ot_minutes" placeholder="480" required
|
||||
<label style="font-size: 0.85rem; font-weight: 600; color: inherit;">Minuten</label>
|
||||
<input type="number" id="ot-minutes" placeholder="480" required
|
||||
style="width: 100px; padding: 8px; border: 1px solid rgba(150,150,150,0.3); border-radius: 4px; background: rgba(150,150,150,0.1); color: inherit;">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label style="font-size: 0.85rem; font-weight: 600; color: inherit;">Grund</label>
|
||||
|
||||
<select name="ot_reason" required>
|
||||
|
||||
<select id="ot-reason" required>
|
||||
<option value="">Bitte wählen</option>
|
||||
<option value="Abbau">Abbau</option>
|
||||
<option value="Aufbau">Aufbau</option>
|
||||
@@ -79,6 +33,56 @@ $gesamt_minuten = $minuten_berichte - $minuten_abbau + $minuten_aufbau;
|
||||
Eintrag speichern
|
||||
</button>
|
||||
</form>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/js/AjaxMethods.js"></script>
|
||||
<script src="/js/AjaxRenderTables.js"></script>
|
||||
<script src="/js/ajaxApi/ZeiterfassungAjaxMethods.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const standAnzeige = document.getElementById('standAnzeige');
|
||||
const overtimeForm = document.getElementById('overtimeForm');
|
||||
|
||||
function formatStand(gesamtMinuten) {
|
||||
const stunden = Math.trunc(gesamtMinuten / 60);
|
||||
const minuten = Math.abs(gesamtMinuten % 60);
|
||||
return `${stunden}h ${minuten}min`;
|
||||
}
|
||||
|
||||
async function ladeStand() {
|
||||
try {
|
||||
const data = await getOvertimeStats();
|
||||
|
||||
standAnzeige.textContent = formatStand(data.gesamtMinuten);
|
||||
standAnzeige.style.color = data.gesamtMinuten >= 0 ? '#28a745' : '#dc3545';
|
||||
|
||||
overtimeForm.style.display = data.istBerechtigt ? 'flex' : 'none';
|
||||
|
||||
} catch (err) {
|
||||
standAnzeige.textContent = 'Fehler beim Laden';
|
||||
console.error(err.message);
|
||||
}
|
||||
}
|
||||
|
||||
overtimeForm.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const datum = document.getElementById('ot-date').value;
|
||||
const minuten = document.getElementById('ot-minutes').value;
|
||||
const grund = document.getElementById('ot-reason').value;
|
||||
|
||||
try {
|
||||
await addOvertimeEntry(datum, minuten, grund);
|
||||
e.target.reset();
|
||||
document.getElementById('ot-date').value = new Date().toISOString().slice(0, 10);
|
||||
await ladeStand();
|
||||
} catch (err) {
|
||||
alert('Fehler beim Speichern: ' + err.message);
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('ot-date').value = new Date().toISOString().slice(0, 10);
|
||||
ladeStand();
|
||||
});
|
||||
</script>
|
||||
Reference in new issue
Block a user