Kontenzuordnung als dritter Einrichtungsschritt: Welches Bankkonto gehört zu welchem eigenen Konto? Umsätze merken sich über `bank_konto_id`, woher sie stammen, und ziehen mit, wenn die Zuordnung erst nach einem Abruf fällt. Abgerufene Umsätze buchen sich auf Wunsch selbst (`Services\Bankabgleich`). Im Kontoblatt lassen sich Buchungen sammelweise löschen; Statusmeldungen liegen jetzt über der Ansicht, statt den Inhalt springen zu lassen. Dazu drei Fehler, die zusammen dafür sorgten, dass abgerufene Umsätze spurlos verschwanden – der Abruf meldete sie als vorhanden, das Kontoblatt zeigte nichts, und in der Vorschlagsliste standen sie ebenfalls nicht: - Eine gelöschte Buchung ließ ihren Umsatz auf „uebernommen“ stehen. Der Fremdschlüssel setzte nur `buchung_id` auf NULL. `Buchung::loeschen()` gibt den Umsatz jetzt vorher frei, `Bankumsatz::verwaisteOeffnen()` fängt die Wege ab, die daran vorbeiführen – Kaskaden lösen in MariaDB keine Trigger aus. - Ein Bankkonto entstand doppelt, wenn die Bank die IBAN nicht bei jedem Dialog mitliefert. Gesucht wird jetzt über die Kontonummer; eine nachgelieferte IBAN wird am vorhandenen Eintrag nachgetragen. - Der Fingerabdruck hing an der IBAN und kippte mit ihr. Er nimmt jetzt die `bank_konto_id`, die fest steht, solange es den Bankzugang gibt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
486 lines
18 KiB
PHP
486 lines
18 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
use Finanzmanager\Controllers\BankingController;
|
||
use Finanzmanager\Database;
|
||
use Finanzmanager\Models\AbgleichRegel;
|
||
use Finanzmanager\Models\Bankumsatz;
|
||
use Finanzmanager\Models\Bankzugang;
|
||
use Finanzmanager\Models\Buchung;
|
||
use Finanzmanager\Models\Einstellung;
|
||
use Finanzmanager\Models\Kategorie;
|
||
use Finanzmanager\Models\Konto;
|
||
use Finanzmanager\Models\Monatsabschluss;
|
||
use Finanzmanager\Services\Bankabgleich;
|
||
|
||
/**
|
||
* Kontenzuordnung und automatisches Buchen.
|
||
*
|
||
* Der Weg, den ein Umsatz nimmt, wenn die Zuordnung Bankkonto → eigenes Konto
|
||
* erst nach dem Abruf getroffen wird – und was danach von allein im Kontoblatt
|
||
* landet. Der FinTS-Dialog selbst bleibt außen vor: Geprüft wird, was mit seinem
|
||
* Ergebnis geschieht.
|
||
*/
|
||
class KontenzuordnungTest extends TestCase
|
||
{
|
||
protected string $testName = 'Test 19: Kontenzuordnung und automatisches Buchen';
|
||
|
||
private int $giro = 0;
|
||
private int $zweitkonto = 0;
|
||
private int $strom = 0;
|
||
private int $zugang = 0;
|
||
private int $bankkonto = 0;
|
||
private int $zweitesBankkonto = 0;
|
||
|
||
public function run(): void
|
||
{
|
||
$this->mandantAnlegen();
|
||
$this->stammdaten();
|
||
|
||
$this->zuordnungZiehtOffeneUmsaetzeNach();
|
||
$this->automatischesBuchenLegtBuchungenAn();
|
||
$this->automatischesBuchenVerbindetStattZuDoppeln();
|
||
$this->umsaetzeOhneKontoBleibenLiegen();
|
||
$this->einZeitverriegelterUmsatzBrichtDenLaufNichtAb();
|
||
$this->abgeschalteteAutomatikBuchtNicht();
|
||
$this->allesUebernehmenBleibtZurueckhaltend();
|
||
$this->unkategorisierteZaehlenJeKonto();
|
||
$this->kontenuebersichtKenntDieOffenenBuchungen();
|
||
$this->dieEinrichtungEndetInDerUebersicht();
|
||
}
|
||
|
||
private function stammdaten(): void
|
||
{
|
||
$this->giro = Konto::anlegen([
|
||
'name' => 'Zuordnungsgiro', 'kontoart' => 'bank', 'anfangssaldo' => 0, 'aktiv' => 1,
|
||
]);
|
||
$this->zweitkonto = Konto::anlegen([
|
||
'name' => 'Zuordnungssparbuch', 'kontoart' => 'sparkonto', 'anfangssaldo' => 0, 'aktiv' => 1,
|
||
]);
|
||
|
||
$this->strom = Kategorie::findenOderAnlegenNachPfad('300 - Wohnen:Strom Zuordnung', 'ausgabe');
|
||
|
||
$this->zugang = Bankzugang::anlegen([
|
||
'name' => 'Zuordnungsbank',
|
||
'bankname' => 'Zuordnungsbank AG',
|
||
'blz' => '12030000',
|
||
'fints_url' => 'https://banking.example.org/fints',
|
||
'benutzerkennung' => 'testkunde',
|
||
'pin' => 'geheim1234',
|
||
'abrufzeitraum' => 'letzter_abruf',
|
||
'aktiv' => 1,
|
||
]);
|
||
|
||
// So legt der Abruf ein bei der Bank gefundenes Konto an: erst einmal
|
||
// ohne Zuordnung, denn welches eigene Konto gemeint ist, weiß nur der
|
||
// Nutzer.
|
||
$this->bankkonto = (int)Bankzugang::findeOderLegeKontoAn(
|
||
$this->zugang,
|
||
'DE29120300000000202052',
|
||
'202052',
|
||
'Girokonto'
|
||
)['id'];
|
||
$this->zweitesBankkonto = (int)Bankzugang::findeOderLegeKontoAn(
|
||
$this->zugang,
|
||
'DE44120300000000202053',
|
||
'202053',
|
||
'Sparkonto'
|
||
)['id'];
|
||
|
||
Einstellung::set('banking_automatisch_buchen', '1', 'banking');
|
||
Einstellung::set('banking_abgleich_tage', '5', 'banking');
|
||
}
|
||
|
||
/** @param array<string,mixed> $daten */
|
||
private function umsatzAnlegen(array $daten): int
|
||
{
|
||
$id = Bankumsatz::anlegen([
|
||
'zugang_id' => $this->zugang,
|
||
'konto_id' => $daten['konto_id'] ?? null,
|
||
'bank_konto_id' => $daten['bank_konto_id'] ?? $this->bankkonto,
|
||
'extern_id' => Bankumsatz::externId(
|
||
(int)($daten['bank_konto_id'] ?? $this->bankkonto),
|
||
(string)$daten['buchungstag'],
|
||
(float)$daten['betrag'],
|
||
(string)($daten['verwendungszweck'] ?? ''),
|
||
(string)($daten['empfaenger'] ?? '')
|
||
),
|
||
'buchungstag' => $daten['buchungstag'],
|
||
'wertstellung' => $daten['buchungstag'],
|
||
'betrag' => $daten['betrag'],
|
||
'empfaenger' => $daten['empfaenger'] ?? '',
|
||
'verwendungszweck' => $daten['verwendungszweck'] ?? '',
|
||
'buchungsart' => 'LASTSCHRIFT',
|
||
]);
|
||
|
||
$this->assertNotEmpty($id, 'Umsatz angelegt: ' . ($daten['verwendungszweck'] ?? ''));
|
||
|
||
return (int)$id;
|
||
}
|
||
|
||
private function heute(string $tage = ''): string
|
||
{
|
||
return (new \DateTimeImmutable($tage === '' ? 'today' : 'today ' . $tage))->format('Y-m-d');
|
||
}
|
||
|
||
/**
|
||
* Der Kern des dritten Einrichtungsschritts: Umsätze, die vor der Zuordnung
|
||
* hereinkamen, dürfen nicht ohne Konto stehen bleiben – sonst ließen sie
|
||
* sich nie buchen.
|
||
*/
|
||
private function zuordnungZiehtOffeneUmsaetzeNach(): void
|
||
{
|
||
$offen = $this->umsatzAnlegen([
|
||
'buchungstag' => $this->heute('-3 days'), 'betrag' => -49.90,
|
||
'empfaenger' => 'Stadtwerke Zuordnung', 'verwendungszweck' => 'Abschlag Strom',
|
||
]);
|
||
|
||
$this->assertNull(
|
||
Bankumsatz::find($offen)['konto_id'],
|
||
'Vor der Zuordnung hat der Umsatz kein Konto'
|
||
);
|
||
|
||
Bankzugang::ordneKontoZu($this->bankkonto, $this->giro);
|
||
|
||
$this->assertEquals(
|
||
$this->giro,
|
||
(int)Bankumsatz::find($offen)['konto_id'],
|
||
'Mit der Zuordnung bekommt der offene Umsatz sein Konto'
|
||
);
|
||
|
||
// Ein Umsatz des anderen Bankkontos darf davon nichts abbekommen.
|
||
$fremd = $this->umsatzAnlegen([
|
||
'bank_konto_id' => $this->zweitesBankkonto,
|
||
'buchungstag' => $this->heute('-3 days'), 'betrag' => -7.10,
|
||
'empfaenger' => 'Sparkonto', 'verwendungszweck' => 'Anderes Bankkonto',
|
||
]);
|
||
$this->assertNull(
|
||
Bankumsatz::find($fremd)['konto_id'],
|
||
'Die Zuordnung greift nur auf das Bankkonto, um das es geht'
|
||
);
|
||
|
||
Bankzugang::ordneKontoZu($this->zweitesBankkonto, $this->zweitkonto);
|
||
$this->assertEquals(
|
||
$this->zweitkonto,
|
||
(int)Bankumsatz::find($fremd)['konto_id'],
|
||
'Und dann auch dort'
|
||
);
|
||
|
||
// Übernommene bleiben, wo sie sind: Ihre Buchung steht bereits in einem
|
||
// Kontoblatt, ein Kontowechsel würde sie dort wegziehen.
|
||
$gebucht = $this->umsatzAnlegen([
|
||
'konto_id' => $this->giro,
|
||
'buchungstag' => $this->heute('-2 days'), 'betrag' => -11.00,
|
||
'empfaenger' => 'Bäcker', 'verwendungszweck' => 'Schon gebucht',
|
||
]);
|
||
Bankumsatz::uebernehmen($gebucht, ['kategorie_id' => $this->strom]);
|
||
|
||
Bankzugang::ordneKontoZu($this->bankkonto, $this->zweitkonto);
|
||
$this->assertEquals(
|
||
$this->giro,
|
||
(int)Bankumsatz::find($gebucht)['konto_id'],
|
||
'Ein übernommener Umsatz wandert nicht mit'
|
||
);
|
||
|
||
Bankzugang::ordneKontoZu($this->bankkonto, $this->giro);
|
||
}
|
||
|
||
private function automatischesBuchenLegtBuchungenAn(): void
|
||
{
|
||
AbgleichRegel::anlegen([
|
||
'name' => 'Strom Zuordnung', 'feld' => 'verwendungszweck', 'vergleich' => 'enthaelt',
|
||
'muster' => 'Abschlag Strom', 'kategorie_id' => $this->strom, 'prioritaet' => 10, 'aktiv' => 1,
|
||
]);
|
||
|
||
$ohneRegel = $this->umsatzAnlegen([
|
||
'konto_id' => $this->giro,
|
||
'buchungstag' => $this->heute('-1 day'), 'betrag' => -23.45,
|
||
'empfaenger' => 'Unbekannt GmbH', 'verwendungszweck' => 'Keine Regel trifft',
|
||
]);
|
||
|
||
$vorher = Buchung::anzahl();
|
||
$ergebnis = Bankabgleich::automatisch();
|
||
|
||
$this->assertNotEmpty($ergebnis, 'Eingeschaltet läuft der automatische Abgleich');
|
||
$this->assertEquals(0, $ergebnis['offen'], 'Nichts bleibt liegen');
|
||
$this->assertEquals(
|
||
$vorher + $ergebnis['uebernommen'],
|
||
Buchung::anzahl(),
|
||
'Für jeden übernommenen Umsatz steht eine Buchung mehr da'
|
||
);
|
||
|
||
// Der Umsatz mit Regel bekommt seine Kategorie …
|
||
$mitRegel = Bankumsatz::liste(['status' => 'uebernommen']);
|
||
$strom = null;
|
||
foreach ($mitRegel as $eintrag) {
|
||
if (str_contains((string)$eintrag['verwendungszweck'], 'Abschlag Strom')) {
|
||
$strom = $eintrag;
|
||
}
|
||
}
|
||
$this->assertNotEmpty($strom, 'Der Umsatz mit Regel ist übernommen');
|
||
$this->assertEquals(
|
||
$this->strom,
|
||
(int)Buchung::find((int)$strom['buchung_id'])['kategorie_id'],
|
||
'Die Kategorie kommt aus der Regel'
|
||
);
|
||
|
||
// … der ohne Regel wird trotzdem gebucht. Genau dafür ist die Automatik
|
||
// da: Der Umsatz soll im Kontoblatt stehen, die Kategorie kommt später.
|
||
$buchungOhneRegel = Buchung::find((int)Bankumsatz::find($ohneRegel)['buchung_id']);
|
||
$this->assertEquals(
|
||
'uebernommen',
|
||
Bankumsatz::find($ohneRegel)['status'],
|
||
'Auch ohne Regel wird gebucht'
|
||
);
|
||
$this->assertNull($buchungOhneRegel['kategorie_id'], 'Aber ohne Kategorie');
|
||
$this->assertEquals($this->giro, (int)$buchungOhneRegel['konto_id'], 'Im zugeordneten Konto');
|
||
$this->assertEquals('fints', $buchungOhneRegel['quelle'], 'Und mit dem Bankabruf als Quelle');
|
||
}
|
||
|
||
/** Wer seine Buchungen selbst erfasst, will sie nicht doppelt sehen. */
|
||
private function automatischesBuchenVerbindetStattZuDoppeln(): void
|
||
{
|
||
$buchungId = Buchung::anlegen([
|
||
'konto_id' => $this->giro, 'datum' => $this->heute('-4 days'), 'betrag' => -128.00,
|
||
'empfaenger' => 'Versicherung', 'kategorie_id' => $this->strom,
|
||
]);
|
||
|
||
$umsatz = $this->umsatzAnlegen([
|
||
'konto_id' => $this->giro,
|
||
'buchungstag' => $this->heute('-2 days'), 'betrag' => -128.00,
|
||
'empfaenger' => 'Versicherung AG', 'verwendungszweck' => 'Beitrag',
|
||
]);
|
||
|
||
$vorher = Buchung::anzahl();
|
||
$ergebnis = Bankabgleich::automatisch();
|
||
|
||
$this->assertEquals(1, $ergebnis['verbunden'], 'Der Umsatz wurde verbunden');
|
||
$this->assertEquals($vorher, Buchung::anzahl(), 'Und keine zweite Buchung angelegt');
|
||
$this->assertEquals(
|
||
$buchungId,
|
||
(int)Bankumsatz::find($umsatz)['buchung_id'],
|
||
'Er zeigt auf die selbst erfasste Buchung'
|
||
);
|
||
$this->assertEquals(
|
||
1,
|
||
(int)Buchung::find($buchungId)['abgeglichen'],
|
||
'Die gilt damit als abgeglichen'
|
||
);
|
||
}
|
||
|
||
private function umsaetzeOhneKontoBleibenLiegen(): void
|
||
{
|
||
// Ein Bankkonto ohne Zuordnung – etwa ein Depot, das nicht mitgeführt wird.
|
||
$ohne = Bankzugang::findeOderLegeKontoAn($this->zugang, 'DE60120300000000202054', '202054', 'Ohne');
|
||
|
||
$umsatz = $this->umsatzAnlegen([
|
||
'bank_konto_id' => (int)$ohne['id'],
|
||
'buchungstag' => $this->heute('-1 day'), 'betrag' => -9.99,
|
||
'empfaenger' => 'Ohne Zuordnung', 'verwendungszweck' => 'Bleibt offen',
|
||
]);
|
||
|
||
$ergebnis = Bankabgleich::automatisch();
|
||
|
||
$this->assertEquals(1, $ergebnis['offen'], 'Ein Umsatz ohne Konto bleibt offen');
|
||
$this->assertEquals(
|
||
'offen',
|
||
Bankumsatz::find($umsatz)['status'],
|
||
'Und steht weiter in der Vorschlagsliste'
|
||
);
|
||
$this->assertEquals([], $ergebnis['fehler'], 'Ohne Fehlermeldung – das ist kein Fehler');
|
||
}
|
||
|
||
/**
|
||
* Ein Umsatz, der sich nicht buchen lässt, darf die übrigen nicht mitreißen.
|
||
* Der abgeschlossene Monat ist der greifbarste Fall davon.
|
||
*/
|
||
private function einZeitverriegelterUmsatzBrichtDenLaufNichtAb(): void
|
||
{
|
||
$jahr = (int)date('Y') - 1;
|
||
$datum = sprintf('%d-03-15', $jahr);
|
||
|
||
Monatsabschluss::abschliessen($jahr, 3, 'Test');
|
||
|
||
$verriegelt = $this->umsatzAnlegen([
|
||
'konto_id' => $this->giro,
|
||
'buchungstag' => $datum, 'betrag' => -31.00,
|
||
'empfaenger' => 'Aus dem Archiv', 'verwendungszweck' => 'Abgeschlossener Monat',
|
||
]);
|
||
$daneben = $this->umsatzAnlegen([
|
||
'konto_id' => $this->giro,
|
||
'buchungstag' => $this->heute(), 'betrag' => -6.60,
|
||
'empfaenger' => 'Heute', 'verwendungszweck' => 'Geht durch',
|
||
]);
|
||
|
||
$ergebnis = Bankabgleich::automatisch();
|
||
|
||
$this->assertEquals(1, count($ergebnis['fehler']), 'Ein Umsatz ließ sich nicht buchen');
|
||
$this->assertEquals(
|
||
'offen',
|
||
Bankumsatz::find($verriegelt)['status'],
|
||
'Er bleibt offen und wartet auf die Wiedereröffnung'
|
||
);
|
||
$this->assertEquals(
|
||
'uebernommen',
|
||
Bankumsatz::find($daneben)['status'],
|
||
'Der Umsatz daneben wurde trotzdem gebucht'
|
||
);
|
||
$this->assert(
|
||
str_contains(Bankabgleich::bericht($ergebnis), 'Nicht gebucht'),
|
||
'Der Bericht nennt den Fall'
|
||
);
|
||
|
||
$abschluss = Monatsabschluss::fuerMonat($jahr, 3);
|
||
Monatsabschluss::wiedereroeffnen((int)$abschluss['id']);
|
||
}
|
||
|
||
private function abgeschalteteAutomatikBuchtNicht(): void
|
||
{
|
||
Einstellung::set('banking_automatisch_buchen', '0', 'banking');
|
||
|
||
$umsatz = $this->umsatzAnlegen([
|
||
'konto_id' => $this->giro,
|
||
'buchungstag' => $this->heute(), 'betrag' => -4.20,
|
||
'empfaenger' => 'Kiosk', 'verwendungszweck' => 'Von Hand abgleichen',
|
||
]);
|
||
|
||
$this->assertNull(Bankabgleich::automatisch(), 'Abgeschaltet läuft nichts');
|
||
$this->assertEquals(
|
||
'offen',
|
||
Bankumsatz::find($umsatz)['status'],
|
||
'Der Umsatz wartet auf den Abgleich'
|
||
);
|
||
|
||
Einstellung::set('banking_automatisch_buchen', '1', 'banking');
|
||
}
|
||
|
||
/**
|
||
* Der Knopf „Alles übernehmen“ ist zurückhaltender als die Automatik: Ohne
|
||
* Regel bleibt der Umsatz liegen, damit die Zuordnung beim Nutzer bleibt.
|
||
*/
|
||
private function allesUebernehmenBleibtZurueckhaltend(): void
|
||
{
|
||
$ergebnis = Bankabgleich::laufenLassen(false);
|
||
|
||
$this->assertEquals(0, $ergebnis['uebernommen'], 'Ohne Regel wird nichts gebucht');
|
||
$this->assertGreaterThan(0, $ergebnis['offen'], 'Die Umsätze bleiben offen');
|
||
|
||
// Mit Regel greift derselbe Lauf dann doch.
|
||
AbgleichRegel::anlegen([
|
||
'name' => 'Kiosk Zuordnung', 'feld' => 'empfaenger', 'vergleich' => 'enthaelt',
|
||
'muster' => 'Kiosk', 'kategorie_id' => $this->strom, 'prioritaet' => 10, 'aktiv' => 1,
|
||
]);
|
||
|
||
$mitRegel = Bankabgleich::laufenLassen(false);
|
||
$this->assertEquals(1, $mitRegel['uebernommen'], 'Mit Regel wird gebucht');
|
||
}
|
||
|
||
private function unkategorisierteZaehlenJeKonto(): void
|
||
{
|
||
$jahr = (int)date('Y');
|
||
|
||
$vorher = Buchung::unkategorisierteJeKonto($jahr)[$this->giro] ?? 0;
|
||
|
||
Buchung::anlegen([
|
||
'konto_id' => $this->giro, 'datum' => $this->heute(), 'betrag' => -15.00,
|
||
'empfaenger' => 'Ohne Kategorie',
|
||
]);
|
||
|
||
$this->assertEquals(
|
||
$vorher + 1,
|
||
Buchung::unkategorisierteJeKonto($jahr)[$this->giro] ?? 0,
|
||
'Eine Buchung ohne Kategorie zählt mit'
|
||
);
|
||
|
||
// Eine Umbuchung ist zugeordnet, auch ohne Kategorie.
|
||
Buchung::anlegen([
|
||
'konto_id' => $this->giro, 'datum' => $this->heute(), 'betrag' => -100.00,
|
||
'empfaenger' => 'Umbuchung', 'gegenkonto_id' => $this->zweitkonto,
|
||
]);
|
||
|
||
// Eine Splitbuchung trägt ihre Zuordnung in den Zeilen.
|
||
Buchung::anlegen(
|
||
[
|
||
'konto_id' => $this->giro, 'datum' => $this->heute(), 'betrag' => -50.00,
|
||
'empfaenger' => 'Gesplittet',
|
||
],
|
||
[
|
||
['kategorie_id' => $this->strom, 'betrag' => -30.00],
|
||
['kategorie_id' => $this->strom, 'betrag' => -20.00],
|
||
]
|
||
);
|
||
|
||
$this->assertEquals(
|
||
$vorher + 1,
|
||
Buchung::unkategorisierteJeKonto($jahr)[$this->giro] ?? 0,
|
||
'Umbuchung und Splitbuchung zählen nicht als unkategorisiert'
|
||
);
|
||
|
||
// Das Vorjahr bleibt außen vor – die Übersicht zeigt das laufende Jahr.
|
||
Database::execute(
|
||
'UPDATE buchungen SET datum = ? WHERE benutzer_id = ? AND konto_id = ?
|
||
AND kategorie_id IS NULL AND gegenkonto_id IS NULL AND gesplittet = 0',
|
||
[($jahr - 1) . '-06-15', \Finanzmanager\Mandant::id(), $this->giro]
|
||
);
|
||
|
||
$this->assertEquals(
|
||
0,
|
||
Buchung::unkategorisierteJeKonto($jahr)[$this->giro] ?? 0,
|
||
'Buchungen aus dem Vorjahr zählen im laufenden Jahr nicht'
|
||
);
|
||
$this->assertGreaterThan(
|
||
0,
|
||
Buchung::unkategorisierteJeKonto($jahr - 1)[$this->giro] ?? 0,
|
||
'Dafür im Vorjahr'
|
||
);
|
||
}
|
||
|
||
private function kontenuebersichtKenntDieOffenenBuchungen(): void
|
||
{
|
||
Buchung::anlegen([
|
||
'konto_id' => $this->zweitkonto, 'datum' => $this->heute(), 'betrag' => -8.00,
|
||
'empfaenger' => 'Frisch abgerufen', 'quelle' => 'fints',
|
||
]);
|
||
|
||
$uebersicht = Konto::uebersicht();
|
||
|
||
$gefunden = [];
|
||
foreach ($uebersicht['gruppen'] as $gruppe) {
|
||
foreach ($gruppe['konten'] as $konto) {
|
||
$gefunden[(int)$konto['id']] = $konto;
|
||
}
|
||
}
|
||
|
||
$this->assertNotEmpty($gefunden[$this->zweitkonto] ?? null, 'Das Konto steht in der Übersicht');
|
||
$this->assertGreaterThan(
|
||
0,
|
||
(int)$gefunden[$this->zweitkonto]['unkategorisiert'],
|
||
'Und meldet seine Buchung ohne Kategorie – die Übersicht setzt es fett'
|
||
);
|
||
$this->assertEquals(
|
||
0,
|
||
(int)($gefunden[$this->giro]['unkategorisiert'] ?? -1),
|
||
'Das aufgeräumte Konto bleibt normal'
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Der letzte Schritt der Einrichtung führt zurück in die Übersicht der
|
||
* Bankverbindungen, nicht in die Zugangsmaske: Dort ist alles erledigt, was
|
||
* sie anbietet.
|
||
*/
|
||
private function dieEinrichtungEndetInDerUebersicht(): void
|
||
{
|
||
$this->assertEquals(
|
||
'/banking',
|
||
BankingController::zielNachZuordnung($this->zugang, true),
|
||
'Nach der Einrichtung geht es in die Übersicht der Bankverbindungen'
|
||
);
|
||
$this->assertEquals(
|
||
'/banking/' . $this->zugang . '/konten',
|
||
BankingController::zielNachZuordnung($this->zugang, false),
|
||
'Die einzeln aufgerufene Zuordnung bleibt, wo sie ist'
|
||
);
|
||
}
|
||
}
|