Finanzmanager/tests/07_KontenTest.php
fds2610-bot 92e15d54c1 Fix: Σ-Kennzeichen ließ sich beim Konto nicht abschalten
Ein nicht angehaktes Ankreuzfeld steht nicht im POST. KontenController::
formulardaten() reichte "in_summe" gar nicht durch, also griff im Model der
Standardwert "zählt zur Summe" – die Anwendung meldete "Konto gespeichert",
geändert hatte sich nichts.

formulardaten() nimmt das POST-Array jetzt als Parameter und ist damit ohne
HTTP prüfbar; die Ankreuzfelder werden ausdrücklich auf true/false abgebildet.
Der Standard bleibt für Aufrufe ohne den Schlüssel bestehen – der QIF-Import
gibt das Feld nicht an.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 17:10:59 +02:00

207 lines
9.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
use Finanzmanager\Controllers\KontenController;
use Finanzmanager\Models\Konto;
use Finanzmanager\Models\Kontengruppe;
class KontenTest extends TestCase
{
protected string $testName = 'Test 07: Konten und Kontengruppen';
public function run(): void
{
$this->mandantAnlegen();
$this->anlegenUndFinden();
$this->kontoarten();
$this->uebersichtGruppiertUndSummiert();
$this->betragsEingabe();
$this->ankreuzfelderAusDemFormular();
}
private function anlegenUndFinden(): void
{
$id = Konto::anlegen([
'name' => 'DKB Girokonto',
'kontoart' => 'bank',
'kontonummer' => '1010903027',
'anfangssaldo' => 1234.56,
'aktiv' => 1,
]);
$konto = Konto::find($id);
$this->assertEquals('DKB Girokonto', $konto['name'], 'Konto wird angelegt');
$this->assertEquals('1234.56', $konto['anfangssaldo'], 'Anfangssaldo wird übernommen');
$doppelt = false;
try {
Konto::anlegen(['name' => 'DKB Girokonto']);
} catch (\Throwable) {
$doppelt = true;
}
$this->assert($doppelt, 'Kontonamen sind eindeutig');
$ohneName = false;
try {
Konto::anlegen(['name' => ' ']);
} catch (\Throwable) {
$ohneName = true;
}
$this->assert($ohneName, 'Ein Konto ohne Namen wird abgewiesen');
// Leerzeichen in der IBAN sind beim Abtippen normal und müssen weg.
Konto::speichern($id, [
'name' => 'DKB Girokonto',
'kontoart' => 'bank',
'iban' => 'de89 3704 0044 0532 0130 00',
'aktiv' => 1,
]);
$this->assertEquals(
'DE89370400440532013000',
Konto::find($id)['iban'],
'IBAN wird ohne Leerzeichen und in Großbuchstaben abgelegt'
);
Konto::loeschen($id);
$this->assertNull(Konto::find($id), 'Konto lässt sich löschen');
}
private function kontoarten(): void
{
$this->assertEquals('bank', Konto::artAusQif('Bank'), 'QIF-Typ Bank');
$this->assertEquals('kreditkarte', Konto::artAusQif('CCard'), 'QIF-Typ CCard');
$this->assertEquals('sparkonto', Konto::artAusQif('Oth T'), 'QIF-Typ Oth T');
$this->assertEquals('depot', Konto::artAusQif('Port'), 'QIF-Typ Port');
$this->assertEquals('depot', Konto::artAusQif('Invst'), 'QIF-Typ Invst');
$this->assertEquals('sonstiges', Konto::artAusQif('Unbekannt'), 'Unbekannter Typ fällt auf Sonstiges');
$this->assertEquals('Kreditkarte', Konto::bezeichnungDerArt('kreditkarte'), 'Bezeichnung auf Deutsch');
$unbekannt = false;
try {
Konto::anlegen(['name' => 'Testkonto', 'kontoart' => 'gibtesnicht']);
} catch (\Throwable) {
$unbekannt = true;
}
$this->assert($unbekannt, 'Unbekannte Kontoart wird abgewiesen');
}
private function uebersichtGruppiertUndSummiert(): void
{
$anlage = Kontengruppe::anlegen('Anlage', '', 1);
Konto::anlegen(['name' => 'Tagesgeld', 'kontoart' => 'sparkonto',
'kontengruppe_id' => $anlage, 'anfangssaldo' => 10000, 'aktiv' => 1]);
Konto::anlegen(['name' => 'Depot', 'kontoart' => 'depot',
'kontengruppe_id' => $anlage, 'anfangssaldo' => 5000, 'aktiv' => 1]);
Konto::anlegen(['name' => 'Girokonto', 'kontoart' => 'bank',
'anfangssaldo' => 1500.50, 'aktiv' => 1]);
Konto::anlegen(['name' => 'Kreditkarte', 'kontoart' => 'kreditkarte',
'anfangssaldo' => -320.25, 'aktiv' => 1]);
Konto::anlegen(['name' => 'Altes Konto', 'kontoart' => 'bank',
'anfangssaldo' => 999, 'aktiv' => 0]);
$uebersicht = Konto::uebersicht();
$summeErwartet = 10000 + 5000 + 1500.50 - 320.25;
$this->assertEquals($summeErwartet, $uebersicht['summe'], 'Gesamtsumme ohne inaktive Konten');
$this->assertEquals(2, count($uebersicht['gruppen']), 'Zwei Gruppen: Anlage und Nicht gruppiert');
$nachName = [];
foreach ($uebersicht['gruppen'] as $gruppe) {
$nachName[$gruppe['name']] = $gruppe;
}
$this->assertEquals(15000.0, $nachName['Anlage']['summe'] ?? 0.0, 'Summe der Gruppe Anlage');
$this->assertEquals(
2,
count($nachName[Kontengruppe::OHNE_GRUPPE]['konten'] ?? []),
'Konten ohne Gruppe stehen unter „Nicht gruppiert“'
);
$mitInaktiven = Konto::uebersicht(false);
$this->assertEquals(
$summeErwartet + 999,
$mitInaktiven['summe'],
'Inaktive Konten zählen mit, wenn sie eingeblendet werden'
);
// Die Saldospalten existieren schon, gespeist aus dem Anfangssaldo.
$giro = null;
foreach ($nachName[Kontengruppe::OHNE_GRUPPE]['konten'] as $konto) {
if ($konto['name'] === 'Girokonto') {
$giro = $konto;
}
}
$this->assertEquals(1500.50, $giro['saldo_aktuell'], 'Aktueller Saldo entspricht dem Anfangssaldo');
$this->assertEquals(1500.50, $giro['saldo_erwartet'], 'Erwarteter Saldo entspricht dem Anfangssaldo');
$this->assertNull($giro['saldo_online'], 'Online-Saldo bleibt leer bis zum ersten Bankabruf');
// Wird die Gruppe gelöscht, bleiben die Konten erhalten.
Kontengruppe::loeschen($anlage);
$danach = Konto::uebersicht();
$this->assertEquals(1, count($danach['gruppen']), 'Nach dem Löschen bleibt nur „Nicht gruppiert“');
$this->assertEquals($summeErwartet, $danach['summe'], 'Die Summe ändert sich dadurch nicht');
}
private function betragsEingabe(): void
{
$this->assertEquals(1234.56, KontenController::zahl('1.234,56'), 'Deutsches Format mit Tausenderpunkt');
$this->assertEquals(-320.25, KontenController::zahl('-320,25'), 'Negativer Betrag');
$this->assertEquals(1234.56, KontenController::zahl('1234.56'), 'Punkt vor zwei Ziffern ist Dezimaltrenner');
$this->assertEquals(1500.0, KontenController::zahl('1.500'), 'Punkt vor drei Ziffern ist Tausendertrenner');
$this->assertEquals(1234567.0, KontenController::zahl('1.234.567'), 'Mehrere Punkte sind Tausendertrenner');
$this->assertEquals(0.5, KontenController::zahl('0.5'), 'Einzelne Nachkommastelle');
$this->assertEquals(0.0, KontenController::zahl(''), 'Leere Eingabe ergibt null');
$this->assertEquals(99.9, KontenController::zahl(' 99,90 € '), 'Währungszeichen und Leerzeichen stören nicht');
}
/**
* Ein nicht angehaktes Ankreuzfeld schickt der Browser gar nicht mit. Die
* Formularabbildung muss daraus ein ausdrückliches Nein machen, sonst lässt
* sich das Kennzeichen nie wieder abschalten – „Konto gespeichert“ steht
* dann da, geändert hat sich nichts.
*/
private function ankreuzfelderAusDemFormular(): void
{
$angehakt = KontenController::formulardaten([
'name' => 'Girokonto', 'kontoart' => 'bank', 'aktiv' => '1', 'in_summe' => '1',
]);
$this->assert($angehakt['aktiv'] === true, 'Angehaktes „aktiv“ kommt als Ja an');
$this->assert($angehakt['in_summe'] === true, 'Angehaktes Σ-Kennzeichen kommt als Ja an');
$leer = KontenController::formulardaten(['name' => 'Girokonto', 'kontoart' => 'bank']);
$this->assert($leer['aktiv'] === false, 'Fehlendes „aktiv“ heißt inaktiv');
$this->assert($leer['in_summe'] === false, 'Fehlendes Σ-Kennzeichen heißt: zählt nicht zur Summe');
// Und derselbe Weg durch das Model hindurch: Abhaken muss ankommen.
$id = Konto::anlegen(KontenController::formulardaten([
'name' => 'Auslagen Eltern', 'kontoart' => 'sonstiges',
'anfangssaldo' => '1.500,00', 'aktiv' => '1', 'in_summe' => '1',
]));
$this->assertEquals(1, (int)Konto::find($id)['in_summe'], 'Neues Konto zählt zunächst mit');
$this->assertEquals(1500.0, (float)Konto::find($id)['anfangssaldo'], 'Anfangssaldo aus dem Formular');
Konto::speichern($id, KontenController::formulardaten([
'name' => 'Auslagen Eltern', 'kontoart' => 'sonstiges',
'anfangssaldo' => '1.500,00', 'aktiv' => '1',
]));
$this->assertEquals(0, (int)Konto::find($id)['in_summe'], 'Σ-Kennzeichen lässt sich entfernen');
$uebersicht = Konto::uebersicht();
$gefunden = false;
foreach ($uebersicht['gruppen'] as $gruppe) {
foreach ($gruppe['konten'] as $konto) {
if ((int)$konto['id'] === $id) {
$gefunden = true;
}
}
}
$this->assert($gefunden, 'Das Konto bleibt in der Übersicht sichtbar');
// Der QIF-Import gibt das Feld nicht an – dort gilt weiter der Standard.
$importiert = Konto::anlegen(['name' => 'Aus dem Export', 'kontoart' => 'bank', 'aktiv' => 1]);
$this->assertEquals(1, (int)Konto::find($importiert)['in_summe'], 'Ohne Angabe zählt ein Konto mit');
}
}