Merge pull request 'Fix #119: Empfänger bei Kartenverfügungen aus dem Verwendungszweck lesen' (#122) from fds2610-bot/Finanzmanager:main into main
Reviewed-on: https://codeberg.org/fds2610/Finanzmanager/pulls/122
This commit is contained in:
commit
84ee4d4d04
7 changed files with 245 additions and 14 deletions
|
|
@ -1,5 +1,13 @@
|
||||||
# Änderungen
|
# Änderungen
|
||||||
|
|
||||||
|
## Kontoumsätze: Empfänger bei Kartenverfügungen (06.10.2026)
|
||||||
|
|
||||||
|
- Anlass (#119): Bei Zahlungen mit der comdirect Visa-Debitkarte (Kartenverfügung, GVC 700) blieb der Empfänger leer – die Bank liefert dafür kein Namensfeld (?32/?33), der Händler steht nur im Verwendungszweck zwischen „KARTENVERFÜGUNG“ und „KARTE NR.“.
|
||||||
|
- Fehlt der Name, liest der FinTS-Abruf ihn dort heraus (`Services/UmsatzEmpfaenger`, neu). Der Fingerabdruck des Umsatzes bleibt unverändert, bereits abgerufene Umsätze kommen nicht doppelt herein.
|
||||||
|
- Ein erneuter Abruf trägt den Empfänger bei bekannten Umsätzen und ihren Buchungen nach, wenn er dort leer ist (`Bankumsatz::ergaenzen()`).
|
||||||
|
- Migration `027_empfaenger_kartenverfuegung.sql` zieht vorhandene Kartenverfügungen und ihre Buchungen nach.
|
||||||
|
- Test: `tests/58_EmpfaengerKartenverfuegungTest.php`.
|
||||||
|
|
||||||
## Echtzeitüberweisung: Status bei der Bank nachfragen (06.10.2026)
|
## Echtzeitüberweisung: Status bei der Bank nachfragen (06.10.2026)
|
||||||
|
|
||||||
- Anlass (#113): Bei offenem Status (Rückmeldung 3045) blieb nur der Blick in den Kontoumsatz.
|
- Anlass (#113): Bei offenem Status (Rückmeldung 3045) blieb nur der Blick in den Kontoumsatz.
|
||||||
|
|
|
||||||
|
|
@ -409,6 +409,12 @@ Umsatz ein zweites Mal herein. Aus demselben Grund findet ein Bankkonto sich üb
|
||||||
**Kontonummer** wieder; eine später nachgelieferte IBAN wird am vorhandenen Eintrag
|
**Kontonummer** wieder; eine später nachgelieferte IBAN wird am vorhandenen Eintrag
|
||||||
nachgetragen, statt einen zweiten anzulegen.
|
nachgetragen, statt einen zweiten anzulegen.
|
||||||
|
|
||||||
|
Bei Kartenverfügungen liefert die Comdirect kein Namensfeld; der Händler steht nur im
|
||||||
|
Verwendungszweck zwischen „KARTENVERFÜGUNG“ und „KARTE NR.“. Fehlt der Name, liest der
|
||||||
|
Abruf ihn dort heraus (`UmsatzEmpfaenger`) – erst nach dem Fingerabdruck, der damit
|
||||||
|
derselbe bleibt. Ein erneuter Abruf trägt so gewonnene Empfänger bei bekannten Umsätzen
|
||||||
|
und ihren Buchungen nach, wo sie noch leer sind.
|
||||||
|
|
||||||
Verliert ein Umsatz seine Buchung – jemand löscht sie im Kontoblatt –, kehrt er in die
|
Verliert ein Umsatz seine Buchung – jemand löscht sie im Kontoblatt –, kehrt er in die
|
||||||
Vorschlagsliste zurück. Bliebe er auf *übernommen* stehen, wäre er nirgends mehr zu sehen:
|
Vorschlagsliste zurück. Bliebe er auf *übernommen* stehen, wäre er nirgends mehr zu sehen:
|
||||||
nicht im Kontoblatt, nicht in der Liste, und beim nächsten Abruf als schon vorhanden
|
nicht im Kontoblatt, nicht in der Liste, und beim nächsten Abruf als schon vorhanden
|
||||||
|
|
|
||||||
23
migrations/027_empfaenger_kartenverfuegung.sql
Normal file
23
migrations/027_empfaenger_kartenverfuegung.sql
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
-- Empfänger bei Kartenverfügungen nachtragen (#119).
|
||||||
|
--
|
||||||
|
-- Die comdirect liefert bei Kartenverfügungen der Visa-Debitkarte kein
|
||||||
|
-- Namensfeld; der Händler steht nur im Verwendungszweck zwischen
|
||||||
|
-- „KARTENVERFÜGUNG“ und „KARTE NR.“. Neue Abrufe leiten ihn ab
|
||||||
|
-- (UmsatzEmpfaenger), hier werden die bereits abgerufenen Umsätze und die
|
||||||
|
-- daraus übernommenen Buchungen nachgezogen – nur, wo der Empfänger leer ist.
|
||||||
|
--
|
||||||
|
-- Idempotent: Nach dem ersten Lauf ist der Empfänger nicht mehr leer.
|
||||||
|
|
||||||
|
UPDATE bank_umsaetze
|
||||||
|
SET empfaenger = LEFT(TRIM(REGEXP_REPLACE(
|
||||||
|
REGEXP_REPLACE(verwendungszweck, '(?s)^\\s*KARTENVERF(Ü|UE)GUNG\\s*(.+?)\\s*KARTE NR\\..*$', '\\2'),
|
||||||
|
'\\s+', ' ')), 255)
|
||||||
|
WHERE empfaenger = ''
|
||||||
|
AND verwendungszweck REGEXP '^\\s*KARTENVERF(Ü|UE)GUNG\\s*(.+?)\\s*KARTE NR\\.';
|
||||||
|
|
||||||
|
UPDATE buchungen b
|
||||||
|
JOIN bank_umsaetze u ON u.buchung_id = b.id AND u.benutzer_id = b.benutzer_id
|
||||||
|
SET b.empfaenger = u.empfaenger
|
||||||
|
WHERE b.empfaenger = ''
|
||||||
|
AND u.empfaenger <> ''
|
||||||
|
AND u.verwendungszweck REGEXP '^\\s*KARTENVERF(Ü|UE)GUNG';
|
||||||
|
|
@ -124,9 +124,11 @@ class Bankumsatz
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trägt IBAN und Bank der Gegenseite bei einem bereits bekannten Umsatz
|
* Trägt Empfänger, IBAN und Bank der Gegenseite bei einem bereits bekannten
|
||||||
* nach. Ältere Abrufe haben sie noch nicht gespeichert; der erneute Abruf
|
* Umsatz nach. Ältere Abrufe haben sie noch nicht gespeichert – den
|
||||||
* liefert sie, und der Fingerabdruck erkennt den Umsatz nur als bekannt.
|
* Empfänger etwa bei Kartenverfügungen, die ihn nur im Verwendungszweck
|
||||||
|
* nennen (#119); der erneute Abruf liefert sie, und der Fingerabdruck
|
||||||
|
* erkennt den Umsatz nur als bekannt.
|
||||||
* Nur leere Felder werden gefüllt – was schon dasteht, bleibt. Hängt der
|
* Nur leere Felder werden gefüllt – was schon dasteht, bleibt. Hängt der
|
||||||
* Umsatz an einer Buchung, bekommt auch sie die Angaben, soweit sie dort
|
* Umsatz an einer Buchung, bekommt auch sie die Angaben, soweit sie dort
|
||||||
* fehlen.
|
* fehlen.
|
||||||
|
|
@ -135,18 +137,20 @@ class Bankumsatz
|
||||||
*/
|
*/
|
||||||
public static function ergaenzen(string $externId, array $daten): void
|
public static function ergaenzen(string $externId, array $daten): void
|
||||||
{
|
{
|
||||||
|
$empfaenger = mb_substr(trim((string)($daten['empfaenger'] ?? '')), 0, 255);
|
||||||
$iban = mb_substr(strtoupper(trim((string)($daten['gegen_iban'] ?? ''))), 0, 34);
|
$iban = mb_substr(strtoupper(trim((string)($daten['gegen_iban'] ?? ''))), 0, 34);
|
||||||
$bankname = mb_substr(trim((string)($daten['gegen_bankname'] ?? '')), 0, 128);
|
$bankname = mb_substr(trim((string)($daten['gegen_bankname'] ?? '')), 0, 128);
|
||||||
if ($iban === '' && $bankname === '') {
|
if ($empfaenger === '' && $iban === '' && $bankname === '') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Database::execute(
|
Database::execute(
|
||||||
"UPDATE bank_umsaetze
|
"UPDATE bank_umsaetze
|
||||||
SET gegen_iban = IF(gegen_iban = '', ?, gegen_iban),
|
SET empfaenger = IF(empfaenger = '', ?, empfaenger),
|
||||||
|
gegen_iban = IF(gegen_iban = '', ?, gegen_iban),
|
||||||
gegen_bankname = IF(gegen_bankname = '', ?, gegen_bankname)
|
gegen_bankname = IF(gegen_bankname = '', ?, gegen_bankname)
|
||||||
WHERE benutzer_id = ? AND extern_id = ?",
|
WHERE benutzer_id = ? AND extern_id = ?",
|
||||||
[$iban, $bankname, Mandant::id(), $externId]
|
[$empfaenger, $iban, $bankname, Mandant::id(), $externId]
|
||||||
);
|
);
|
||||||
|
|
||||||
$buchungId = Database::fetchValue(
|
$buchungId = Database::fetchValue(
|
||||||
|
|
@ -154,19 +158,20 @@ class Bankumsatz
|
||||||
[Mandant::id(), $externId]
|
[Mandant::id(), $externId]
|
||||||
);
|
);
|
||||||
if ($buchungId !== null && $buchungId !== false) {
|
if ($buchungId !== null && $buchungId !== false) {
|
||||||
self::herkunftUebertragen((int)$buchungId, $iban, $bankname);
|
self::herkunftUebertragen((int)$buchungId, $empfaenger, $iban, $bankname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Füllt IBAN und Bank einer Buchung, soweit sie dort noch leer sind. */
|
/** Füllt Empfänger, IBAN und Bank einer Buchung, soweit sie dort noch leer sind. */
|
||||||
private static function herkunftUebertragen(int $buchungId, string $iban, string $bankname): void
|
private static function herkunftUebertragen(int $buchungId, string $empfaenger, string $iban, string $bankname): void
|
||||||
{
|
{
|
||||||
Database::execute(
|
Database::execute(
|
||||||
"UPDATE buchungen
|
"UPDATE buchungen
|
||||||
SET iban = IF(iban = '', ?, iban),
|
SET empfaenger = IF(empfaenger = '', ?, empfaenger),
|
||||||
|
iban = IF(iban = '', ?, iban),
|
||||||
bankname = IF(bankname = '', ?, bankname)
|
bankname = IF(bankname = '', ?, bankname)
|
||||||
WHERE id = ? AND benutzer_id = ?",
|
WHERE id = ? AND benutzer_id = ?",
|
||||||
[$iban, $bankname, $buchungId, Mandant::id()]
|
[$empfaenger, $iban, $bankname, $buchungId, Mandant::id()]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -757,6 +762,7 @@ class Bankumsatz
|
||||||
if ($umsatz !== null) {
|
if ($umsatz !== null) {
|
||||||
self::herkunftUebertragen(
|
self::herkunftUebertragen(
|
||||||
$buchungId,
|
$buchungId,
|
||||||
|
'',
|
||||||
(string)($umsatz['gegen_iban'] ?? ''),
|
(string)($umsatz['gegen_iban'] ?? ''),
|
||||||
(string)($umsatz['gegen_bankname'] ?? '')
|
(string)($umsatz['gegen_bankname'] ?? '')
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -417,6 +417,12 @@ class FinTsAbruf
|
||||||
$empfaenger
|
$empfaenger
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Erst nach dem Fingerabdruck: Er bleibt so bei bereits
|
||||||
|
// abgerufenen Umsätzen gleich, sonst kämen sie doppelt herein.
|
||||||
|
if ($empfaenger === '') {
|
||||||
|
$empfaenger = UmsatzEmpfaenger::ausVerwendungszweck($zweck);
|
||||||
|
}
|
||||||
|
|
||||||
$id = Bankumsatz::anlegen([
|
$id = Bankumsatz::anlegen([
|
||||||
'zugang_id' => (int)$this->zugang['id'],
|
'zugang_id' => (int)$this->zugang['id'],
|
||||||
'konto_id' => $bankkonto['konto_id'],
|
'konto_id' => $bankkonto['konto_id'],
|
||||||
|
|
@ -434,7 +440,7 @@ class FinTsAbruf
|
||||||
'iban' => $bankkonto['iban'],
|
'iban' => $bankkonto['iban'],
|
||||||
'eref' => $umsatz->getEndToEndID(),
|
'eref' => $umsatz->getEndToEndID(),
|
||||||
'code' => $umsatz->getBookingCode(),
|
'code' => $umsatz->getBookingCode(),
|
||||||
'name' => $empfaenger,
|
'name' => trim($umsatz->getName()),
|
||||||
'zweck' => $zweck,
|
'zweck' => $zweck,
|
||||||
], JSON_UNESCAPED_UNICODE),
|
], JSON_UNESCAPED_UNICODE),
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
31
src/Services/UmsatzEmpfaenger.php
Normal file
31
src/Services/UmsatzEmpfaenger.php
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Finanzmanager\Services;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empfänger eines Bankumsatzes, wenn die Bank ihn nicht als eigenes Feld liefert.
|
||||||
|
*
|
||||||
|
* Die comdirect füllt bei Kartenverfügungen der Visa-Debitkarte (GVC 700) das
|
||||||
|
* Namensfeld (?32/?33) nicht. Der Händler steht nur im Verwendungszweck,
|
||||||
|
* zwischen dem Buchungstext und der Kartennummer:
|
||||||
|
*
|
||||||
|
* KARTENVERFÜGUNGTINDIE, EZPLM.COM USKARTE NR. 4871 78XX XXXX 9119…
|
||||||
|
*
|
||||||
|
* Im Online-Banking zeigt die Bank genau diesen Teil als Empfänger an.
|
||||||
|
*/
|
||||||
|
final class UmsatzEmpfaenger
|
||||||
|
{
|
||||||
|
private const KARTENVERFUEGUNG = '/^\s*KARTENVERF(?:Ü|UE)GUNG\s*(.+?)\s*KARTE NR\./iu';
|
||||||
|
|
||||||
|
/** Liefert den Empfänger aus dem Verwendungszweck oder '' , wenn keiner erkennbar ist. */
|
||||||
|
public static function ausVerwendungszweck(string $zweck): string
|
||||||
|
{
|
||||||
|
if (preg_match(self::KARTENVERFUEGUNG, $zweck, $m) !== 1) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return trim(preg_replace('/\s+/u', ' ', $m[1]) ?? $m[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
151
tests/58_EmpfaengerKartenverfuegungTest.php
Normal file
151
tests/58_EmpfaengerKartenverfuegungTest.php
Normal file
|
|
@ -0,0 +1,151 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Finanzmanager\Database;
|
||||||
|
use Finanzmanager\Models\Bankumsatz;
|
||||||
|
use Finanzmanager\Models\Bankzugang;
|
||||||
|
use Finanzmanager\Models\Buchung;
|
||||||
|
use Finanzmanager\Models\Konto;
|
||||||
|
use Finanzmanager\Services\UmsatzEmpfaenger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empfänger bei Kartenverfügungen (#119).
|
||||||
|
*
|
||||||
|
* Die comdirect liefert bei Zahlungen mit der Visa-Debitkarte kein
|
||||||
|
* Namensfeld; der Händler steht nur im Verwendungszweck. Geprüft wird, dass
|
||||||
|
* er dort herausgelesen wird, dass andere Umsätze unberührt bleiben und dass
|
||||||
|
* ein erneuter Abruf den Empfänger bei bereits übernommenen Umsätzen und
|
||||||
|
* ihren Buchungen nachträgt.
|
||||||
|
*/
|
||||||
|
class EmpfaengerKartenverfuegungTest extends TestCase
|
||||||
|
{
|
||||||
|
protected string $testName = 'Test 58: Empfänger bei Kartenverfügungen';
|
||||||
|
|
||||||
|
private const TINDIE = 'KARTENVERFÜGUNGTINDIE, EZPLM.COM USKARTE NR. 4871 78XX XXXX 9119'
|
||||||
|
. 'KARTENZAHLUNGCOMDIRECT VISA-DEBITKARTE2026-09-30 00:00:00ORIGINALBETRAG: 28,19 USD'
|
||||||
|
. 'Ref. 6V2C29HM13Z7LAYO/10934';
|
||||||
|
|
||||||
|
private int $giro = 0;
|
||||||
|
private int $zugang = 0;
|
||||||
|
|
||||||
|
public function run(): void
|
||||||
|
{
|
||||||
|
$this->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<string,mixed> $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'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue