Steuerkram/tests/34_BankImportDkbTest.php

140 lines
6.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
/**
* Test 34: BankImportParser – DKB-Format mit Template-basiertem Buchungstext.
*/
class BankImportDkbTest extends TestCase
{
protected string $testName = 'Test 34: BankImportParser – DKB-Format (Template)';
private function makeTempCsv(string $content): string
{
$path = $this->tempPath('.csv');
file_put_contents($path, $content);
return $path;
}
private function dkbFormat(): array
{
return [
'skip_rows' => 4,
'has_header_row' => 1,
'delimiter' => ';',
'enclosure' => '"',
'col_buchungstag' => 0,
'col_wertstellung' => 1,
'col_vorgang' => 6,
'col_buchungstext' => 5,
'col_wert' => 8,
'buchungstext_template_debit' => 'Auftraggeber: {Zahlungsempfänger*in} Buchungstext: {Verwendungszweck}',
'buchungstext_template_credit' => 'Auftraggeber: {Zahlungspflichtige*r} Buchungstext: {Verwendungszweck}',
'date_format' => 'd.m.Y',
'decimal_separator' => ',',
'thousands_separator' => '.',
];
}
private function dkbHeader(): string
{
return '"Buchungsdatum";"Wertstellung";"Status";"Zahlungspflichtige*r";'
. '"Zahlungsempfänger*in";"Verwendungszweck";"Umsatztyp";"IBAN";"Betrag (€)";'
. '"Gläubiger-ID";"Mandatsreferenz";"Kundenreferenz"';
}
public function run(): void
{
$parser = new \Steuerkram\Services\BankImportParser();
$fmt = $this->dkbFormat();
// ── Negativer Betrag: Zahlungsempfänger*in im Buchungstext ───────
$csv = "Skip1\nSkip2\nSkip3\nSkip4\n"
. $this->dkbHeader() . "\n"
. '"15.05.2026";"15.05.2026";"Gebucht";"Max Muster";"Amazon GmbH";"Abo Monatsbeitrag";"Lastschrift";"DE123";"- 9,99";"GL01";"MR01";"KR01"' . "\n";
$tmp = $this->makeTempCsv($csv);
$rows = $parser->parse($tmp, 'csv', $fmt);
$this->assertEquals(1, count($rows), 'DKB negativer Betrag: 1 Buchung geparst');
$this->assertEquals('2026-05-15', $rows[0]['buchungstag'], 'Buchungstag korrekt');
$this->assertEquals('2026-05-15', $rows[0]['wertstellung'], 'Wertstellung korrekt');
$this->assertEquals('Lastschrift', $rows[0]['vorgang'], 'Umsatztyp als vorgang');
$this->assertEquals(-9.99, $rows[0]['wert'], 'Betrag -9,99 korrekt');
$this->assertEquals(
'Auftraggeber: Amazon GmbH Buchungstext: Abo Monatsbeitrag',
$rows[0]['buchungstext'],
'Negativer Betrag: Template debit mit Zahlungsempfänger*in'
);
// ── Positiver Betrag: Zahlungspflichtige*r im Buchungstext ───────
$csv2 = "Skip1\nSkip2\nSkip3\nSkip4\n"
. $this->dkbHeader() . "\n"
. '"14.05.2026";"14.05.2026";"Gebucht";"Kunde AG";"Eigenkonto";"Rechnung 2026-042";"Gutschrift";"DE456";"1.500,00";"";"";"KR02"' . "\n";
$tmp2 = $this->makeTempCsv($csv2);
$rows2 = $parser->parse($tmp2, 'csv', $fmt);
$this->assertEquals(1, count($rows2), 'DKB positiver Betrag: 1 Buchung geparst');
$this->assertEquals(1500.00, $rows2[0]['wert'], 'Betrag 1.500,00 korrekt');
$this->assertEquals(
'Auftraggeber: Kunde AG Buchungstext: Rechnung 2026-042',
$rows2[0]['buchungstext'],
'Positiver Betrag: Template credit mit Zahlungspflichtige*r'
);
// ── Betrag 0: credit-Template (>= 0) ────────────────────────────
$csv3 = "Skip1\nSkip2\nSkip3\nSkip4\n"
. $this->dkbHeader() . "\n"
. '"13.05.2026";"13.05.2026";"Gebucht";"Nullbetrag GmbH";"Gegenkonto";"Storno";"Umbuchung";"DE789";"0,00";"";"";"KR03"' . "\n";
$tmp3 = $this->makeTempCsv($csv3);
$rows3 = $parser->parse($tmp3, 'csv', $fmt);
$this->assertEquals(1, count($rows3), 'DKB Betrag 0: 1 Buchung geparst');
$this->assertEquals(
'Auftraggeber: Nullbetrag GmbH Buchungstext: Storno',
$rows3[0]['buchungstext'],
'Betrag 0: credit-Template genutzt'
);
// ── Unbekannte Placeholder werden als leer aufgelöst ─────────────
$fmtUnknown = $fmt;
$fmtUnknown['buchungstext_template_debit'] = 'Test: {NichtVorhanden} Ende';
$csv5 = "Skip1\nSkip2\nSkip3\nSkip4\n"
. $this->dkbHeader() . "\n"
. '"12.05.2026";"12.05.2026";"Gebucht";"A";"B";"C";"Lastschrift";"DE";"- 1,00";"";"";"KR05"' . "\n";
$tmp5 = $this->makeTempCsv($csv5);
$rows5 = $parser->parse($tmp5, 'csv', $fmtUnknown);
$this->assertEquals('Test: Ende', $rows5[0]['buchungstext'],
'Unbekannter Placeholder wird als leerer String aufgelöst');
// ── Format ohne Template: col_buchungstext wird direkt genutzt ───
$fmtStd = [
'skip_rows' => 3,
'has_header_row' => 1,
'delimiter' => ';',
'enclosure' => '"',
'col_buchungstag' => 0,
'col_wertstellung' => 1,
'col_vorgang' => 2,
'col_buchungstext' => 3,
'col_wert' => 4,
'date_format' => 'd.m.Y',
'decimal_separator' => ',',
'thousands_separator' => '.',
];
$csv4 = "Z1\nZ2\nZ3\n"
. "Buchungstag;Wertstellung;Vorgang;Buchungstext;Betrag\n"
. "15.05.2026;15.05.2026;Lastschrift;Normaler Text;\"-50,00\"\n";
$tmp4 = $this->makeTempCsv($csv4);
$rows4 = $parser->parse($tmp4, 'csv', $fmtStd);
$this->assertEquals('Normaler Text', $rows4[0]['buchungstext'],
'Format ohne Template: col_buchungstext direkt genutzt');
}
}