# Buchungen Kontoblatt, Buchungsmaske und die Saldenrechnung. ## Umbuchungen: ein Datensatz, zwei Sichten Eine Umbuchung wird **einmal** gespeichert – als Buchung auf dem Ausgangskonto mit `gegenkonto_id`. Das Kontoblatt des Gegenkontos zeigt sie mit umgekehrtem Vorzeichen. Der Grund ist nicht nur Sparsamkeit: Zwei gespiegelte Datensätze laufen früher oder später auseinander (einer wird geändert, der andere nicht). Und der QIF-Export macht es genauso – dort steht jede Umbuchung genau einmal, die Gegenseite nur als `L[Zielkonto]`. `Buchung::kontoblatt()` vereinigt deshalb drei Mengen: 1. Buchungen mit `konto_id = X` (eigene Sicht) 2. Buchungen mit `gegenkonto_id = X` ohne Splitzeilen, Betrag negiert 3. Splitzeilen mit `gegenkonto_id = X`, Betrag negiert Zeilen aus 2 und 3 tragen `gegensicht = true`. Sie sind nicht bearbeitbar – das geht auf dem Ursprungskonto –, damit eine Umbuchung nicht aus zwei Richtungen widersprüchlich geändert wird. Dieselbe Dreiteilung gilt für die Salden (`Buchung::saldenJeKonto()`), die alle Konten mit sechs Abfragen auf einmal berechnet statt je Konto einzeln. ## Splitbuchungen Eine Buchung ist entweder einfach zugeordnet **oder** gesplittet. Sobald Splitzeilen vorliegen, räumt das Model `kategorie_id` und `gegenkonto_id` der Buchung; die Zuordnung steckt dann ausschließlich in den Zeilen. Die Summe der Zeilen muss dem Buchungsbetrag entsprechen – geprüft im Model (Toleranz ein halber Cent, für Rundungen aus der Betragsumrechnung) und in der Maske als Restbetragsanzeige. Eine Splitzeile darf ein Gegenkonto tragen; dann erscheint auf jenem Konto nur der Betrag dieser Zeile. ## Salden | Spalte | Bedeutung | |---|---| | Online-Saldo | Stand des letzten Bankabrufs (`konten.saldo_online`, ab Phase 5) | | Aktueller Saldo | Anfangssaldo plus alle Buchungen bis heute | | Erwarteter Saldo | zusätzlich die künftig datierten Buchungen | In die **Summe der Kontostände** zählen nur Konten mit `in_summe = 1` – das entspricht der Σ-Spalte im FinanzManager. Durchlaufende Auslagen und Rentenversicherungen bleiben so außen vor, erscheinen aber weiter in der Liste. Der QIF-Export kennt das Kennzeichen nicht; es wird im Kontoformular gepflegt. ## Beträge in der Oberfläche Eingegeben wird immer ein **positiver** Betrag; die Richtung bestimmt die Auswahl *Ausgabe / Einnahme / Umbuchung*. `KontenController::zahl()` liest das deutsche Format und entscheidet bei einem Punkt ohne Komma nach der Stellenzahl: drei Ziffern dahinter heißt Tausendertrenner (`1.500`), sonst Dezimaltrenner (`1234.56`). ## Bestätigungen und die Content-Security-Policy Die CSP erlaubt keine Inline-Skripte (`script-src 'self'`). Rückfragen vor dem Löschen dürfen deshalb **nicht** als `onsubmit="return confirm(…)"` im HTML stehen – der Browser verwirft sie stillschweigend, und gelöscht wird ohne Nachfrage. Stattdessen: ```html