mandantAnlegen(); $this->anlegenUndFinden(); $this->kontoarten(); $this->uebersichtGruppiertUndSummiert(); $this->betragsEingabe(); $this->ankreuzfelderAusDemFormular(); $this->kontenEinerGruppeZuordnen(); } /** * Die Kontengruppen stehen nicht im QIF-Export; sie werden nach dem Import * angelegt und die Konten in einem Zug angekreuzt. Abgehakte Konten müssen * dabei zurück nach „Nicht gruppiert“ fallen, Konten anderer Gruppen aber * unberührt bleiben. */ private function kontenEinerGruppeZuordnen(): void { $anlage = Kontengruppe::anlegen('Anlage', '', 1); $liquide = Kontengruppe::anlegen('Liquide Mittel', '', 2); $haus = Konto::anlegen(['name' => 'Whg Besigheim', 'kontoart' => 'vermoegen', 'aktiv' => 1]); $auto = Konto::anlegen(['name' => 'Skoda Kamiq', 'kontoart' => 'vermoegen', 'aktiv' => 1]); $giro = Konto::anlegen(['name' => 'VR Weil Girokonto', 'kontoart' => 'bank', 'aktiv' => 1]); Kontengruppe::kontenZuordnen($liquide, [$giro]); Kontengruppe::kontenZuordnen($anlage, [$haus, $auto]); $this->assertEquals($anlage, (int)Konto::find($haus)['kontengruppe_id'], 'Konto landet in der Gruppe'); $this->assertEquals($anlage, (int)Konto::find($auto)['kontengruppe_id'], 'Auch das zweite Konto'); $this->assertEquals( $liquide, (int)Konto::find($giro)['kontengruppe_id'], 'Konten anderer Gruppen bleiben, wo sie sind' ); // Zweiter Durchgang ohne das Auto: es fällt zurück zu „Nicht gruppiert“. Kontengruppe::kontenZuordnen($anlage, [$haus]); $this->assertNull(Konto::find($auto)['kontengruppe_id'], 'Abgehaktes Konto steht wieder ohne Gruppe'); $this->assertEquals($anlage, (int)Konto::find($haus)['kontengruppe_id'], 'Das andere bleibt zugeordnet'); // Leere Auswahl leert die Gruppe, ohne sie zu löschen. Kontengruppe::kontenZuordnen($anlage, []); $this->assertNull(Konto::find($haus)['kontengruppe_id'], 'Leere Auswahl räumt die Gruppe'); $this->assertNotEmpty(Kontengruppe::find($anlage), 'Die Gruppe selbst bleibt bestehen'); $mitZahl = []; foreach (Kontengruppe::alleMitKontenzahl() as $gruppe) { $mitZahl[$gruppe['name']] = (int)$gruppe['anzahl_konten']; } $this->assertEquals(0, $mitZahl['Anlage'], 'Kontenzahl der geleerten Gruppe'); $this->assertEquals(1, $mitZahl['Liquide Mittel'], 'Kontenzahl der anderen Gruppe'); } 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'); } }