mandantAnlegen(); $this->depot = Konto::anlegen([ 'name' => 'Bankdepot', 'kontoart' => 'depot', 'kontonummer' => '502022353', 'anfangssaldo' => 0, 'aktiv' => 1, ]); $this->bestandUndKurs(); $this->vergleichZeigtAbweichungen(); $this->zweiterAbrufErsetztDenErsten(); $this->nachweisMitPruefsumme(); } private function position(string $isin, string $name, float $stueck, float $kurs): Holding { return (new Holding()) ->setISIN($isin) ->setName($name) ->setAmount($stueck) ->setPrice($kurs) ->setValue($stueck * $kurs) ->setCurrency('EUR') ->setDate(new \DateTime('2026-09-30')); } private function bestandUndKurs(): void { $bekannt = Wertpapier::findenOderAnlegen([ 'name' => 'Bekannte AG', 'isin' => 'DE0001111111', 'art' => 'aktie', ]); $ergebnis = Depotabgleich::uebernehmen($this->depot, [ $this->position('DE0001111111', 'Bekannte AG', 10.0, 12.5), $this->position('DE0002222222', 'Unbekannte AG', 4.0, 100.0), ]); $this->assertEquals(2, $ergebnis['positionen'], 'Beide Positionen stehen im Bankbestand'); $this->assertEquals(1, $ergebnis['kurse'], 'Nur das bekannte Papier bekommt einen Kurs'); $this->assertEquals( 12.5, (float)Wertpapier::letzterKurs($bekannt)['kurs'], 'Der Bewertungskurs der Bank ist der Kurs des Papiers' ); $this->assertNull( Wertpapier::finde('DE0002222222'), 'Das unbekannte Papier wird nicht angelegt' ); $this->assertNotEmpty(Depotabgleich::abgerufenAm($this->depot), 'Der Abrufzeitpunkt ist vermerkt'); } private function vergleichZeigtAbweichungen(): void { $bekannt = Wertpapier::finde('DE0001111111'); Depotbuchung::anlegen([ 'konto_id' => $this->depot, 'wertpapier_id' => (int)$bekannt['id'], 'vorgang' => 'kauf', 'datum' => '2026-01-05', 'stueck' => 8, 'kurs' => 10, 'betrag' => 80, ]); $verkauftes = Wertpapier::findenOderAnlegen([ 'name' => 'Alte AG', 'isin' => 'DE0003333333', 'art' => 'aktie', ]); Depotbuchung::anlegen([ 'konto_id' => $this->depot, 'wertpapier_id' => $verkauftes, 'vorgang' => 'kauf', 'datum' => '2026-01-05', 'stueck' => 3, 'kurs' => 10, 'betrag' => 30, ]); $je = []; foreach (Depotabgleich::vergleich($this->depot) as $zeile) { $je[$zeile['isin']] = $zeile; } $this->assertEquals(2.0, $je['DE0001111111']['abweichung'], 'Die Bank hat 2 Stück mehr als gebucht'); $this->assertEquals(4.0, $je['DE0002222222']['abweichung'], 'Nur bei der Bank: ganze Position abweichend'); $this->assertNull($je['DE0002222222']['eigen'], 'Für das unbekannte Papier gibt es keinen eigenen Bestand'); $this->assertEquals(-3.0, $je['DE0003333333']['abweichung'], 'Nur im Finanzmanager: Bank führt es nicht'); $this->assertNull($je['DE0003333333']['bank'], 'Bei der Bank fehlt das Papier'); } private function zweiterAbrufErsetztDenErsten(): void { Depotabgleich::uebernehmen($this->depot, [ $this->position('DE0001111111', 'Bekannte AG', 8.0, 13.0), ]); $bank = array_filter( Depotabgleich::vergleich($this->depot), static fn(array $zeile): bool => $zeile['bank'] !== null ); $this->assertEquals(1, count($bank), 'Der neue Abruf ersetzt den alten Bankbestand'); } private function nachweisMitPruefsumme(): void { $verrechnung = Konto::anlegen([ 'name' => 'Nachweisgiro', 'kontoart' => 'bank', 'anfangssaldo' => 100, 'aktiv' => 1, ]); $auftragId = Zahlungsauftrag::anlegen([ 'konto_id' => $verrechnung, 'empfaenger' => 'Beweis GmbH', 'iban' => 'DE02120300000000202051', 'betrag' => 12.34, 'verwendungszweck' => 'Rechnung 42', ]); $dialog = "> HNHBK:1:3+000000000100'\n< HIRMG:2:2+0010::Nachricht entgegengenommen'"; $id = Bankprotokoll::speichern(null, 'ueberweisung', 'erfolg', 'übergeben', $dialog, $auftragId); $this->assertNotEmpty($id, 'Das Protokoll wird gespeichert'); $auftrag = Zahlungsauftrag::find($auftragId); $nachweis = Bankprotokoll::nachweis($auftrag); $this->assert(str_contains($nachweis, 'Beweis GmbH'), 'Der Nachweis nennt den Empfänger'); $this->assert(str_contains($nachweis, $dialog), 'Der Nachweis enthält den vollständigen Dialog'); $this->assert(str_contains($nachweis, hash('sha256', $dialog)), 'Der Nachweis nennt die Prüfsumme'); $this->assert(str_contains($nachweis, 'unverändert seit dem Speichern'), 'Unveränderter Text wird bestätigt'); \Finanzmanager\Database::execute( 'UPDATE bank_protokolle SET protokoll = ? WHERE id = ?', [$dialog . "\nnachträglich", $id] ); $this->assert( str_contains(Bankprotokoll::nachweis($auftrag), 'ABWEICHUNG'), 'Ein nachträglich geänderter Text fällt im Nachweis auf' ); } }