feat: JSON-Bridge für die Logbuch-App inkl. Spende-Feld
Bringt die bislang nur im Working Tree vorhandene Logbuch-Unterstützung in die Versionsverwaltung: RepoLogbuch (Liste, Anlegen, Ändern, Löschen, BEOs/Objekte, Fahrkosten, Backup) samt der LB_*-Kommandos und der zugehörigen Tabellenkonstanten. Neu darin sind die Spalten Spende und SpendeBetrag: SELECT/INSERT/UPDATE sind erweitert, spendeValues() setzt beides auf NULL außer bei ArtFuehrung 'SF', prüft den Wert gegen eine Whitelist und übernimmt den Betrag nur bei 'bar'. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+731
-11
@@ -123,6 +123,12 @@ const TBL_SOFIANMELD = 'sofianmeld';
|
||||
const TBL_FDATES = 'fdates';
|
||||
const TBL_SONNEANMELD = 'sonneanmeld';
|
||||
|
||||
// ---- Logbuch-Tabellen ----
|
||||
const TBL_LOGBUCH = 'logbuch';
|
||||
const TBL_LOGBUCH_BEOS = 'logbuch_beos';
|
||||
const TBL_LOGBUCH_OBJEKTE = 'logbuch_objekte';
|
||||
const TBL_OBJEKTE = 'objekte';
|
||||
|
||||
const URL_KALENDER = 'https://sternwarte-welzheim.de/kalender/';
|
||||
const URL_BEO_FORM = 'beoform/beoFormular.php?id=';
|
||||
const LISTE_EMAIL = 'sofue-liste@sternwarte-welzheim.de';
|
||||
@@ -547,6 +553,10 @@ class RepoBeos
|
||||
{
|
||||
return DB::one("SELECT * FROM " . TBL_BEOS . " WHERE name=?", [$name]);
|
||||
}
|
||||
public static function getByNamePW(string $kurz, string $what): ?array
|
||||
{
|
||||
return DB::one("SELECT $what FROM " . TBL_BEOS . " WHERE kürzel=?", [$kurz]);
|
||||
}
|
||||
public static function vorname(string $name): string
|
||||
{
|
||||
$r = self::getByName($name);
|
||||
@@ -893,6 +903,563 @@ class RepoStatistikGesamt
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Logbuch Repository (liest direkt aus der logbuch-Tabelle) ----
|
||||
class RepoLogbuch
|
||||
{
|
||||
public static function firstYear(): ?int
|
||||
{
|
||||
$r = DB::one("SELECT MIN(YEAR(Beginn)) AS y FROM logbuch");
|
||||
return isset($r['y']) && $r['y'] !== null ? (int)$r['y'] : null;
|
||||
}
|
||||
|
||||
public static function yearList(): array
|
||||
{
|
||||
$rows = DB::all("SELECT DISTINCT YEAR(Beginn) AS jahr FROM logbuch ORDER BY jahr DESC");
|
||||
return array_map(function($r) { return (int)$r['jahr']; }, $rows);
|
||||
}
|
||||
|
||||
public static function getByYear(int $year): array
|
||||
{
|
||||
// Laufenden Monat nicht anzeigen – Daten erst ab dem 1. des Folgemonats
|
||||
$dateFilter = ($year == (int)date('Y')) ? " AND Beginn < DATE_FORMAT(NOW(), '%Y-%m-01')" : "";
|
||||
|
||||
$sql =
|
||||
"SELECT MONTH(Beginn) AS monat," .
|
||||
" SUM(CASE WHEN ArtFuehrung IN ('RF','PrF','SonF','Sonst') THEN Besucher ELSE 0 END) AS besucherNormal," .
|
||||
" SUM(CASE WHEN ArtFuehrung IN ('SF','BEOS') THEN Besucher ELSE 0 END) AS besucherSonder," .
|
||||
" SUM(CASE WHEN ArtFuehrung = 'ToT' THEN Besucher ELSE 0 END) AS besucherToT," .
|
||||
" SUM(CASE WHEN ArtFuehrung NOT IN ('TD','Beob') THEN 1 ELSE 0 END) AS fuehrungen," .
|
||||
" SUM(CASE WHEN ArtFuehrung = 'Beob' THEN 1 ELSE 0 END) AS beobachtungen," .
|
||||
" SUM(CASE WHEN ArtFuehrung = 'TD' THEN 1 ELSE 0 END) AS techdienst" .
|
||||
" FROM logbuch WHERE YEAR(Beginn) = ?" . $dateFilter .
|
||||
" GROUP BY MONTH(Beginn)";
|
||||
$rows = DB::all($sql, [$year]);
|
||||
|
||||
// Index by month number
|
||||
$byMonth = [];
|
||||
foreach ($rows as $r) {
|
||||
$byMonth[(int)$r['monat']] = $r;
|
||||
}
|
||||
|
||||
// Always return all 12 months so statistic.js positions bars correctly
|
||||
$data = [];
|
||||
for ($m = 1; $m <= 12; $m++) {
|
||||
if (isset($byMonth[$m])) {
|
||||
$r = $byMonth[$m];
|
||||
$data[] = [
|
||||
'datum' => sprintf('%04d-%02d-01', $year, $m),
|
||||
'besucherNormal' => (int)$r['besucherNormal'],
|
||||
'besucherSonder' => (int)$r['besucherSonder'],
|
||||
'besucherToT' => (int)$r['besucherToT'],
|
||||
'fuehrungen' => (int)$r['fuehrungen'],
|
||||
'beobachtungen' => (int)$r['beobachtungen'],
|
||||
'techdienst' => (int)$r['techdienst'],
|
||||
'beoTage' => 0,
|
||||
'beoZeit' => 0,
|
||||
'bemerkung' => '',
|
||||
];
|
||||
} else {
|
||||
$data[] = [
|
||||
'datum' => sprintf('%04d-%02d-01', $year, $m),
|
||||
'besucherNormal' => 0,
|
||||
'besucherSonder' => 0,
|
||||
'besucherToT' => 0,
|
||||
'fuehrungen' => 0,
|
||||
'beobachtungen' => 0,
|
||||
'techdienst' => 0,
|
||||
'beoTage' => 0,
|
||||
'beoZeit' => 0,
|
||||
'bemerkung' => '',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$sumB = array_sum(array_map(
|
||||
function($r) { return $r['besucherNormal'] + $r['besucherSonder'] + $r['besucherToT']; },
|
||||
$data
|
||||
));
|
||||
$sumA = array_sum(array_map(
|
||||
function($r) { return $r['fuehrungen'] + $r['beobachtungen'] + $r['techdienst']; },
|
||||
$data
|
||||
));
|
||||
|
||||
$gesamt = DB::one("SELECT bemerkung FROM StatistikGesamt WHERE jahr=?", [$year]);
|
||||
return [
|
||||
'data' => $data,
|
||||
'sumB' => $sumB,
|
||||
'sumA' => $sumA,
|
||||
'sumBZ' => 0,
|
||||
'sumBT' => 0,
|
||||
'bemG' => $gesamt['bemerkung'] ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
public static function yearlySummary(): array
|
||||
{
|
||||
$sql =
|
||||
"SELECT YEAR(Beginn) AS jahr," .
|
||||
" SUM(Besucher) AS besucher," .
|
||||
" COUNT(*) AS aktivitaeten," .
|
||||
" '' AS bemerkung" .
|
||||
" FROM logbuch GROUP BY YEAR(Beginn) ORDER BY jahr DESC";
|
||||
return DB::all($sql);
|
||||
}
|
||||
|
||||
public static function getByMonth(string $datum): ?array
|
||||
{
|
||||
$year = (int)substr($datum, 0, 4);
|
||||
$month = (int)substr($datum, 5, 2);
|
||||
$sql =
|
||||
"SELECT COUNT(*) AS cnt," .
|
||||
" SUM(CASE WHEN ArtFuehrung IN ('RF','PrF','SonF','Sonst') THEN COALESCE(Besucher,0) ELSE 0 END) AS besucherNormal," .
|
||||
" SUM(CASE WHEN ArtFuehrung IN ('SF','BEOS') THEN COALESCE(Besucher,0) ELSE 0 END) AS besucherSonder," .
|
||||
" SUM(CASE WHEN ArtFuehrung = 'ToT' THEN COALESCE(Besucher,0) ELSE 0 END) AS besucherToT," .
|
||||
" SUM(CASE WHEN ArtFuehrung NOT IN ('TD','Beob') THEN 1 ELSE 0 END) AS fuehrungen," .
|
||||
" SUM(CASE WHEN ArtFuehrung = 'Beob' THEN 1 ELSE 0 END) AS beobachtungen," .
|
||||
" SUM(CASE WHEN ArtFuehrung = 'TD' THEN 1 ELSE 0 END) AS techdienst" .
|
||||
" FROM logbuch WHERE YEAR(Beginn)=? AND MONTH(Beginn)=?";
|
||||
$r = DB::one($sql, [$year, $month]);
|
||||
if ((int)($r['cnt'] ?? 0) === 0) return null;
|
||||
return [
|
||||
'datum' => sprintf('%04d-%02d-01', $year, $month),
|
||||
'besucherNormal' => (int)($r['besucherNormal'] ?? 0),
|
||||
'besucherSonder' => (int)($r['besucherSonder'] ?? 0),
|
||||
'besucherToT' => (int)($r['besucherToT'] ?? 0),
|
||||
'fuehrungen' => (int)($r['fuehrungen'] ?? 0),
|
||||
'beobachtungen' => (int)($r['beobachtungen'] ?? 0),
|
||||
'techdienst' => (int)($r['techdienst'] ?? 0),
|
||||
'beoTage' => 0,
|
||||
'beoZeit' => 0.0,
|
||||
'bemerkung' => '',
|
||||
'bemG' => '',
|
||||
];
|
||||
}
|
||||
|
||||
// ---- Logbuch-CRUD & Auth (für Logbuch-App) ----
|
||||
|
||||
private static function checkAccess(int $logbuchId, int $userId, string $userRole, string $action): void
|
||||
{
|
||||
$row = DB::one("SELECT ID FROM " . TBL_LOGBUCH . " WHERE ID = ?", [$logbuchId]);
|
||||
if (!$row) {
|
||||
respondError('Eintrag nicht gefunden', 404);
|
||||
}
|
||||
if (strpos($userRole, 'admin') !== false) return;
|
||||
$beoRow = DB::one(
|
||||
"SELECT COUNT(*) AS cnt FROM " . TBL_LOGBUCH_BEOS . " WHERE LogbuchID = ? AND BeoID = ?",
|
||||
[$logbuchId, $userId]
|
||||
);
|
||||
if ((int)($beoRow['cnt'] ?? 0) === 0) {
|
||||
respondError('Keine Berechtigung zum ' . $action . ' dieses Eintrags', 403);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getByKuerzel(string $kuerzel): ?array
|
||||
{
|
||||
return DB::one(
|
||||
"SELECT id, name, vorname, `kürzel`, pw, MustChangePassword, role FROM " . TBL_BEOS . " WHERE `kürzel` = ?",
|
||||
[$kuerzel]
|
||||
);
|
||||
}
|
||||
|
||||
public static function getByName(string $name): ?array
|
||||
{
|
||||
return DB::one(
|
||||
"SELECT id, name, vorname, `kürzel`, pw, MustChangePassword, role FROM " . TBL_BEOS . " WHERE LOWER(name) = LOWER(?)",
|
||||
[$name]
|
||||
);
|
||||
}
|
||||
|
||||
public static function updatePw(int $id, string $pwHash): void
|
||||
{
|
||||
DB::exec("UPDATE " . TBL_BEOS . " SET pw = ?, MustChangePassword = 0 WHERE id = ?", [$pwHash, $id]);
|
||||
}
|
||||
|
||||
public static function resetPw(int $id): void
|
||||
{
|
||||
DB::exec("UPDATE " . TBL_BEOS . " SET pw = NULL, MustChangePassword = 1 WHERE id = ?", [$id]);
|
||||
}
|
||||
|
||||
public static function listUsers(): array
|
||||
{
|
||||
$rows = DB::all(
|
||||
"SELECT id, `kürzel`, name, vorname, role, (pw IS NOT NULL) AS hasPw FROM " . TBL_BEOS . " ORDER BY name, vorname"
|
||||
);
|
||||
return array_map(function ($r) {
|
||||
$r['hasPw'] = (bool)$r['hasPw'];
|
||||
return $r;
|
||||
}, $rows);
|
||||
}
|
||||
|
||||
public static function listLogbuch(array $p): array
|
||||
{
|
||||
$kuppel = $p['kuppel'] ?? 'West';
|
||||
$limit = min((int)($p['limit'] ?? 10), 500);
|
||||
$offset = max(0, (int)($p['offset'] ?? 0));
|
||||
$month = $p['month'] ?? '';
|
||||
$order = strtoupper($p['order'] ?? 'DESC') === 'ASC' ? 'ASC' : 'DESC';
|
||||
$search = trim($p['search'] ?? '');
|
||||
|
||||
$baseSelect =
|
||||
"SELECT l.ID, l.Kuppel, l.ArtFuehrung,"
|
||||
. " DATE_FORMAT(l.Beginn, '%Y-%m-%dT%H:%i') AS Beginn,"
|
||||
. " DATE_FORMAT(l.Ende, '%Y-%m-%dT%H:%i') AS Ende,"
|
||||
. " l.Besucher, l.Bemerkungen, l.SonderName, l.Spende, l.SpendeBetrag,"
|
||||
. " l.WetterTemp, l.WetterFeuchte, l.WetterDruck,"
|
||||
. " l.created_by, l.created_at,"
|
||||
. " creator.kuerzel AS created_by_kuerzel,"
|
||||
. " GROUP_CONCAT(DISTINCT bk.kuerzel ORDER BY bk.kuerzel SEPARATOR ', ') AS BEOs,"
|
||||
. " GROUP_CONCAT(DISTINCT o.Name ORDER BY o.Name SEPARATOR ', ') AS Objekte"
|
||||
. " FROM " . TBL_LOGBUCH . " l"
|
||||
. " LEFT JOIN (SELECT id, `kürzel` AS kuerzel FROM " . TBL_BEOS . ") creator ON creator.id = l.created_by"
|
||||
. " LEFT JOIN " . TBL_LOGBUCH_BEOS . " lb ON lb.LogbuchID = l.ID"
|
||||
. " LEFT JOIN (SELECT id, `kürzel` AS kuerzel FROM " . TBL_BEOS . ") bk ON bk.id = lb.BeoID"
|
||||
. " LEFT JOIN " . TBL_LOGBUCH_OBJEKTE . " lo ON lo.LogbuchID = l.ID"
|
||||
. " LEFT JOIN " . TBL_OBJEKTE . " o ON o.ID = lo.ObjektID"
|
||||
. " WHERE l.Kuppel = ?";
|
||||
|
||||
$baseParams = [$kuppel];
|
||||
$monthCond = '';
|
||||
|
||||
if ($month && preg_match('/^\d{4}-\d{2}$/', $month)) {
|
||||
[$y, $m] = explode('-', $month);
|
||||
$y = (int)$y;
|
||||
$m = (int)$m;
|
||||
$start = sprintf('%d-%02d-01', $y, $m);
|
||||
$nextM = $m === 12 ? 1 : $m + 1;
|
||||
$nextY = $m === 12 ? $y + 1 : $y;
|
||||
$end = sprintf('%d-%02d-01', $nextY, $nextM);
|
||||
$monthCond = " AND l.Beginn >= ? AND l.Beginn < ?";
|
||||
$baseParams[] = $start;
|
||||
$baseParams[] = $end;
|
||||
}
|
||||
|
||||
if ($search !== '') {
|
||||
$pattern = '%' . $search . '%';
|
||||
$listSql = $baseSelect . $monthCond
|
||||
. " GROUP BY l.ID"
|
||||
. " HAVING (MAX(l.Bemerkungen) LIKE ? OR BEOs LIKE ? OR Objekte LIKE ?)"
|
||||
. " ORDER BY l.Beginn $order LIMIT $limit OFFSET $offset";
|
||||
$listParams = array_merge($baseParams, [$pattern, $pattern, $pattern]);
|
||||
|
||||
$countSql =
|
||||
"SELECT COUNT(*) AS total FROM ("
|
||||
. "SELECT l.ID FROM " . TBL_LOGBUCH . " l"
|
||||
. " LEFT JOIN " . TBL_LOGBUCH_BEOS . " lb ON lb.LogbuchID = l.ID"
|
||||
. " LEFT JOIN (SELECT id, `kürzel` AS kuerzel FROM " . TBL_BEOS . ") bk ON bk.id = lb.BeoID"
|
||||
. " LEFT JOIN " . TBL_LOGBUCH_OBJEKTE . " lo ON lo.LogbuchID = l.ID"
|
||||
. " LEFT JOIN " . TBL_OBJEKTE . " o ON o.ID = lo.ObjektID"
|
||||
. " WHERE l.Kuppel = ?" . ($monthCond ? $monthCond : '')
|
||||
. " GROUP BY l.ID"
|
||||
. " HAVING (MAX(l.Bemerkungen) LIKE ?"
|
||||
. " OR GROUP_CONCAT(DISTINCT bk.kuerzel ORDER BY bk.kuerzel SEPARATOR ', ') LIKE ?"
|
||||
. " OR GROUP_CONCAT(DISTINCT o.Name ORDER BY o.Name SEPARATOR ', ') LIKE ?)"
|
||||
. ") AS sub";
|
||||
$countParams = array_merge($baseParams, [$pattern, $pattern, $pattern]);
|
||||
} else {
|
||||
$listSql = $baseSelect . $monthCond
|
||||
. " GROUP BY l.ID ORDER BY l.Beginn $order LIMIT $limit OFFSET $offset";
|
||||
$listParams = $baseParams;
|
||||
|
||||
$countSql = "SELECT COUNT(*) AS total FROM " . TBL_LOGBUCH . " WHERE Kuppel = ?";
|
||||
$countParams = [$kuppel];
|
||||
if ($monthCond) {
|
||||
$countSql .= " AND Beginn >= ? AND Beginn < ?";
|
||||
$countParams = array_merge($countParams, array_slice($baseParams, 1));
|
||||
}
|
||||
}
|
||||
|
||||
$entries = DB::all($listSql, $listParams);
|
||||
$countRow = DB::one($countSql, $countParams);
|
||||
|
||||
return ['entries' => $entries, 'total' => (int)($countRow['total'] ?? 0)];
|
||||
}
|
||||
|
||||
private static function upsertObjekte(int $logbuchId, array $objekte, string $kategorie): void
|
||||
{
|
||||
foreach ($objekte as $obj) {
|
||||
$objektId = (int)($obj['ID'] ?? 0);
|
||||
if (!$objektId) {
|
||||
$existing = DB::one(
|
||||
"SELECT ID, Kategorie FROM " . TBL_OBJEKTE . " WHERE LOWER(Name) = LOWER(?)",
|
||||
[$obj['Name']]
|
||||
);
|
||||
if ($existing) {
|
||||
$objektId = (int)$existing['ID'];
|
||||
$currentKats = $existing['Kategorie'] ? explode(',', (string)$existing['Kategorie']) : [];
|
||||
if (!in_array($kategorie, $currentKats, true)) {
|
||||
$currentKats[] = $kategorie;
|
||||
sort($currentKats);
|
||||
DB::exec("UPDATE " . TBL_OBJEKTE . " SET Kategorie = ? WHERE ID = ?", [implode(',', $currentKats), $objektId]);
|
||||
}
|
||||
} else {
|
||||
DB::exec("INSERT INTO " . TBL_OBJEKTE . " (Name, Kategorie) VALUES (?, ?)", [$obj['Name'], $kategorie]);
|
||||
$objektId = (int)DB::insertId();
|
||||
}
|
||||
}
|
||||
DB::exec("UPDATE " . TBL_OBJEKTE . " SET LastUsed = NOW() WHERE ID = ?", [$objektId]);
|
||||
DB::exec(
|
||||
"INSERT INTO " . TBL_LOGBUCH_OBJEKTE . " (LogbuchID, ObjektID) VALUES (?, ?)",
|
||||
[$logbuchId, $objektId]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/** Spende nur bei Sonderführung; Betrag nur bei 'bar'. Rückgabe: [Spende, SpendeBetrag] */
|
||||
private static function spendeValues(array $p): array
|
||||
{
|
||||
if (($p['ArtFuehrung'] ?? '') !== 'SF') return [null, null];
|
||||
$art = in_array($p['Spende'] ?? null, ['bar', 'ueberw', 'kasse', 'keine'], true)
|
||||
? $p['Spende']
|
||||
: null;
|
||||
$betrag = ($art === 'bar' && isset($p['SpendeBetrag']))
|
||||
? round((float)$p['SpendeBetrag'], 2)
|
||||
: null;
|
||||
return [$art, $betrag];
|
||||
}
|
||||
|
||||
public static function createLogbuch(array $p): int
|
||||
{
|
||||
$wetter = is_array($p['Wetter'] ?? null) ? $p['Wetter'] : [];
|
||||
[$spende, $spendeBetrag] = self::spendeValues($p);
|
||||
$db = DB::conn();
|
||||
$db->beginTransaction();
|
||||
try {
|
||||
DB::exec(
|
||||
"INSERT INTO " . TBL_LOGBUCH
|
||||
. " (Kuppel, ArtFuehrung, SonderName, Spende, SpendeBetrag, Beginn, Ende, Besucher,"
|
||||
. " Bemerkungen, WetterTemp, WetterFeuchte, WetterDruck, created_by)"
|
||||
. " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
[
|
||||
$p['Kuppel'],
|
||||
$p['ArtFuehrung'],
|
||||
$p['SonderName'] ?? null,
|
||||
$spende,
|
||||
$spendeBetrag,
|
||||
$p['Beginn'],
|
||||
$p['Ende'],
|
||||
(int)($p['Besucher'] ?? 0),
|
||||
isset($p['Bemerkungen']) ? substr((string)$p['Bemerkungen'], 0, 500) : null,
|
||||
isset($wetter['temp']) ? (float)$wetter['temp'] : null,
|
||||
isset($wetter['feuchte']) ? (float)$wetter['feuchte'] : null,
|
||||
isset($wetter['druck']) ? (float)$wetter['druck'] : null,
|
||||
(int)$p['created_by'],
|
||||
]
|
||||
);
|
||||
$logbuchId = (int)DB::insertId();
|
||||
|
||||
foreach (($p['beoIds'] ?? []) as $beoId) {
|
||||
DB::exec(
|
||||
"INSERT INTO " . TBL_LOGBUCH_BEOS . " (LogbuchID, BeoID) VALUES (?, ?)",
|
||||
[$logbuchId, (int)$beoId]
|
||||
);
|
||||
}
|
||||
|
||||
$kategorie = ($p['ArtFuehrung'] === 'SonF') ? 'sonne' : 'stern';
|
||||
self::upsertObjekte($logbuchId, $p['objekte'] ?? [], $kategorie);
|
||||
|
||||
$db->commit();
|
||||
return $logbuchId;
|
||||
} catch (Throwable $e) {
|
||||
$db->rollBack();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public static function updateLogbuch(int $id, int $userId, string $userRole, array $p): void
|
||||
{
|
||||
self::checkAccess($id, $userId, $userRole, 'Ändern');
|
||||
|
||||
$wetter = is_array($p['Wetter'] ?? null) ? $p['Wetter'] : [];
|
||||
[$spende, $spendeBetrag] = self::spendeValues($p);
|
||||
$db = DB::conn();
|
||||
$db->beginTransaction();
|
||||
try {
|
||||
DB::exec(
|
||||
"UPDATE " . TBL_LOGBUCH
|
||||
. " SET Kuppel=?, ArtFuehrung=?, SonderName=?, Spende=?, SpendeBetrag=?, Beginn=?, Ende=?, Besucher=?,"
|
||||
. " Bemerkungen=?, WetterTemp=?, WetterFeuchte=?, WetterDruck=? WHERE ID=?",
|
||||
[
|
||||
$p['Kuppel'],
|
||||
$p['ArtFuehrung'],
|
||||
$p['SonderName'] ?? null,
|
||||
$spende,
|
||||
$spendeBetrag,
|
||||
$p['Beginn'],
|
||||
$p['Ende'],
|
||||
(int)($p['Besucher'] ?? 0),
|
||||
isset($p['Bemerkungen']) ? substr((string)$p['Bemerkungen'], 0, 500) : null,
|
||||
isset($wetter['temp']) ? (float)$wetter['temp'] : null,
|
||||
isset($wetter['feuchte']) ? (float)$wetter['feuchte'] : null,
|
||||
isset($wetter['druck']) ? (float)$wetter['druck'] : null,
|
||||
$id,
|
||||
]
|
||||
);
|
||||
|
||||
DB::exec("DELETE FROM " . TBL_LOGBUCH_BEOS . " WHERE LogbuchID = ?", [$id]);
|
||||
DB::exec("DELETE FROM " . TBL_LOGBUCH_OBJEKTE . " WHERE LogbuchID = ?", [$id]);
|
||||
|
||||
foreach (($p['beoIds'] ?? []) as $beoId) {
|
||||
DB::exec(
|
||||
"INSERT INTO " . TBL_LOGBUCH_BEOS . " (LogbuchID, BeoID) VALUES (?, ?)",
|
||||
[$id, (int)$beoId]
|
||||
);
|
||||
}
|
||||
|
||||
$kategorie = ($p['ArtFuehrung'] === 'SonF') ? 'sonne' : 'stern';
|
||||
self::upsertObjekte($id, $p['objekte'] ?? [], $kategorie);
|
||||
|
||||
$db->commit();
|
||||
} catch (Throwable $e) {
|
||||
$db->rollBack();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public static function deleteLogbuch(int $id, int $userId, string $userRole): void
|
||||
{
|
||||
self::checkAccess($id, $userId, $userRole, 'Löschen');
|
||||
DB::exec("DELETE FROM " . TBL_LOGBUCH . " WHERE ID = ?", [$id]);
|
||||
}
|
||||
|
||||
public static function listBeos(): array
|
||||
{
|
||||
return DB::all(
|
||||
"SELECT id AS ID, `kürzel` AS Kuerzel,"
|
||||
. " CONCAT(IFNULL(vorname, ''), IF(vorname IS NOT NULL, ' ', ''), name) AS Name"
|
||||
. " FROM " . TBL_BEOS
|
||||
. " WHERE `kürzel` IS NOT NULL AND FIND_IN_SET('guide', role) > 0"
|
||||
. " ORDER BY name ASC"
|
||||
);
|
||||
}
|
||||
|
||||
// Alle BEOs mit Adressfeldern (für die km-Berechnung zur Sternwarte Welzheim)
|
||||
public static function listBeoAdressen(): array
|
||||
{
|
||||
return DB::all(
|
||||
"SELECT id AS ID, `kürzel` AS Kuerzel, name AS Name,"
|
||||
. " adresse AS Adresse, plz AS Plz, ort AS Ort, km AS Km"
|
||||
. " FROM " . TBL_BEOS
|
||||
. " ORDER BY name ASC"
|
||||
);
|
||||
}
|
||||
|
||||
// Straßenentfernung (km) eines BEOs zur Sternwarte setzen (NULL = unbekannt)
|
||||
public static function updateBeoKm(int $id, ?float $km): void
|
||||
{
|
||||
DB::exec("UPDATE " . TBL_BEOS . " SET km = ? WHERE id = ?", [$km, $id]);
|
||||
}
|
||||
|
||||
public static function listObjekte(string $kategorie = 'stern'): array
|
||||
{
|
||||
return DB::all("SELECT ID, Name FROM " . TBL_OBJEKTE . " WHERE FIND_IN_SET(?, Kategorie) > 0 ORDER BY LastUsed DESC LIMIT 100", [$kategorie]);
|
||||
}
|
||||
|
||||
public static function listObjekteAdmin(): array
|
||||
{
|
||||
return DB::all("SELECT ID, Name, LastUsed, Kategorie FROM " . TBL_OBJEKTE . " ORDER BY Name ASC");
|
||||
}
|
||||
|
||||
public static function createObjekt(string $name, string $kategorie = 'stern'): int
|
||||
{
|
||||
DB::exec("INSERT INTO " . TBL_OBJEKTE . " (Name, Kategorie) VALUES (?, ?)", [$name, $kategorie]);
|
||||
return (int)DB::insertId();
|
||||
}
|
||||
|
||||
public static function updateObjekt(int $id, string $name, ?string $kategorie = null): void
|
||||
{
|
||||
if ($kategorie !== null) {
|
||||
DB::exec("UPDATE " . TBL_OBJEKTE . " SET Name = ?, Kategorie = ? WHERE ID = ?", [$name, $kategorie, $id]);
|
||||
} else {
|
||||
DB::exec("UPDATE " . TBL_OBJEKTE . " SET Name = ? WHERE ID = ?", [$name, $id]);
|
||||
}
|
||||
}
|
||||
|
||||
public static function deleteObjekt(int $id): void
|
||||
{
|
||||
DB::exec("DELETE FROM " . TBL_OBJEKTE . " WHERE ID = ?", [$id]);
|
||||
}
|
||||
|
||||
public static function fahrkosten(string $ab, string $bis): array
|
||||
{
|
||||
return DB::all(
|
||||
"SELECT b.id AS ID, b.`kürzel` AS Kuerzel,"
|
||||
. " CONCAT(IFNULL(b.vorname, ''), IF(b.vorname IS NOT NULL, ' ', ''), b.name) AS Name,"
|
||||
. " b.km AS Km,"
|
||||
. " COUNT(DISTINCT l.ID) AS Anzahl"
|
||||
. " FROM " . TBL_BEOS . " b"
|
||||
. " JOIN " . TBL_LOGBUCH_BEOS . " lb ON lb.BeoID = b.id"
|
||||
. " JOIN " . TBL_LOGBUCH . " l ON l.ID = lb.LogbuchID"
|
||||
. " WHERE l.Beginn >= ? AND l.Beginn <= ?"
|
||||
. " GROUP BY b.id, b.`kürzel`, b.name, b.vorname, b.km"
|
||||
. " ORDER BY b.name ASC",
|
||||
[$ab . ' 00:00:00', $bis . ' 23:59:59']
|
||||
);
|
||||
}
|
||||
|
||||
public static function statistik(int $year): array
|
||||
{
|
||||
$monthly = DB::all(
|
||||
"SELECT MONTH(Beginn) AS monat,"
|
||||
. " COUNT(CASE WHEN ArtFuehrung IN ('RF','SF','SonF','PrF') THEN 1 END) AS tageFuehrungen,"
|
||||
. " COUNT(CASE WHEN ArtFuehrung = 'Beob' THEN 1 END) AS tageBeob,"
|
||||
. " COUNT(CASE WHEN ArtFuehrung = 'TD' THEN 1 END) AS tageTD,"
|
||||
. " COUNT(CASE WHEN ArtFuehrung = 'Sonst' THEN 1 END) AS tageSonst,"
|
||||
. " COUNT(CASE WHEN ArtFuehrung = 'BEOS' THEN 1 END) AS tageBEOS,"
|
||||
. " COUNT(CASE WHEN ArtFuehrung = 'ToT' THEN 1 END) AS tagesToT,"
|
||||
. " COUNT(CASE WHEN ArtFuehrung IN ('RF','SF','SonF','PrF','Beob','TD','Sonst','BEOS','ToT') THEN 1 END) AS tageGesamt,"
|
||||
. " SUM(CASE WHEN ArtFuehrung = 'RF' THEN Besucher ELSE 0 END) AS besucherRF,"
|
||||
. " SUM(CASE WHEN ArtFuehrung = 'SF' THEN Besucher ELSE 0 END) AS besucherSF,"
|
||||
. " SUM(CASE WHEN ArtFuehrung = 'SonF' THEN Besucher ELSE 0 END) AS besucherSonF,"
|
||||
. " SUM(CASE WHEN ArtFuehrung = 'PrF' THEN Besucher ELSE 0 END) AS besucherPrF,"
|
||||
. " SUM(CASE WHEN ArtFuehrung = 'ToT' THEN Besucher ELSE 0 END) AS besucherToT,"
|
||||
. " SUM(CASE WHEN ArtFuehrung IN ('RF','SF','SonF','PrF','ToT') THEN Besucher ELSE 0 END) AS besucherGesamt"
|
||||
. " FROM " . TBL_LOGBUCH . " WHERE YEAR(Beginn) = ?"
|
||||
. " GROUP BY MONTH(Beginn) ORDER BY monat",
|
||||
[$year]
|
||||
);
|
||||
|
||||
$monthly = array_map(function ($r) {
|
||||
return array_map(function ($v) { return is_numeric($v) ? (int)$v : $v; }, $r);
|
||||
}, $monthly);
|
||||
|
||||
$cumRow = DB::one(
|
||||
"SELECT SUM(CASE WHEN ArtFuehrung IN ('RF','SF','SonF','PrF','ToT') THEN Besucher ELSE 0 END) AS total"
|
||||
. " FROM " . TBL_LOGBUCH . " WHERE YEAR(Beginn) = ?",
|
||||
[$year]
|
||||
);
|
||||
$tageRow = DB::one(
|
||||
"SELECT COUNT(*) AS tage FROM " . TBL_LOGBUCH
|
||||
. " WHERE YEAR(Beginn) = ? AND ArtFuehrung IN ('RF','SF','SonF','PrF','Beob','TD','Sonst','BEOS','ToT')",
|
||||
[$year]
|
||||
);
|
||||
|
||||
return [
|
||||
'monthly' => $monthly,
|
||||
'cumulative' => (int)($cumRow['total'] ?? 0),
|
||||
'tage' => (int)($tageRow['tage'] ?? 0),
|
||||
'year' => $year,
|
||||
];
|
||||
}
|
||||
|
||||
public static function backupData(): array
|
||||
{
|
||||
$logbuchTables = [TBL_LOGBUCH, TBL_LOGBUCH_BEOS, TBL_LOGBUCH_OBJEKTE, TBL_OBJEKTE];
|
||||
$db = DB::conn();
|
||||
$tables = [];
|
||||
foreach ($logbuchTables as $name) {
|
||||
$createStmt = $db->query("SHOW CREATE TABLE `$name`");
|
||||
$createRow = $createStmt ? $createStmt->fetch(PDO::FETCH_ASSOC) : false;
|
||||
$createSql = $createRow ? array_values($createRow)[1] : '';
|
||||
|
||||
$rowsStmt = $db->query("SELECT * FROM `$name`");
|
||||
$rows = $rowsStmt ? $rowsStmt->fetchAll(PDO::FETCH_ASSOC) : [];
|
||||
|
||||
$tables[] = ['name' => $name, 'createSql' => $createSql, 'rows' => $rows];
|
||||
}
|
||||
return ['tables' => $tables];
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Kalender Repository ----
|
||||
class RepoKalender
|
||||
{
|
||||
@@ -1103,6 +1670,27 @@ class Commands
|
||||
'UPDATETLNFD' => 'Teilnehmer-Datum aktualisieren',
|
||||
'SEND_MAIL_HTML' => 'Mail versenden (Text)',
|
||||
'GET_ALLTEILN' => 'Alle Teilnehmer ab Datum',
|
||||
// Logbuch-Befehle
|
||||
'LB_AUTH_KUERZEL' => 'Logbuch: BEO-Auth nach Kürzel',
|
||||
'LB_AUTH_NAME' => 'Logbuch: BEO-Auth nach Name',
|
||||
'LB_UPDATE_PW' => 'Logbuch: Passwort setzen',
|
||||
'LB_RESET_PW' => 'Logbuch: Passwort zurücksetzen',
|
||||
'LB_LIST_USERS' => 'Logbuch: Alle Benutzer',
|
||||
'LB_GET_BEO_ADRESSEN' => 'Logbuch: BEOs mit Adressen (km-Berechnung)',
|
||||
'LB_UPDATE_BEO_KM' => 'Logbuch: km-Entfernung eines BEOs setzen',
|
||||
'LB_LIST_LOGBUCH' => 'Logbuch: Einträge abrufen',
|
||||
'LB_CREATE_LOGBUCH' => 'Logbuch: Eintrag anlegen',
|
||||
'LB_UPDATE_LOGBUCH' => 'Logbuch: Eintrag ändern',
|
||||
'LB_DELETE_LOGBUCH' => 'Logbuch: Eintrag löschen',
|
||||
'LB_GET_BEOS' => 'Logbuch: Guide-BEOs abrufen',
|
||||
'LB_GET_OBJEKTE' => 'Logbuch: Objekte (zuletzt genutzt)',
|
||||
'LB_CREATE_OBJEKT' => 'Logbuch: Objekt anlegen',
|
||||
'LB_UPDATE_OBJEKT' => 'Logbuch: Objekt umbenennen',
|
||||
'LB_DELETE_OBJEKT' => 'Logbuch: Objekt löschen',
|
||||
'LB_LIST_OBJEKTE_ADMIN' => 'Logbuch: Alle Objekte (Admin)',
|
||||
'LB_FAHRKOSTEN' => 'Logbuch: Fahrkosten-Auswertung',
|
||||
'LB_STATISTIK' => 'Logbuch: Jahresstatistik',
|
||||
'LB_BACKUP_DATA' => 'Logbuch: Backup-Daten (Schema + Rows)',
|
||||
'LIST_COMMANDS' => 'Liste aller Kommandos'
|
||||
];
|
||||
}
|
||||
@@ -1229,6 +1817,9 @@ try {
|
||||
case 'GET_ONEBEO':
|
||||
$r = RepoBeos::getByName($input['name']);
|
||||
respond($r ?: ['error' => 'Not found']);
|
||||
case 'GET_ONEBEOPW':
|
||||
$r = RepoBeos::getByNamePW($input['kurz'], $input['what']);
|
||||
respond($r ?: ['error' => 'Not found']);
|
||||
|
||||
// Sonderführungen
|
||||
case 'GET_ONE':
|
||||
@@ -1282,7 +1873,8 @@ try {
|
||||
case 'SENDMAILZUSAGE':
|
||||
$info = RepoSoFue::getById((int)$input['id']);
|
||||
if (!$info) respondError('Führung nicht gefunden', 404);
|
||||
$ma = RepoBeos::getByName($input['mitarbeiter']);
|
||||
$ma_first = trim(explode(',', $input['mitarbeiter'])[0]);
|
||||
$ma = RepoBeos::getByName($ma_first);
|
||||
$ma_name = $ma['name'];
|
||||
$ma_vorname = $ma['vorname'];
|
||||
$gender = $ma['gender'] == 'm';
|
||||
@@ -1464,19 +2056,29 @@ Spendenbescheinigung: \t" . $info['spende'] . "
|
||||
|
||||
// Statistik - Jahre
|
||||
case 'GET_YEARS':
|
||||
respond(RepoStatistikJahre::getYearList());
|
||||
$fromSta = RepoStatistikJahre::getYearList();
|
||||
$fromLog = RepoLogbuch::yearList();
|
||||
$all = array_values(array_unique(array_merge($fromLog, $fromSta)));
|
||||
rsort($all);
|
||||
respond($all);
|
||||
case 'GET_ONE_A':
|
||||
$datum = $input['datum'] ?? respondError('datum missing');
|
||||
$datum = $input['datum'] ?? $_GET['datum'] ?? null;
|
||||
if (!$datum) respondError('datum missing');
|
||||
$year = (int)substr($datum, 0, 4);
|
||||
if ($year >= 2026) {
|
||||
respond(RepoLogbuch::getByMonth($datum));
|
||||
}
|
||||
$result = RepoStatistikJahre::getByDate($datum);
|
||||
if ($result) {
|
||||
// Add bemG from Gesamt
|
||||
$year = substr($datum, 0, 4);
|
||||
$gesamt = RepoStatistikGesamt::getByYear((int)$year);
|
||||
$gesamt = RepoStatistikGesamt::getByYear($year);
|
||||
$result['bemG'] = $gesamt['bemerkung'] ?? '';
|
||||
}
|
||||
respond($result ?: ['error' => 'Not found']);
|
||||
respond($result);
|
||||
case 'GET_ALL_A':
|
||||
$year = (int)($input['jahr'] ?? date('Y'));
|
||||
$year = (int)($input['jahr'] ?? $_GET['jahr'] ?? date('Y'));
|
||||
if ($year >= 2026) {
|
||||
respond(RepoLogbuch::getByYear($year));
|
||||
}
|
||||
respond(RepoStatistikJahre::getByYear($year));
|
||||
case 'CRUP_A':
|
||||
if (!isset($input['toInsert'])) respondError('toInsert missing');
|
||||
@@ -1484,11 +2086,43 @@ Spendenbescheinigung: \t" . $info['spende'] . "
|
||||
|
||||
// Statistik - Gesamt
|
||||
case 'GET_ALL_G':
|
||||
respond(RepoStatistikGesamt::getAll());
|
||||
$gesamt = RepoStatistikGesamt::getAll();
|
||||
// Für Jahre >= 2026: Daten live aus logbuch statt aus StatistikGesamt
|
||||
$logSummary = RepoLogbuch::yearlySummary();
|
||||
$logMap = [];
|
||||
foreach ($logSummary as $r) { if ((int)$r['jahr'] >= 2026) $logMap[(int)$r['jahr']] = $r; }
|
||||
$merged = [];
|
||||
$existingYears = [];
|
||||
foreach ($gesamt['data'] as $r) {
|
||||
$j = (int)$r['jahr'];
|
||||
$existingYears[] = $j;
|
||||
$merged[] = ($j >= 2026 && isset($logMap[$j])) ? $logMap[$j] : $r;
|
||||
}
|
||||
foreach ($logMap as $j => $r) {
|
||||
if (!in_array($j, $existingYears)) { $merged[] = $r; }
|
||||
}
|
||||
usort($merged, function($a, $b) { return (int)$b['jahr'] - (int)$a['jahr']; });
|
||||
$gesamt['data'] = $merged;
|
||||
$gesamt['sumB'] = array_sum(array_column($merged, 'besucher'));
|
||||
$gesamt['sumA'] = array_sum(array_column($merged, 'aktivitaeten'));
|
||||
// lastDate auf das neueste Jahr (ggf. aus logbuch) aktualisieren
|
||||
if (!empty($logMap)) {
|
||||
$lbLastYear = max(array_keys($logMap));
|
||||
if ($lbLastYear > (int)$gesamt['lastDate']['lastYear']) {
|
||||
$lbYearData = RepoLogbuch::getByYear($lbLastYear);
|
||||
$gesamt['lastDate'] = ['lastYear' => $lbLastYear, 'fullYear' => $lbYearData['data']];
|
||||
}
|
||||
}
|
||||
respond($gesamt);
|
||||
case 'GET_ONE_G':
|
||||
$year = (int)($input['jahr'] ?? date('Y'));
|
||||
$result = RepoStatistikGesamt::getByYear($year);
|
||||
respond($result ?: ['error' => 'Not found']);
|
||||
if ($year >= 2026) {
|
||||
$rows = RepoLogbuch::yearlySummary();
|
||||
$result = null;
|
||||
foreach ($rows as $r) { if ((int)$r['jahr'] === $year) { $result = $r; break; } }
|
||||
respond($result);
|
||||
}
|
||||
respond(RepoStatistikGesamt::getByYear($year));
|
||||
case 'CRUP_G':
|
||||
if (!isset($input['toInsert'])) respondError('toInsert missing');
|
||||
respond(RepoStatistikGesamt::createOrUpdate($input['toInsert']));
|
||||
@@ -1536,6 +2170,92 @@ Spendenbescheinigung: \t" . $info['spende'] . "
|
||||
$sql = "SELECT * FROM " . TBL_ANMELD . " WHERE fdatum >= ? ORDER BY fid ASC";
|
||||
respond(DB::all($sql, [$fdatum]));
|
||||
|
||||
// ---- Logbuch ----
|
||||
case 'LB_AUTH_KUERZEL':
|
||||
$kuerzel = $input['kuerzel'] ?? respondError('kuerzel missing');
|
||||
respond(['beo' => RepoLogbuch::getByKuerzel((string)$kuerzel)]);
|
||||
case 'LB_AUTH_NAME':
|
||||
$name = $input['name'] ?? respondError('name missing');
|
||||
respond(['beo' => RepoLogbuch::getByName((string)$name)]);
|
||||
case 'LB_UPDATE_PW':
|
||||
$id = (int)($input['id'] ?? respondError('id missing'));
|
||||
$pw = $input['pw'] ?? respondError('pw missing');
|
||||
RepoLogbuch::updatePw($id, (string)$pw);
|
||||
respond(['ok' => true]);
|
||||
case 'LB_RESET_PW':
|
||||
$id = (int)($input['id'] ?? respondError('id missing'));
|
||||
RepoLogbuch::resetPw($id);
|
||||
respond(['ok' => true]);
|
||||
case 'LB_LIST_USERS':
|
||||
respond(RepoLogbuch::listUsers());
|
||||
case 'LB_LIST_LOGBUCH':
|
||||
respond(RepoLogbuch::listLogbuch($input));
|
||||
case 'LB_CREATE_LOGBUCH':
|
||||
$newId = RepoLogbuch::createLogbuch($input);
|
||||
respond(['id' => $newId], 201);
|
||||
case 'LB_UPDATE_LOGBUCH':
|
||||
$id = (int)($input['id'] ?? respondError('id missing'));
|
||||
$userId = (int)($input['user_id'] ?? respondError('user_id missing'));
|
||||
$userRole = (string)($input['user_role'] ?? '');
|
||||
RepoLogbuch::updateLogbuch($id, $userId, $userRole, $input);
|
||||
respond(['ok' => true]);
|
||||
case 'LB_DELETE_LOGBUCH':
|
||||
$id = (int)($input['id'] ?? respondError('id missing'));
|
||||
$userId = (int)($input['user_id'] ?? respondError('user_id missing'));
|
||||
$userRole = (string)($input['user_role'] ?? '');
|
||||
RepoLogbuch::deleteLogbuch($id, $userId, $userRole);
|
||||
respond(['ok' => true]);
|
||||
case 'LB_GET_BEOS':
|
||||
respond(RepoLogbuch::listBeos());
|
||||
case 'LB_GET_BEO_ADRESSEN':
|
||||
respond(RepoLogbuch::listBeoAdressen());
|
||||
case 'LB_UPDATE_BEO_KM':
|
||||
$id = (int)($input['id'] ?? respondError('id missing'));
|
||||
$km = (array_key_exists('km', $input) && $input['km'] !== null && $input['km'] !== '')
|
||||
? (float)$input['km'] : null;
|
||||
RepoLogbuch::updateBeoKm($id, $km);
|
||||
respond(['ok' => true]);
|
||||
case 'LB_GET_OBJEKTE':
|
||||
$kategorie = in_array($input['kategorie'] ?? '', ['stern', 'sonne']) ? (string)$input['kategorie'] : 'stern';
|
||||
respond(RepoLogbuch::listObjekte($kategorie));
|
||||
case 'LB_CREATE_OBJEKT':
|
||||
$name = trim((string)($input['name'] ?? respondError('name missing')));
|
||||
if ($name === '') respondError('name darf nicht leer sein');
|
||||
$kategorie = in_array($input['kategorie'] ?? '', ['stern', 'sonne']) ? (string)$input['kategorie'] : 'stern';
|
||||
$newId = RepoLogbuch::createObjekt($name, $kategorie);
|
||||
respond(['ID' => $newId, 'Name' => $name, 'Kategorie' => $kategorie], 201);
|
||||
case 'LB_UPDATE_OBJEKT':
|
||||
$id = (int)($input['id'] ?? respondError('id missing'));
|
||||
$name = trim((string)($input['name'] ?? respondError('name missing')));
|
||||
if ($name === '') respondError('name darf nicht leer sein');
|
||||
$kategorie = in_array($input['kategorie'] ?? '', ['stern', 'sonne']) ? (string)$input['kategorie'] : null;
|
||||
RepoLogbuch::updateObjekt($id, $name, $kategorie);
|
||||
respond(['ID' => $id, 'Name' => $name]);
|
||||
case 'LB_DELETE_OBJEKT':
|
||||
$id = (int)($input['id'] ?? respondError('id missing'));
|
||||
RepoLogbuch::deleteObjekt($id);
|
||||
respond(['ok' => true]);
|
||||
case 'LB_LIST_OBJEKTE_ADMIN':
|
||||
respond(RepoLogbuch::listObjekteAdmin());
|
||||
case 'LB_FAHRKOSTEN':
|
||||
$ab = $input['ab'] ?? respondError('ab missing');
|
||||
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', (string)$ab)) respondError('ab muss YYYY-MM-DD sein');
|
||||
$bis = $input['bis'] ?? date('Y-m-d');
|
||||
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', (string)$bis)) respondError('bis muss YYYY-MM-DD sein');
|
||||
respond(RepoLogbuch::fahrkosten((string)$ab, (string)$bis));
|
||||
case 'LB_STATISTIK':
|
||||
$year = (int)($input['year'] ?? date('Y'));
|
||||
respond(RepoLogbuch::statistik($year));
|
||||
case 'LB_BACKUP_DATA':
|
||||
respond(RepoLogbuch::backupData());
|
||||
|
||||
case 'LB_UNUSED_OBJEKTE':
|
||||
respond(DB::all(
|
||||
"SELECT o.ID, o.Name, o.LastUsed FROM " . TBL_OBJEKTE . " o" .
|
||||
" LEFT JOIN " . TBL_LOGBUCH_OBJEKTE . " lo ON lo.ObjektID = o.ID" .
|
||||
" WHERE lo.ObjektID IS NULL ORDER BY o.Name"
|
||||
));
|
||||
|
||||
case 'LIST_COMMANDS':
|
||||
respond(['commands' => Commands::MAP, 'count' => count(Commands::MAP)]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user