verlangeAnmeldung(); $this->render('verwaltung/index.php', [ 'titel' => 'Verwaltung', 'zahlen' => [ 'kategorien' => Kategorie::anzahl(), 'einnahmen' => Kategorie::anzahl('einnahme'), 'ausgaben' => Kategorie::anzahl('ausgabe'), 'klassen' => Klasse::anzahl(), 'konten' => Konto::anzahl(), 'kontengruppen' => count(Kontengruppe::alle()), 'bankinstitute' => Bankinstitut::anzahl(), 'reihen' => count(RegelmaessigeBuchung::alle(true)), 'erinnerungen' => Erinnerung::anzahlOffen(), 'vertraege' => count(Vertrag::alle(true)), 'fristen' => count(Vertrag::fristenLaufenAb(90)), 'bargeld' => count(Kategorie::bargeldAuswahl()), 'adressen' => Adresse::anzahl(), ], 'bargeldAktiv' => BargeldAbgleich::eingerichtet(), ]); } public function klassen(): void { $this->verlangeAnmeldung(); $this->render('verwaltung/klassen.php', [ 'titel' => 'Klassen', 'klassen' => Klasse::alle(), ]); } public function klasseAnlegen(): void { $this->verlangeAnmeldung(); try { Klasse::anlegen($this->post('name'), $this->post('beschreibung')); } catch (\Throwable $e) { View::redirect('/verwaltung/klassen', $e->getMessage(), 'fehler'); return; } View::redirect('/verwaltung/klassen', 'Klasse angelegt.'); } /** @param array $params */ public function klasseSpeichern(array $params): void { $this->verlangeAnmeldung(); try { Klasse::speichern( (int)$params['id'], $this->post('name'), $this->post('beschreibung'), isset($_POST['aktiv']) ); } catch (\Throwable $e) { View::redirect('/verwaltung/klassen', $e->getMessage(), 'fehler'); return; } View::redirect('/verwaltung/klassen', 'Klasse gespeichert.'); } /** @param array $params */ public function klasseLoeschen(array $params): void { $this->verlangeAnmeldung(); Klasse::loeschen((int)$params['id']); View::redirect('/verwaltung/klassen', 'Klasse gelöscht.'); } public function kontengruppen(): void { $this->verlangeAnmeldung(); $this->render('verwaltung/kontengruppen.php', [ 'titel' => 'Kontengruppen', 'gruppen' => Kontengruppe::alleMitKontenzahl(), 'ohneGruppe' => Kontengruppe::anzahlOhneGruppe(), ]); } public function kontengruppeNeu(): void { $this->verlangeAnmeldung(); $this->kontengruppeFormular(null); } /** @param array $params */ public function kontengruppeBearbeiten(array $params): void { $this->verlangeAnmeldung(); $gruppe = Kontengruppe::find((int)$params['id']); if ($gruppe === null) { View::redirect('/verwaltung/kontengruppen', 'Kontengruppe nicht gefunden.', 'fehler'); return; } $this->kontengruppeFormular($gruppe); } /** @param array|null $gruppe */ private function kontengruppeFormular(?array $gruppe): void { $this->render('verwaltung/kontengruppe-formular.php', [ 'titel' => $gruppe === null ? 'Neue Kontengruppe' : 'Kontengruppe bearbeiten', 'gruppe' => $gruppe, 'konten' => Konto::alle(), ]); } public function kontengruppeAnlegen(): void { $this->verlangeAnmeldung(); try { $id = Kontengruppe::anlegen( $this->post('name'), $this->post('beschreibung'), (int)$this->post('sortierung', '0') ); Kontengruppe::kontenZuordnen($id, $this->postIds('konten')); } catch (\Throwable $e) { View::redirect('/verwaltung/kontengruppen/neu', $e->getMessage(), 'fehler'); return; } View::redirect('/verwaltung/kontengruppen', 'Kontengruppe angelegt.'); } /** @param array $params */ public function kontengruppeSpeichern(array $params): void { $this->verlangeAnmeldung(); $id = (int)$params['id']; try { Kontengruppe::speichern( $id, $this->post('name'), $this->post('beschreibung'), (int)$this->post('sortierung', '0') ); Kontengruppe::kontenZuordnen($id, $this->postIds('konten')); } catch (\Throwable $e) { View::redirect('/verwaltung/kontengruppen/' . $id, $e->getMessage(), 'fehler'); return; } View::redirect('/verwaltung/kontengruppen', 'Kontengruppe gespeichert.'); } /** @param array $params */ public function kontengruppeLoeschen(array $params): void { $this->verlangeAnmeldung(); Kontengruppe::loeschen((int)$params['id']); View::redirect( '/verwaltung/kontengruppen', 'Kontengruppe gelöscht. Die Konten stehen jetzt unter „' . Kontengruppe::OHNE_GRUPPE . '“.' ); } /** * Die Konfiguration des Bargeld-Tools: Adresse, Zugangsdaten und die * Auswahl der Kategorien, die damit abgeglichen werden. * * Diese Einstellungen stehen bewusst nicht im zentralen * Einstellungsdialog: Ihr größerer Teil ist die Kategorienauswahl, und die * gehört in die Verwaltung, wo die Kategorien selbst gepflegt werden. */ public function bargeld(): void { $this->verlangeAnmeldung(); $this->render('verwaltung/bargeld.php', [ 'titel' => 'Bargeld-Tool', 'url' => (string)Einstellung::get('bargeld_url', ''), // Nicht 'benutzer': So heißt im Layout der angemeldete Mensch. 'benutzerkennung' => (string)Einstellung::get('bargeld_benutzer', ''), 'hatPasswort' => (string)Einstellung::get('bargeld_passwort', '') !== '', 'tage' => BargeldAbgleich::fensterTage(), 'kategorien' => Kategorie::baumFlach(), 'auswahl' => Kategorie::bargeldAuswahl(), 'schluessel' => Crypto::einsatzbereit(), ]); } public function bargeldSpeichern(): void { $this->verlangeAnmeldung(); $url = trim($this->post('bargeld_url')); if ($url !== '' && !preg_match('#^https?://#i', $url)) { View::redirect('/verwaltung/bargeld', 'Die Adresse muss mit http:// oder https:// beginnen.', 'fehler'); return; } // Ein mitkopiertes „/api/v1“ am Ende fliegt raus – sonst hinge der // Schnittstellenpfad ein zweites Mal dran. Einstellung::set('bargeld_url', $url === '' ? '' : BargeldTool::basisadresse($url), 'bargeld'); Einstellung::set('bargeld_benutzer', trim($this->post('bargeld_benutzer')), 'bargeld'); // Wie bei der FinTS-PIN: Ein leeres Feld heißt „unverändert“, sonst // ließe sich das Passwort nie speichern, ohne es erneut einzutippen. $passwort = $this->post('bargeld_passwort'); if ($passwort !== '') { Einstellung::set('bargeld_passwort', Crypto::verschluessle($passwort), 'bargeld'); } if ($this->post('passwort_loeschen') !== '') { Einstellung::set('bargeld_passwort', '', 'bargeld'); } $tage = (int)$this->post('bargeld_tage', (string)BargeldAbgleich::TAGE_STANDARD); Einstellung::set('bargeld_tage', (string)($tage > 0 ? min($tage, 365) : BargeldAbgleich::TAGE_STANDARD), 'bargeld'); $auswahl = $this->postIds('kategorien'); Kategorie::bargeldAuswahlSetzen($auswahl); // Was nicht mehr abgeglichen wird, darf auch keinen Haken mehr tragen. BargeldAbgleich::statusAufraeumen($auswahl); View::redirect('/verwaltung/bargeld', 'Einstellungen zum Bargeld-Tool gespeichert.'); } /** Der Verbindungstest – erreichbar? Zugangsdaten richtig? */ public function bargeldTest(): void { $this->verlangeAnmeldung(); $zugang = BargeldTool::ausEinstellungen(); if ($zugang === null) { View::redirect('/verwaltung/bargeld', 'Es ist keine Adresse hinterlegt.', 'fehler'); return; } $ergebnis = $zugang->test(); View::redirect('/verwaltung/bargeld', $ergebnis['meldung'], $ergebnis['erfolg'] ? 'erfolg' : 'fehler'); } /** * Alle Buchungen, an denen die Bargeld-Tool-Prüfung zuletzt einen Fehler * festgestellt hat – der Weg, den die Kachel „Offene Vorgänge“ des * Cockpit anbietet, sobald es solche Buchungen gibt. */ public function bargeldFehler(): void { $this->verlangeAnmeldung(); $fehlt = ($_GET['status'] ?? '') === 'fehlt'; $this->render('verwaltung/bargeld_fehler.php', [ 'titel' => $fehlt ? 'Bargeld-Tool: nicht gefundene Buchungen' : 'Bargeld-Tool: fehlgeschlagene Prüfungen', 'fehlt' => $fehlt, 'buchungen' => Buchung::mitBargeldFehler($fehlt ? 'fehlt' : 'fehler'), ]); } }