diff --git a/sternwarte/DB4js_all.php b/sternwarte/DB4js_all.php index b302fdf..65f7bb7 100644 --- a/sternwarte/DB4js_all.php +++ b/sternwarte/DB4js_all.php @@ -601,6 +601,17 @@ class RepoSoFue [$beginn, $beginn] ); } + /** Kommende zugesagte Sonderführungen ab heute — Grundlage des Führungen-Tabs im Logbuch. */ + public static function kommendeTermine(int $limit = 50): array + { + $limit = max(1, min($limit, 200)); + return DB::all( + "SELECT id, wtermin, verein, name, vorname, anzahl, mitarbeiter, bemerkung" + . " FROM " . TBL_SOFUE + . " WHERE deleted=0 AND status=2 AND DATE(wtermin) >= CURDATE()" + . " ORDER BY wtermin ASC LIMIT " . $limit + ); + } public static function getAfterDate(string $date) { // Accept YYYYMMDD or YYYY-MM-DD; compare by DATE(wtermin) @@ -723,6 +734,49 @@ class RepoSoFue return DB::exec("UPDATE " . TBL_SOFUE . " SET deleted=1 WHERE id=?", [$id]); } + /** Hängt eine datierte Zeile an die Bemerkung an, statt sie zu ersetzen. */ + private static function notizAnhaengen(?string $alt, string $zeile): string + { + $alt = trim((string)$alt); + return self::cp1252Safe($alt === '' ? $zeile : $alt . "\n" . $zeile, 65000); + } + + /** Sonderführung ist ausgefallen: status=3, Termin bleibt stehen. */ + public static function absagen(int $id, string $grund, string $kuerzel): bool + { + $satz = self::getById($id); + if (!$satz || (int)($satz['deleted'] ?? 0) === 1) return false; + + $zeile = date('d.m.Y') . ' ' . $kuerzel . ': Führung ausgefallen' + . ($grund !== '' ? ' — ' . $grund : ''); + DB::exec( + "UPDATE " . TBL_SOFUE . " SET status=3, stattgefunden=0, erledigt_datum=CURDATE()," + . " bemerkung=? WHERE id=?", + [self::notizAnhaengen($satz['bemerkung'] ?? '', $zeile), $id] + ); + return true; + } + + /** + * Sonderführung wird verschoben: der bisherige Termin wandert nach 'verlegt', + * der Status bleibt zugesagt. Die vollständige Kette steht in 'bemerkung'. + */ + public static function verschieben(int $id, string $neuerTermin, string $grund, string $kuerzel): bool + { + $satz = self::getById($id); + if (!$satz || (int)($satz['deleted'] ?? 0) === 1) return false; + + $zeile = date('d.m.Y') . ' ' . $kuerzel . ': verschoben vom ' + . date('d.m.Y H:i', strtotime((string)$satz['wtermin'])) . ' auf ' + . date('d.m.Y H:i', strtotime($neuerTermin)) + . ($grund !== '' ? ' — ' . $grund : ''); + DB::exec( + "UPDATE " . TBL_SOFUE . " SET verlegt=?, wtermin=?, bemerkung=? WHERE id=?", + [$satz['wtermin'], $neuerTermin, self::notizAnhaengen($satz['bemerkung'] ?? '', $zeile), $id] + ); + return true; + } + /** * Spende aus dem Logbuch als bezahlt-Text — gleiche Schreibweise wie das * beoanswer-Formular (beoanswer/src/components/LastButtons.jsx). @@ -1761,6 +1815,9 @@ class Commands '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_SOFUE_TERMINE' => 'Logbuch: kommende zugesagte Sonderführungen', + 'LB_SOFUE_ABSAGEN' => 'Logbuch: Sonderführung als ausgefallen markieren', + 'LB_SOFUE_VERSCHIEBEN' => 'Logbuch: Sonderführung auf neuen Termin verschieben', 'LB_CREATE_LOGBUCH' => 'Logbuch: Eintrag anlegen (trägt Sonderführungen in SoFue2 nach)', 'LB_UPDATE_LOGBUCH' => 'Logbuch: Eintrag ändern (trägt Sonderführungen in SoFue2 nach)', 'LB_DELETE_LOGBUCH' => 'Logbuch: Eintrag löschen', @@ -2289,6 +2346,24 @@ Spendenbescheinigung: \t" . $info['spende'] . " $userRole = (string)($input['user_role'] ?? ''); RepoLogbuch::deleteLogbuch($id, $userId, $userRole); respond(['ok' => true]); + case 'LB_SOFUE_TERMINE': + respond(RepoSoFue::kommendeTermine((int)($input['limit'] ?? 50))); + case 'LB_SOFUE_ABSAGEN': + if (!isset($input['id'])) respondError('id missing'); + if (!RepoSoFue::absagen((int)$input['id'], trim((string)($input['grund'] ?? '')), (string)($input['kuerzel'] ?? ''))) { + respondError('Führung nicht gefunden', 404); + } + respond(['ok' => true]); + case 'LB_SOFUE_VERSCHIEBEN': + if (!isset($input['id'])) respondError('id missing'); + $termin = (string)($input['termin'] ?? ''); + if (!preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:00$/', $termin)) { + respondError('termin ungültig (erwartet YYYY-MM-DD HH:MM:00)'); + } + if (!RepoSoFue::verschieben((int)$input['id'], $termin, trim((string)($input['grund'] ?? '')), (string)($input['kuerzel'] ?? ''))) { + respondError('Führung nicht gefunden', 404); + } + respond(['ok' => true]); case 'LB_GET_BEOS': respond(RepoLogbuch::listBeos()); case 'LB_GET_BEO_ADRESSEN':