Konten, Kontengruppen, Kategorien und Klassen samt Übernahme aus dem
QIF-Export des Lexware FinanzManagers.
Kontenübersicht nach Kontengruppen gebündelt, mit Gruppensummen und
Gesamtsumme; die drei Saldospalten (Online-Saldo, aktueller und erwarteter
Saldo) sind angelegt und werden bis Phase 2 aus dem Anfangssaldo gespeist.
Kategorien sind hierarchisch mit ":" als Trenner. Der vollständige Pfad
steht redundant in der Tabelle, weil jede Anzeige und der gesamte Import
darüber laufen; Umbenennen und Verschieben schreiben den Teilbaum neu. Die
Art (Einnahme/Ausgabe) gilt für den ganzen Ast. Register wie im Original:
Alle, Einnahmen, Ausgaben, Umbuchungskonten.
QifParser liest zustandsbehaftet und sequenziell, wandelt ISO-8859-1 nach
UTF-8 und versteht US-Beträge sowie das Datumsformat aus der Kopfzeile.
QifStammdatenImport ist idempotent und bietet Trockenlauf und Protokoll -
im Dialog unter Verwaltung sowie über scripts/qif-import.php. Am echten
Export geprüft: 17 Klassen, 105 Kategorien, 37 Konten.
Enthält außerdem die Korrektur der englischen Monatsnamen im
Einstellungsdialog: date('F') ist sprachlich nicht umschaltbar, deshalb
liegen die Namen jetzt zentral als View::MONATE vor. Die Änderung ließ
sich nicht als eigener Commit trennen, weil sie dieselben Dateien berührt
wie Phase 1.
Tests: 227 PHP-Prüfungen und 14 Playwright-Tests, alle grün.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
112 lines
3.3 KiB
PHP
112 lines
3.3 KiB
PHP
#!/usr/bin/env php
|
||
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
/**
|
||
* QIF-Stammdatenimport auf der Kommandozeile.
|
||
*
|
||
* Dieselbe Logik wie im Dialog unter Verwaltung → QIF-Import, aber ohne Upload –
|
||
* praktisch für den großen Vollexport und für die Erstbefüllung.
|
||
*
|
||
* docker compose exec -u www-data php php scripts/qif-import.php data/import/Export.QIF
|
||
* docker compose exec -u www-data php php scripts/qif-import.php --uebernehmen data/import/Export.QIF
|
||
*
|
||
* Ohne --uebernehmen läuft nur der Trockenlauf: es wird nichts gespeichert.
|
||
*/
|
||
|
||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||
|
||
use Finanzmanager\Config;
|
||
use Finanzmanager\Mandant;
|
||
use Finanzmanager\Models\Benutzer;
|
||
use Finanzmanager\Services\QifParser;
|
||
use Finanzmanager\Services\QifStammdatenImport;
|
||
|
||
Config::load();
|
||
|
||
$argumente = array_slice($argv, 1);
|
||
$uebernehmen = false;
|
||
$benutzer = null;
|
||
$datei = null;
|
||
|
||
foreach ($argumente as $argument) {
|
||
if ($argument === '--uebernehmen') {
|
||
$uebernehmen = true;
|
||
} elseif (str_starts_with($argument, '--benutzer=')) {
|
||
$benutzer = substr($argument, 11);
|
||
} elseif (str_starts_with($argument, '-')) {
|
||
fwrite(STDERR, "Unbekannte Option: {$argument}\n");
|
||
exit(1);
|
||
} else {
|
||
$datei = $argument;
|
||
}
|
||
}
|
||
|
||
if ($datei === null) {
|
||
fwrite(STDERR, "Aufruf: qif-import.php [--uebernehmen] [--benutzer=NAME] <datei.qif>\n");
|
||
exit(1);
|
||
}
|
||
|
||
// Relative Angaben beziehen sich auf das Projektverzeichnis.
|
||
if (!str_starts_with($datei, '/')) {
|
||
$datei = dirname(__DIR__) . '/' . $datei;
|
||
}
|
||
|
||
if (!is_file($datei)) {
|
||
fwrite(STDERR, "Datei nicht gefunden: {$datei}\n");
|
||
exit(1);
|
||
}
|
||
|
||
if ($benutzer !== null) {
|
||
$zeile = Benutzer::findByName($benutzer);
|
||
if ($zeile === null) {
|
||
fwrite(STDERR, "Benutzer nicht gefunden: {$benutzer}\n");
|
||
exit(1);
|
||
}
|
||
Mandant::setze((int)$zeile['id']);
|
||
}
|
||
|
||
try {
|
||
$parser = QifParser::ausDatei($datei);
|
||
$ergebnis = (new QifStammdatenImport($parser))->ausfuehren(!$uebernehmen);
|
||
} catch (\Throwable $e) {
|
||
fwrite(STDERR, 'Import fehlgeschlagen: ' . $e->getMessage() . "\n");
|
||
exit(1);
|
||
}
|
||
|
||
echo ($uebernehmen ? 'Import' : 'Trockenlauf') . ': ' . basename($datei) . "\n";
|
||
|
||
$abschnitte = [];
|
||
foreach ($parser->zusammenfassung() as $typ => $anzahl) {
|
||
$abschnitte[] = "{$typ}: {$anzahl}";
|
||
}
|
||
echo 'Datei enthält ' . implode(' · ', $abschnitte) . "\n\n";
|
||
|
||
printf("%-12s %8s %12s %8s\n", 'Bereich', $uebernehmen ? 'angelegt' : 'neu', 'vorhanden', 'Fehler');
|
||
foreach (['klassen' => 'Klassen', 'kategorien' => 'Kategorien', 'konten' => 'Konten'] as $schluessel => $titel) {
|
||
printf(
|
||
"%-12s %8d %12d %8d\n",
|
||
$titel,
|
||
$ergebnis[$schluessel]['neu'],
|
||
$ergebnis[$schluessel]['vorhanden'],
|
||
$ergebnis[$schluessel]['fehler']
|
||
);
|
||
}
|
||
|
||
if ($ergebnis['meldungen'] !== []) {
|
||
echo "\nProtokoll:\n";
|
||
foreach ($ergebnis['meldungen'] as $meldung) {
|
||
echo ' - ' . $meldung['text'] . "\n";
|
||
}
|
||
}
|
||
|
||
if (!$uebernehmen) {
|
||
echo "\nEs wurde nichts gespeichert. Mit --uebernehmen wird der Import durchgeführt.\n";
|
||
} else {
|
||
echo "\nAnfangssalden stehen nicht im Export – sie werden je Konto in der\n"
|
||
. "Kontenübersicht nachgetragen.\n";
|
||
}
|
||
|
||
$fehler = $ergebnis['klassen']['fehler'] + $ergebnis['kategorien']['fehler'] + $ergebnis['konten']['fehler'];
|
||
exit($fehler > 0 ? 1 : 0);
|