mandantAnlegen(); $this->stammdaten(); $this->haendlerWirdAusDemVerwendungszweckGelesen(); $this->andereUmsaetzeBleibenOhneEmpfaenger(); $this->erneuterAbrufTraegtDenEmpfaengerNach(); $this->vorhandenerEmpfaengerBleibt(); } private function stammdaten(): void { $this->giro = Konto::anlegen([ 'name' => 'Karten-Giro', 'kontoart' => 'bank', 'anfangssaldo' => 0, 'aktiv' => 1, ]); $this->zugang = Bankzugang::anlegen([ 'name' => 'Kartenbank', 'bankname' => 'Kartenbank AG', 'blz' => '12030000', 'fints_url' => 'https://banking.example.org/fints', 'benutzerkennung' => 'testkunde', 'pin' => 'geheim1234', 'abrufzeitraum' => 'letzter_abruf', 'aktiv' => 1, ]); } private function haendlerWirdAusDemVerwendungszweckGelesen(): void { $this->assertEquals( 'TINDIE, EZPLM.COM US', UmsatzEmpfaenger::ausVerwendungszweck(self::TINDIE), 'Der Händler steht zwischen Buchungstext und Kartennummer' ); $this->assertEquals( 'ANTHROPIC* CLAUDE SUB, ANTHROPIC.COM US', UmsatzEmpfaenger::ausVerwendungszweck( 'KARTENVERFÜGUNGANTHROPIC* CLAUDE SUB, ANTHROPIC.COM USKARTE NR. 4871 78XX XXXX 9119' . 'KARTENZAHLUNGCOMDIRECT VISA-DEBITKARTE2026-09-24 20:46:00' ), 'Auch ein Händlername über zwei Zeilen' ); $this->assertEquals( 'BAECKEREI MUELLER', UmsatzEmpfaenger::ausVerwendungszweck('KARTENVERFUEGUNG BAECKEREI MUELLER KARTE NR. 1234'), 'Auch in Umschrift' ); } private function andereUmsaetzeBleibenOhneEmpfaenger(): void { $this->assertEquals( '', UmsatzEmpfaenger::ausVerwendungszweck( 'KONTOABSCHLUSSABSCHLUSS ZINSEN KTO 847626905EURVON 30.06.2026 BIS 30.09.2026' ), 'Ein Kontoabschluss hat keinen Empfänger' ); $this->assertEquals( '', UmsatzEmpfaenger::ausVerwendungszweck( 'LASTSCHRIFT / BELASTUNGDB FERNVERKEHR AG, FRANKFURT DEKARTE NR. 4871 78XX XXXX 9119' ), 'Eine Lastschrift bringt ihren Empfänger selbst mit' ); } /** @param array $daten */ private function umsatz(string $externId, array $daten = []): ?int { return Bankumsatz::anlegen(array_merge([ 'zugang_id' => $this->zugang, 'konto_id' => $this->giro, 'extern_id' => $externId, 'buchungstag' => '2026-10-02', 'wertstellung' => '2026-10-02', 'betrag' => -25.48, 'empfaenger' => '', 'verwendungszweck' => self::TINDIE, ], $daten)); } private function erneuterAbrufTraegtDenEmpfaengerNach(): void { $externId = 'karte-' . bin2hex(random_bytes(4)); $umsatzId = (int)$this->umsatz($externId); $buchungId = Bankumsatz::uebernehmen($umsatzId); $this->assertEquals('', Buchung::find($buchungId)['empfaenger'], 'Vorher ohne Empfänger übernommen'); $wieder = $this->umsatz($externId, ['empfaenger' => 'TINDIE, EZPLM.COM US']); $this->assertNull($wieder, 'Der erneute Abruf legt keinen zweiten Umsatz an'); $this->assertEquals( 'TINDIE, EZPLM.COM US', Bankumsatz::find($umsatzId)['empfaenger'], 'Der Umsatz bekommt den Empfänger nachgetragen' ); $this->assertEquals( 'TINDIE, EZPLM.COM US', Buchung::find($buchungId)['empfaenger'], 'Ebenso die übernommene Buchung' ); } private function vorhandenerEmpfaengerBleibt(): void { $externId = 'karte-' . bin2hex(random_bytes(4)); $umsatzId = (int)$this->umsatz($externId, ['empfaenger' => 'Tindie', 'betrag' => -12.30]); $buchungId = Bankumsatz::uebernehmen($umsatzId); Database::execute( "UPDATE buchungen SET empfaenger = 'Tindie Elektronik' WHERE id = ?", [$buchungId] ); $this->umsatz($externId, ['empfaenger' => 'TINDIE, EZPLM.COM US', 'betrag' => -12.30]); $this->assertEquals('Tindie', Bankumsatz::find($umsatzId)['empfaenger'], 'Der Umsatz behält seinen Empfänger'); $this->assertEquals( 'Tindie Elektronik', Buchung::find($buchungId)['empfaenger'], 'Die Buchung behält den von Hand gesetzten Empfänger' ); } }