299 lines
10 KiB
PHP
299 lines
10 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace Finanzmanager\Controllers;
|
||
|
||
use Finanzmanager\Models\Adresse;
|
||
use Finanzmanager\Models\Bankinstitut;
|
||
use Finanzmanager\Models\Buchung;
|
||
use Finanzmanager\Models\Einstellung;
|
||
use Finanzmanager\Models\Erinnerung;
|
||
use Finanzmanager\Models\Kategorie;
|
||
use Finanzmanager\Models\Klasse;
|
||
use Finanzmanager\Models\Konto;
|
||
use Finanzmanager\Models\Kontengruppe;
|
||
use Finanzmanager\Models\RegelmaessigeBuchung;
|
||
use Finanzmanager\Models\Vertrag;
|
||
use Finanzmanager\Services\BargeldAbgleich;
|
||
use Finanzmanager\Services\BargeldTool;
|
||
use Finanzmanager\Services\Crypto;
|
||
use Finanzmanager\View;
|
||
|
||
/**
|
||
* Einstiegsseite der Verwaltung sowie die beiden schlanken Stammdatenlisten
|
||
* Klassen und Kontengruppen – beide flach, beide mit Anlegen, Bearbeiten und
|
||
* Löschen auf einer Seite.
|
||
*/
|
||
class VerwaltungController extends BaseController
|
||
{
|
||
public function index(): void
|
||
{
|
||
$this->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<string,string> $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<string,string> $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<string,string> $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<string,mixed>|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<string,string> $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<string,string> $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'),
|
||
]);
|
||
}
|
||
}
|