mandantAnlegen(); $this->giro = Konto::anlegen([ 'name' => 'Fälligkeitsgiro', 'kontoart' => 'bank', 'anfangssaldo' => 0, 'aktiv' => 1, ]); $this->loeschenOeffnetTerminWieder(); $this->aeltereVonZweienGeloescht(); $this->beendeteReiheWirdAktiv(); $this->manuelleBuchungBleibtUnberuehrt(); $this->buchungstextWirdUebernommen(); $this->naechsterTerminLaesstSichSetzen(); $this->buchenMitAbweichendemDatum(); } private function reihe(string $name, string $beginn, ?string $ende = null): int { return RegelmaessigeBuchung::anlegen([ 'name' => $name, 'konto_id' => $this->giro, 'betrag' => -10, 'intervall' => 'monatlich', 'beginn' => $beginn, 'ende' => $ende, 'aktiv' => 1, ]); } private function faelligkeit(int $id): string { return (string)RegelmaessigeBuchung::find($id)['naechste_faelligkeit']; } private function loeschenOeffnetTerminWieder(): void { $id = $this->reihe('Löschtest', '2026-06-01'); $buchung = RegelmaessigeBuchung::buchen($id); $this->assertEquals($id, (int)Buchung::find($buchung)['regelmaessige_id'], 'Die Buchung kennt ihre Reihe'); $this->assertEquals('2026-06-01', (string)Buchung::find($buchung)['faelligkeit'], 'Und ihren Termin'); $this->assert($this->faelligkeit($id) > '2026-06-01', 'Nach dem Buchen ist der Termin fortgeschrieben'); Buchung::loeschen($buchung); $this->assertEquals('2026-06-01', $this->faelligkeit($id), 'Nach dem Löschen steht der Termin wieder an'); $this->assertNull(RegelmaessigeBuchung::find($id)['zuletzt_am'], 'Ohne verbleibende Buchung kein letztes Datum'); } private function aeltereVonZweienGeloescht(): void { $id = $this->reihe('Zwei Termine', '2026-03-01'); $erste = RegelmaessigeBuchung::buchen($id); $zweite = RegelmaessigeBuchung::buchen($id); Buchung::loeschen($erste); $this->assertEquals('2026-03-01', $this->faelligkeit($id), 'Es gilt der älteste offene Termin'); $this->assertEquals( (string)Buchung::find($zweite)['datum'], (string)RegelmaessigeBuchung::find($id)['zuletzt_am'], 'zuletzt_am folgt der verbleibenden Buchung' ); } private function beendeteReiheWirdAktiv(): void { $id = $this->reihe('Befristet', '2026-07-01', '2026-07-31'); $buchung = RegelmaessigeBuchung::buchen($id); $this->assertEquals(0, (int)RegelmaessigeBuchung::find($id)['aktiv'], 'Die Reihe ist ausgelaufen'); Buchung::loeschen($buchung); $this->assertEquals(1, (int)RegelmaessigeBuchung::find($id)['aktiv'], 'Das Löschen öffnet sie wieder'); $this->assertEquals('2026-07-01', $this->faelligkeit($id), 'Mit dem gelöschten Termin'); } private function manuelleBuchungBleibtUnberuehrt(): void { $id = $this->reihe('Unbeteiligt', '2026-09-01'); $vorher = $this->faelligkeit($id); $manuell = Buchung::anlegen(['konto_id' => $this->giro, 'datum' => '2026-08-01', 'betrag' => -5]); Buchung::loeschen($manuell); $this->assertEquals($vorher, $this->faelligkeit($id), 'Eine freie Buchung ändert keine Fälligkeit'); } private function buchungstextWirdUebernommen(): void { $id = RegelmaessigeBuchung::anlegen([ 'name' => 'Mit Text', 'konto_id' => $this->giro, 'betrag' => -10, 'buchungstext' => 'Miete Oktober', 'intervall' => 'monatlich', 'beginn' => '2026-10-01', 'aktiv' => 1, ]); $this->assertEquals('Miete Oktober', (string)RegelmaessigeBuchung::find($id)['buchungstext'], 'Der Buchungstext wird gespeichert'); $buchung = RegelmaessigeBuchung::buchen($id); $this->assertEquals('Miete Oktober', (string)Buchung::find($buchung)['buchungstext'], 'Und in die Buchung übernommen'); } private function naechsterTerminLaesstSichSetzen(): void { $id = $this->reihe('Verschiebbar', '2026-10-01'); $daten = RegelmaessigeBuchung::find($id); RegelmaessigeBuchung::speichern($id, $daten); $this->assertEquals('2026-10-01', $this->faelligkeit($id), 'Speichern ohne Änderung lässt den Termin stehen'); RegelmaessigeBuchung::speichern($id, ['naechste_faelligkeit' => '2026-12-15'] + $daten); $this->assertEquals('2026-12-15', $this->faelligkeit($id), 'Ein gesetzter Termin gilt'); RegelmaessigeBuchung::speichern($id, ['naechste_faelligkeit' => 'Unsinn'] + $daten); $this->assertEquals('2026-12-15', $this->faelligkeit($id), 'Ungültige Angaben werden ignoriert'); } private function buchenMitAbweichendemDatum(): void { $id = $this->reihe('Datumsbuchung', '2026-10-01'); $b1 = RegelmaessigeBuchung::buchen($id, ['datum' => '', 'betrag' => '']); $this->assertEquals('2026-10-01', (string)Buchung::find($b1)['datum'], 'Leeres Datum bucht zum Termin'); $id = $this->reihe('Datumsbuchung 2', '2026-10-01'); $termin = $this->faelligkeit($id); $b2 = RegelmaessigeBuchung::buchen($id, ['datum' => '2026-10-05']); $this->assertEquals('2026-10-05', (string)Buchung::find($b2)['datum'], 'Das gewählte Datum ist das Buchungsdatum'); $this->assertEquals($termin, (string)Buchung::find($b2)['faelligkeit'], 'Der Termin der Reihe bleibt der gespeicherte'); $fehler = false; try { RegelmaessigeBuchung::buchen($id, ['datum' => '31.02.2026']); } catch (\InvalidArgumentException) { $fehler = true; } $this->assert($fehler, 'Ein ungültiges Datum wird abgewiesen'); } }