193 lines
10 KiB
Markdown
193 lines
10 KiB
Markdown
# Auswertungen
|
||
|
||
Der Bereich *Auswertungen* baut die Berichte des FinanzManagers nach: fünf Berichtstypen,
|
||
eine Filterleiste, gespeicherte Berichte in Gruppen, Drilldown in die Buchungen und
|
||
CSV-Export.
|
||
|
||
Ein Bericht wird **nie gerechnet gespeichert**, sondern immer nur seine Frage. Die Zahlen
|
||
entstehen bei jedem Aufruf neu aus den Buchungen. Ein Bericht mit der Zeitraumvorgabe
|
||
„Letzter Monat“ zeigt im August den Juli und nicht für immer den Monat seiner Entstehung.
|
||
|
||
## Was gezählt wird
|
||
|
||
Grundlage sind die **Bewegungen**: nicht gesplittete Buchungen mit ihrem Betrag,
|
||
gesplittete über ihre Splitzeilen. Sonst zählte eine Splitbuchung doppelt oder gar nicht.
|
||
|
||
**Umbuchungen bleiben außen vor.** Sie verschieben Vermögen zwischen eigenen Konten und
|
||
sind weder Einnahme noch Ausgabe – dieselbe Regel wie im Budgetplaner. Allein der
|
||
Buchungsbericht kann sie über den Schalter *Umbuchungen mitzählen* mitführen; dann weicht
|
||
seine Summe naturgemäß vom Summenbericht ab.
|
||
|
||
**Nicht kategorisierte Buchungen verschwinden nicht.** Sie stehen als eigene Zeile
|
||
*Nicht kategorisiert* am Ende ihres Abschnitts. Geld, das keiner Kategorie zugeordnet ist,
|
||
fiele sonst lautlos aus der Summe.
|
||
|
||
Ob eine Bewegung zu den Einnahmen oder den Ausgaben zählt, entscheidet die **Art ihrer
|
||
Kategorie**, nicht das Vorzeichen: Eine Erstattung ist eine negative Ausgabe und gehört
|
||
unter die Ausgaben. Nur wo keine Kategorie steht, bleibt das Vorzeichen als einziger
|
||
Anhaltspunkt.
|
||
|
||
Aggregiert wird in PHP, nicht in SQL. Die Datenbank liefert die Bewegungen des Zeitraums,
|
||
das Einsortieren in Zeilen und Spalten passiert in `Auswertung`. Bei Zehntausenden
|
||
Buchungen ist das Millisekundensache, und Baumsummen über Kategorien, Vorzeichenregeln und
|
||
Spaltenraster wären in SQL erheblich schwerer nachzulesen.
|
||
|
||
## Vorzeichen
|
||
|
||
Intern gilt durchgehend die Buchhaltung: Ausgaben negativ. In der **Anzeige** dreht der
|
||
Ausgabenabschnitt sein Vorzeichen – dort steht 636,39 statt −636,39, wie im FinanzManager;
|
||
die Überschrift sagt ja bereits, worum es geht. Die Schlusszeile *Gesamt Einnahmen −
|
||
Ausgaben* rechnet wieder mit den echten Werten.
|
||
|
||
Zwei Ausnahmen führen das Vorzeichen mit, weil sie keine Abschnitte haben: der
|
||
**Buchungsbericht** (eine Buchungsliste, kein Summenbericht) und der **Budgetbericht**
|
||
(Vorzeichen wie im Budgetplaner). Der Drilldown zeigt ebenfalls die echten Vorzeichen.
|
||
|
||
## Die fünf Berichtstypen
|
||
|
||
| Typ | Zeilen | Spalten |
|
||
|---|---|---|
|
||
| **Summenbericht** | Zeilen-Summe, nach Einnahmen und Ausgaben getrennt | Zeitraum, je nach Spalten-Aufteilung |
|
||
| **Buchungsbericht** | Einzelbuchungen, gruppiert nach Zeilen-Summe; bei eingerichtetem Bargeld-Tool mit Spalte „Bar“ und Filter „Bargeld-Tool“ | feste Buchungsspalten |
|
||
| **Vergleichsbericht** | wie Summenbericht | Zeitraum, Vorjahreszeitraum, Differenz, Veränderung |
|
||
| **Kontostandsbericht** | Konten | Salden zu den Enden der Spaltenzeiträume |
|
||
| **Budgetbericht** | Kategoriebaum | Budget, Ist, Saldo |
|
||
|
||
### Summenbericht
|
||
|
||
Bei der Zeilen-Summe *Kategorie* entsteht der eingerückte Baum: Jede Kategorie zeigt ihre
|
||
**eigenen** Werte, Kategorien mit Nachfahren bekommen dahinter eine Zeile *Gesamt <Name>*
|
||
mit der Summe des Astes. Eine Elternkategorie ohne eigene Buchungen steht deshalb als
|
||
bloße Kopfzeile da – genau wie im Original.
|
||
|
||
Der Schalter *mit Einrückung* schaltet auf eine flache Liste mit vollem Kategoriepfad um.
|
||
Dort zählt jede Kategorie nur sich selbst, und es gibt keine Astsummen; sonst stünde eine
|
||
Summe wie ein gleichrangiger Posten neben ihren eigenen Bestandteilen.
|
||
|
||
Bei *Klasse*, *Konto* und *Empfänger* ist die Liste flach und alphabetisch. Die Aufteilung
|
||
in Einnahmen und Ausgaben bleibt: Eine Klasse mit beidem erscheint in beiden Abschnitten.
|
||
|
||
### Vergleichsbericht
|
||
|
||
Verglichen wird gegen **denselben Zeitraum ein Jahr früher**. Die Spalten-Aufteilung
|
||
spielt hier keine Rolle – die Spalten gibt der Vergleich vor.
|
||
|
||
Ohne Vorjahreswert bleibt die Prozentspalte leer: „unendlich viel mehr“ ist keine Aussage,
|
||
die in eine Spalte gehört. Ein Monatsende bleibt beim Rückrechnen ein Monatsende, damit
|
||
der 28.02. nicht auf einen 29.02. trifft und der Vergleichszeitraum einen Tag zu lang wird.
|
||
|
||
### Kontostandsbericht
|
||
|
||
Anders als die übrigen Berichte zählt hier nicht die Bewegung im Zeitraum, sondern der
|
||
**Stand**: alle Buchungen bis zum Stichtag, auch die vor dem Berichtszeitraum, und die
|
||
Gegenseiten von Umbuchungen. Konten, die im ganzen Zeitraum auf null standen, fallen weg –
|
||
dieselbe Regel wie in der Cockpit-Kachel. Die Summe zählt alle gezeigten Konten,
|
||
unabhängig vom Σ-Kennzeichen der Kontenübersicht.
|
||
|
||
Die Null wird hier ausgeschrieben: Ein Konto, das auf null steht, ist eine Aussage.
|
||
|
||
### Budgetbericht
|
||
|
||
Gerechnet wird über die **vollen Monate**, die der Zeitraum berührt. Ein Budget ist ein
|
||
Monatswert, und ein halber Monat hat kein halbes Budget; anders wären Budget und Ist nicht
|
||
vergleichbar und die Saldospalte bedeutungslos. Der Berichtskopf nennt deshalb den
|
||
Monatsbereich.
|
||
|
||
Geht der Zeitraum über den Jahreswechsel, gilt je Jahr dessen eigenes aktives Budget
|
||
(`Budget::aktivesFuerJahr()`). Vorzeichen und Saldo folgen dem Budgetplaner: Ausgaben
|
||
negativ, Saldo ist `ist − budget`, positiv heißt besser als geplant. Übergeordnete
|
||
Kategorien zeigen die Summe ihres Astes.
|
||
|
||
## Filterleiste
|
||
|
||
| Feld | Wirkung |
|
||
|---|---|
|
||
| Zeitraum | Vorgabe oder *Benutzerdefiniert*; von/bis sind immer gefüllt und zeigen, was die Vorgabe gerade bedeutet |
|
||
| Bericht anzeigen als | wechselt den Berichtstyp, ohne den übrigen Filter zu verlieren |
|
||
| Zeilen-Summe | Kategorie, Klasse, Konto oder Empfänger |
|
||
| Spalten-Aufteilung | Keine, Monat, Quartal, Jahr |
|
||
| mit Einrückung | Kategoriebaum oder flache Liste mit Pfad |
|
||
| Suche | Empfänger oder Buchungstext |
|
||
| Einschränken | Konten, Kategorien, Klassen (Mehrfachauswahl) |
|
||
|
||
Eine gewählte Kategorie **schließt ihre Unterkategorien ein** – wer „400 - Leben“ filtert,
|
||
meint den ganzen Ast. Nichts ausgewählt heißt alles.
|
||
|
||
Zwei Berichte bestimmen ihre Zeilen selbst und sperren das Feld: der Kontostandsbericht
|
||
führt immer Konten, der Budgetbericht immer Kategorien. Zwei bestimmen ihre Spalten
|
||
selbst: Vergleichs- und Budgetbericht.
|
||
|
||
Die Filterleiste sendet per **GET**. Jeder Zwischenstand ist damit eine Adresse, die man
|
||
sich merken, weitergeben und mit *Speichern unter* festhalten kann.
|
||
|
||
## Gespeicherte Berichte und Gruppen
|
||
|
||
Ein gespeicherter Bericht ist Name, Typ und Filter – mehr nicht. Der Filter liegt als JSON
|
||
in einer Spalte und wird beim Lesen immer durch `Auswertung::normalisiere()` geschickt:
|
||
Was dort nicht vorgesehen ist, fällt weg. Ein alter Bericht kann nach einer
|
||
Programmänderung höchstens eine Einstellung verlieren, aber nichts Unerwartetes in die
|
||
Abfrage tragen.
|
||
|
||
*Speichern unter* legt unter neuem Namen an und kann die Berichtsgruppe gleich mit
|
||
anlegen – wer sie erst anderswo erzeugen müsste, verlöre den eingestellten Filter.
|
||
*Speichern* überschreibt den geöffneten Bericht.
|
||
|
||
**Berichtsgruppen** sind die Kacheln der Übersicht, wie „Bankgeschäfte“ oder „Steuern“ im
|
||
Original. Wird eine Gruppe gelöscht, bleiben ihre Berichte erhalten und rücken unter
|
||
*Nicht gruppiert*: Ein Bericht ist Arbeit, eine Gruppe nicht.
|
||
|
||
Leere Gruppen bleiben in der Übersicht stehen. Sie sind angelegt worden, um befüllt zu
|
||
werden, und ohne Kachel gäbe es keinen Ort, an den ein Bericht könnte.
|
||
|
||
## Drilldown
|
||
|
||
Jeder Zeilenname und jede Zahl im Summen-, Vergleichs- und Budgetbericht ist ein Link auf
|
||
die Buchungen dahinter. Eine Zahl schränkt zusätzlich auf ihre Spalte ein.
|
||
|
||
Gefiltert wird nicht, indem die Zeile in einen neuen Filter übersetzt wird, sondern indem
|
||
**dieselben Bewegungen nachgesiebt** werden, aus denen die Zelle entstanden ist. Nur so
|
||
trifft der Drilldown auch das, was ein Filter gar nicht ausdrücken könnte: die Zeile
|
||
*Nicht kategorisiert* etwa, oder eine Astsumme über mehrere Unterkategorien.
|
||
|
||
Die Legenden der Cockpit-Kacheln nutzen denselben Weg (`/auswertungen/buchungen`) mit drei
|
||
Zusätzen: `art=einnahme|ausgabe` siebt zusätzlich nach Einnahme oder Ausgabe (entschieden
|
||
wie im Bericht über die Art der Kategorie, ohne Kategorie über das Vorzeichen), eine leere
|
||
`zeile` nimmt alle Bewegungen, und `zeile=kategorie:12,15,0` fasst mehrere Kategorien
|
||
zusammen (die `0` steht für *Nicht kategorisiert*). `herkunft=cockpit` lenkt den Weg
|
||
zurück ins Cockpit statt in einen Bericht.
|
||
|
||
## CSV-Export
|
||
|
||
Dieselben Zeilen, dieselben Zahlen, dieselben Vorzeichen wie am Bildschirm – wer den
|
||
Export mit der Anzeige vergleicht, soll nicht rechnen müssen.
|
||
|
||
Deutsches Tabellenkalkulations-CSV: Semikolon als Trenner, Komma als Dezimalzeichen, kein
|
||
Tausenderpunkt (der machte aus der Zahl einen Text), CRLF als Zeilenende und ein
|
||
vorangestelltes BOM – sonst zeigen Excel und LibreOffice beim Doppelklick „Übrige“ statt
|
||
„Übrige“. Die Einrückung des Kategoriebaums steht als führende Leerzeichen im Namensfeld,
|
||
sonst wäre die Hierarchie verloren.
|
||
|
||
PDF gibt es bewusst nicht (siehe `PLAN.md`); Papier läuft über die Druckfunktion des
|
||
Browsers.
|
||
|
||
## Dateien
|
||
|
||
| Datei | Inhalt |
|
||
|---|---|
|
||
| `src/Services/Auswertung.php` | die Rechenmaschine: Bewegungen, die fünf Berichtstypen, Drilldown |
|
||
| `src/Services/Zeitraum.php` | Zeitraumvorgaben und Spaltenraster, reine Kalenderrechnung ohne Datenbank |
|
||
| `src/Services/BerichtExport.php` | CSV |
|
||
| `src/Models/Bericht.php` | gespeicherte Berichte, Filter-JSON |
|
||
| `src/Models/Berichtsgruppe.php` | Gruppen |
|
||
| `src/Controllers/AuswertungenController.php` | Übersicht, Berichtsansicht, Drilldown, Export |
|
||
| `src/Views/auswertungen/` | Übersicht, Filterleiste, ein Teiltemplate je Darstellung |
|
||
| `migrations/005_berichte.sql` | `berichte`, `berichtsgruppen` |
|
||
|
||
## Tests
|
||
|
||
* `tests/14_AuswertungTest.php` – Zeitraumvorgaben und Spaltenraster, Filterprüfung,
|
||
alle fünf Berichtstypen, Astsummen, Splitbuchungen, Ausschluss der Umbuchungen,
|
||
unkategorisierte Buchungen, Einschränkungen, Drilldown, CSV, gespeicherte Berichte
|
||
* `tests/e2e/specs/auswertungen.spec.js` – Übersicht und Standardvorlagen, die fünf
|
||
Tabellen, Spalten-Aufteilung, Drilldown und zurück, Speichern/Wiederfinden/Löschen,
|
||
CSV-Download
|