Fünf Berichtstypen wie im FinanzManager – Summen-, Buchungs-, Vergleichs-, Kontostands- und Budgetbericht – mit Filterleiste, gespeicherten Berichten in Berichtsgruppen, Drilldown in die Buchungen und CSV-Export. Ein Bericht speichert nur seine Frage; die Zahlen entstehen bei jedem Aufruf neu aus den Buchungen. Gezählt werden Bewegungen (gesplittete Buchungen über ihre Splitzeilen), Umbuchungen bleiben außen vor, Unkategorisiertes bekommt eine eigene Zeile. Im Ausgabenabschnitt steht der Betrag ohne Minus wie im Original, die Schlusszeile rechnet mit den echten Vorzeichen. Einzelheiten in docs/auswertungen.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
123 lines
4.6 KiB
PHP
123 lines
4.6 KiB
PHP
<?php
|
||
|
||
use Finanzmanager\Services\Auswertung;
|
||
use Finanzmanager\View;
|
||
|
||
/**
|
||
* Verwaltung der Berichtsgruppen – die Kacheln der Auswertungsübersicht.
|
||
*
|
||
* @var array<int, array{gruppe: array<string,mixed>|null, berichte: list<array<string,mixed>>}> $gruppen
|
||
* @var string $csrfToken
|
||
*/
|
||
|
||
include __DIR__ . '/../layout/kopf.php';
|
||
?>
|
||
|
||
<div class="tableiste">
|
||
<a class="tab" href="/auswertungen">Hauptansicht</a>
|
||
<span class="tab aktiv">Berichtsgruppen</span>
|
||
</div>
|
||
|
||
<div class="seitenaktionen">
|
||
<a href="/auswertungen" class="knopf">Zur Übersicht</a>
|
||
</div>
|
||
|
||
<p class="hinweis">
|
||
Gruppen ordnen die gespeicherten Berichte zu Kacheln – wie „Bankgeschäfte“ oder
|
||
„Steuern“ im FinanzManager. Wird eine Gruppe gelöscht, bleiben ihre Berichte erhalten
|
||
und rücken unter „Nicht gruppiert“.
|
||
</p>
|
||
|
||
<div class="kachel einzeln">
|
||
<h2>Neue Berichtsgruppe</h2>
|
||
<form method="post" action="/auswertungen/gruppen/neu" class="zeilenform">
|
||
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
|
||
<label>Name
|
||
<input type="text" name="name" required maxlength="120" placeholder="z. B. Bankgeschäfte">
|
||
</label>
|
||
<label>Sortierung
|
||
<input type="number" name="sortierung" value="0" class="schmal">
|
||
</label>
|
||
<button type="submit" class="knopf primaer">Anlegen</button>
|
||
</form>
|
||
</div>
|
||
|
||
<?php
|
||
$echte = array_filter($gruppen, static fn(array $eintrag): bool => $eintrag['gruppe'] !== null);
|
||
?>
|
||
|
||
<?php if ($echte === []): ?>
|
||
<p class="platzhalter">Noch keine Berichtsgruppe angelegt.</p>
|
||
<?php else: ?>
|
||
<table class="liste">
|
||
<thead>
|
||
<tr>
|
||
<th>Name</th>
|
||
<th class="rechts">Sortierung</th>
|
||
<th>Berichte</th>
|
||
<th class="rechts">Aktion</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php foreach ($echte as $eintrag): ?>
|
||
<?php $gruppe = $eintrag['gruppe']; ?>
|
||
<tr>
|
||
<td colspan="4">
|
||
<form method="post" action="/auswertungen/gruppen/<?= (int)$gruppe['id'] ?>"
|
||
class="zeilenform">
|
||
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
|
||
<input type="text" name="name" value="<?= View::h($gruppe['name']) ?>"
|
||
required maxlength="120">
|
||
<input type="number" name="sortierung" class="schmal"
|
||
value="<?= (int)$gruppe['sortierung'] ?>">
|
||
<span class="berichtstyp">
|
||
<?php if ($eintrag['berichte'] === []): ?>
|
||
keine Berichte
|
||
<?php else: ?>
|
||
<?= count($eintrag['berichte']) ?> Bericht<?= count($eintrag['berichte']) === 1 ? '' : 'e' ?>:
|
||
<?= View::h(implode(', ', array_column($eintrag['berichte'], 'name'))) ?>
|
||
<?php endif; ?>
|
||
</span>
|
||
<button type="submit" class="knopf klein">Speichern</button>
|
||
</form>
|
||
|
||
<form method="post" action="/auswertungen/gruppen/<?= (int)$gruppe['id'] ?>/loeschen"
|
||
class="inline" data-bestaetigen="Gruppe löschen? Die Berichte bleiben erhalten.">
|
||
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
|
||
<button type="submit" class="knopf klein gefahr">Löschen</button>
|
||
</form>
|
||
</td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
<?php endif; ?>
|
||
|
||
<?php
|
||
$ohne = $gruppen[0]['berichte'] ?? [];
|
||
?>
|
||
<?php if ($ohne !== []): ?>
|
||
<h2>Nicht gruppiert</h2>
|
||
<table class="liste">
|
||
<thead>
|
||
<tr><th>Bericht</th><th>Typ</th><th class="rechts">Aktion</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php foreach ($ohne as $bericht): ?>
|
||
<tr>
|
||
<td>
|
||
<a href="/auswertungen/bericht/<?= (int)$bericht['id'] ?>">
|
||
<?= View::h($bericht['name']) ?>
|
||
</a>
|
||
</td>
|
||
<td><?= View::h(Auswertung::TYPEN[$bericht['typ']] ?? $bericht['typ']) ?></td>
|
||
<td class="rechts">
|
||
<a href="/auswertungen/bericht/<?= (int)$bericht['id'] ?>" class="knopf klein">Öffnen</a>
|
||
</td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
<?php endif; ?>
|
||
|
||
<?php include __DIR__ . '/../layout/fuss.php'; ?>
|