Fix: Dublettenprüfung verwendet nur (buchungstag, wertstellung, wert) ohne buchungstext, da Vorlagenänderungen sonst zu falschen Duplikaten führen.
71 lines
3 KiB
PHP
71 lines
3 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
use Steuerkram\Services\BankImportParser;
|
||
|
||
/**
|
||
* Test 35: BankImportParser::suggestFormat() – automatische Format-Erkennung.
|
||
*/
|
||
class BankImportSuggestTest extends TestCase
|
||
{
|
||
protected string $testName = 'Test 35: BankImportParser – automatische Format-Erkennung';
|
||
|
||
private function makeTempCsv(string $content): string
|
||
{
|
||
$path = sys_get_temp_dir() . '/test35_' . uniqid() . '.csv';
|
||
file_put_contents($path, $content);
|
||
return $path;
|
||
}
|
||
|
||
public function run(): void
|
||
{
|
||
$parser = new BankImportParser();
|
||
|
||
// CSV mit 2 Metazeilen vor dem Header (DKB-ähnlich)
|
||
$csv = implode("\n", [
|
||
'"Kontonummer:";"DE12 3456 7890 1234 5678 90";',
|
||
'"Von:";"01.01.2026";"Bis:";"31.01.2026";',
|
||
'"Kontostand vom 31.01.2026:";"1.234,56 EUR";',
|
||
'"";',
|
||
'"Buchungsdatum";"Wertstellung";"Status";"Zahlungspflichtige*r";"Zahlungsempfänger*in";"Verwendungszweck";"Umsatztyp";"IBAN";"Betrag (€)"',
|
||
'"15.01.2026";"15.01.2026";"Gebucht";"Max Mustermann";"REWE";"Lebensmittel";"Lastschrift";"DE11111";"−45,30"',
|
||
]);
|
||
|
||
$file = $this->makeTempCsv($csv);
|
||
$result = $parser->suggestFormat($file, 'csv');
|
||
|
||
$this->assert($result !== null, 'suggestFormat() gibt ein Ergebnis zurück');
|
||
$this->assertEquals(4, $result['skip_rows'], 'skip_rows korrekt erkannt (4)');
|
||
$this->assertEquals(';', $result['delimiter'], 'Delimiter korrekt erkannt (;)');
|
||
$this->assertEquals(1, $result['has_header_row'], 'has_header_row gesetzt');
|
||
$this->assertNotEmpty($result['header'], 'header-Array nicht leer');
|
||
$this->assertNotEmpty($result['mapping'], 'mapping-Array nicht leer');
|
||
$this->assert(isset($result['mapping']['col_buchungstag']), 'col_buchungstag gemappt');
|
||
$this->assert(isset($result['mapping']['col_wertstellung']), 'col_wertstellung gemappt');
|
||
$this->assert(isset($result['mapping']['col_wert']), 'col_wert gemappt (Betrag)');
|
||
|
||
unlink($file);
|
||
|
||
// CSV ohne Banking-Keywords → kein Vorschlag
|
||
$csvOhneKeywords = implode("\n", [
|
||
'Foo;Bar;Baz',
|
||
'1;2;3',
|
||
]);
|
||
$file2 = $this->makeTempCsv($csvOhneKeywords);
|
||
$result2 = $parser->suggestFormat($file2, 'csv');
|
||
$this->assert($result2 === null, 'suggestFormat() gibt null zurück wenn kein Banking-Header erkannt');
|
||
unlink($file2);
|
||
|
||
// Comdirect-ähnliche CSV (kein skip_rows)
|
||
$csvComdirect = implode("\n", [
|
||
'"Buchungstag";"Wertstellung";"Vorgang";"Buchungstext";"Betrag (€)"',
|
||
'"10.01.2026";"10.01.2026";"Lastschrift";"Amazon";"−19,99"',
|
||
]);
|
||
$file3 = $this->makeTempCsv($csvComdirect);
|
||
$result3 = $parser->suggestFormat($file3, 'csv');
|
||
$this->assert($result3 !== null, 'suggestFormat() erkennt Comdirect-ähnliche CSV');
|
||
$this->assertEquals(0, $result3['skip_rows'], 'skip_rows=0 bei direktem Header');
|
||
unlink($file3);
|
||
}
|
||
}
|