mandantAnlegen(); $this->konto = Konto::anlegen([ 'name' => 'Splitklasse Giro', 'kontoart' => 'bank', 'anfangssaldo' => 0, 'aktiv' => 1, ]); $this->lebensmittel = Kategorie::anlegen(['name' => 'Splitklasse Lebensmittel', 'art' => 'ausgabe']); $this->drogerie = Kategorie::anlegen(['name' => 'Splitklasse Drogerie', 'art' => 'ausgabe']); $this->privat = Klasse::anlegen('Splitklasse Privat'); $this->beruf = Klasse::anlegen('Splitklasse Beruf'); $this->alt = Klasse::anlegen('Splitklasse Buchungsklasse'); $this->splitKlasseErmitteln(); $this->kontoblattZeigtGemeinsameKlasse(); $this->kontoblattZeigtMarkeBeiVerschiedenenKlassen(); $this->ohneSplitBleibtEsBeiDerBuchungsklasse(); } private function splitKlasseErmitteln(): void { $gleich = [['klasse_id' => $this->privat], ['klasse_id' => (string)$this->privat]]; $this->assertEquals( ['gemischt' => false, 'klasse_id' => $this->privat], Buchung::splitKlasse($gleich, $this->alt), 'Gleiche Klassen in allen Zeilen gelten für die ganze Buchung' ); $verschieden = [['klasse_id' => $this->privat], ['klasse_id' => $this->beruf]]; $this->assertEquals( ['gemischt' => true, 'klasse_id' => null], Buchung::splitKlasse($verschieden, $this->alt), 'Verschiedene Klassen machen die Buchung gemischt' ); $teilweise = [['klasse_id' => $this->privat], ['klasse_id' => null]]; $this->assertEquals( true, Buchung::splitKlasse($teilweise, null)['gemischt'], 'Eine Zeile ohne Klasse unterscheidet sich von einer mit Klasse' ); $ohne = [['klasse_id' => null], ['klasse_id' => null]]; $this->assertEquals( ['gemischt' => false, 'klasse_id' => $this->alt], Buchung::splitKlasse($ohne, $this->alt), 'Ohne Klasse in den Zeilen bleibt die Klasse der Buchung' ); $this->assertEquals( ['gemischt' => false, 'klasse_id' => null], Buchung::splitKlasse($ohne, null), 'Ohne jede Klasse bleibt die Spalte leer' ); } private function kontoblattZeigtGemeinsameKlasse(): void { $id = $this->splitbuchung('Gleichmarkt', $this->privat, $this->privat); $zelle = $this->klassenzelle($id); $this->assert(str_contains($zelle, 'Splitklasse Privat'), 'Die gemeinsame Klasse steht in der Spalte'); $this->assert(!str_contains($zelle, 'class="marke"'), 'Ohne Marke „Splitbuchung“'); $this->assert(str_contains($zelle, 'data-split="1"'), 'Der Klick führt in den Splitdialog'); $this->assert( str_contains($zelle, 'data-klasse="' . $this->privat . '"'), 'Die Zelle trägt die gemeinsame Klasse' ); } private function kontoblattZeigtMarkeBeiVerschiedenenKlassen(): void { $id = $this->splitbuchung('Mischmarkt', $this->privat, $this->beruf); $zelle = $this->klassenzelle($id); $this->assert( str_contains($zelle, 'Splitbuchung'), 'Verschiedene Klassen zeigen die Marke „Splitbuchung“' ); $this->assert( str_contains($zelle, 'title="Splitklasse Lebensmittel: Splitklasse Privat' . "\n" . 'Splitklasse Drogerie: Splitklasse Beruf"'), 'Der Tooltip nennt je Splitzeile Kategorie und Klasse' ); $this->assert( !str_contains($zelle, 'Splitklasse Buchungsklasse'), 'Die Klasse der Buchung selbst spielt keine Rolle' ); } private function ohneSplitBleibtEsBeiDerBuchungsklasse(): void { $id = Buchung::anlegen([ 'konto_id' => $this->konto, 'datum' => '2026-05-03', 'betrag' => -12.00, 'empfaenger' => 'Einzelmarkt', 'kategorie_id' => $this->lebensmittel, 'klasse_id' => $this->beruf, ]); $zelle = $this->klassenzelle($id); $this->assert(str_contains($zelle, 'Splitklasse Beruf'), 'Eine einfache Buchung zeigt ihre Klasse'); $this->assert(!str_contains($zelle, 'data-split'), 'Und öffnet weiter die Klassenliste'); } private function splitbuchung(string $empfaenger, int $klasseA, int $klasseB): int { return Buchung::anlegen( [ 'konto_id' => $this->konto, 'datum' => '2026-05-02', 'betrag' => -30.00, 'empfaenger' => $empfaenger, 'klasse_id' => $this->alt, ], [ ['kategorie_id' => $this->lebensmittel, 'klasse_id' => $klasseA, 'betrag' => -20.00], ['kategorie_id' => $this->drogerie, 'klasse_id' => $klasseB, 'betrag' => -10.00], ] ); } /** * Die Klassenzelle einer Buchung aus dem gerenderten Kontoblatt. */ private function klassenzelle(int $buchungId): string { $html = $this->kontoblattHtml(); $muster = '#