Feature: Nextcloud-Konfiguration in Einstellungen-UI (Migration 023)

This commit is contained in:
fds2610-bot 2026-04-10 21:34:59 +02:00
parent 880c479024
commit 092ea1f02f
7 changed files with 91 additions and 37 deletions

View file

@ -6,7 +6,8 @@
### Neu
- `NextcloudImportService`: importiert Belege aus einem Nextcloud-Ordner via WebDAV (PROPFIND → GET → MOVE/DELETE); Duplikat-Erkennung via SHA-256; JPEG/PNG werden nach dem Download automatisch zugeschnitten
- `scripts/nextcloud-import.php`: CLI-Einstiegspunkt für Cron-Betrieb; Konfiguration über `.env`-Variablen `NEXTCLOUD_URL`, `NEXTCLOUD_USER`, `NEXTCLOUD_PASS`, `NEXTCLOUD_FOLDER`, `NEXTCLOUD_DONE`
- `scripts/nextcloud-import.php`: CLI-Einstiegspunkt für Cron-Betrieb
- Migration 023: Nextcloud-Zugangsdaten (`nextcloud_url`, `nextcloud_user`, `nextcloud_pass`, `nextcloud_folder`, `nextcloud_done`) in `company_settings`; Konfiguration über Einstellungen → Nextcloud-Belegimport in der UI
---

View file

@ -168,17 +168,9 @@ Belege können automatisch aus einem Nextcloud-Ordner via WebDAV importiert werd
### Konfiguration
Umgebungsvariablen in der `.env`-Datei:
Die Zugangsdaten werden in der Steuerkram-UI gepflegt: **Einstellungen → Nextcloud-Belegimport**.
```env
NEXTCLOUD_URL=https://cloud.example.com
NEXTCLOUD_USER=meinbenutzername
NEXTCLOUD_PASS=mein-app-passwort
NEXTCLOUD_FOLDER=/Belege/Import # Ordner in Nextcloud, der überwacht wird
NEXTCLOUD_DONE=/Belege/Importiert # Ziel nach Import (leer lassen = Datei löschen)
```
**Empfehlung:** Ein Nextcloud-App-Passwort verwenden (Nextcloud → Einstellungen → Sicherheit → App-Passwörter).
Empfehlung: Ein Nextcloud-App-Passwort verwenden (Nextcloud → Einstellungen → Sicherheit → App-Passwörter).
### Manueller Aufruf

View file

@ -0,0 +1,7 @@
-- Migration 023: Nextcloud-Import-Konfiguration in company_settings
ALTER TABLE company_settings
ADD COLUMN IF NOT EXISTS nextcloud_url VARCHAR(500) NULL AFTER ocr_aktiv,
ADD COLUMN IF NOT EXISTS nextcloud_user VARCHAR(255) NULL AFTER nextcloud_url,
ADD COLUMN IF NOT EXISTS nextcloud_pass VARCHAR(500) NULL AFTER nextcloud_user,
ADD COLUMN IF NOT EXISTS nextcloud_folder VARCHAR(500) NULL DEFAULT '/Belege/Import' AFTER nextcloud_pass,
ADD COLUMN IF NOT EXISTS nextcloud_done VARCHAR(500) NULL AFTER nextcloud_folder;

View file

@ -3,30 +3,26 @@
/**
* Nextcloud-Belegimport – CLI-Einstiegspunkt.
*
* Liest Belege aus dem konfigurierten Nextcloud-Ordner (WebDAV) und legt
* sie in Steuerkram an. Danach werden die Dateien in Nextcloud in den
* Erledigte-Ordner verschoben (oder gelöscht, wenn kein DONE-Ordner gesetzt).
* Liest Belege aus dem in den Einstellungen konfigurierten Nextcloud-Ordner
* (WebDAV) und legt sie in Steuerkram an. Danach werden die Dateien in
* Nextcloud in den Erledigte-Ordner verschoben (oder gelöscht, wenn dieser
* nicht konfiguriert ist).
*
* Konfiguration: Einstellungen → Nextcloud-Belegimport in der Steuerkram-UI.
*
* Aufruf:
* docker compose exec web php scripts/nextcloud-import.php
*
* Für Cronjob (im Kontext des Containers):
* * * * * * docker compose -f /path/to/Steuerkram/docker-compose.yml exec -T web \
* php scripts/nextcloud-import.php >> /var/log/steuerkram-import.log 2>&1
*
* Umgebungsvariablen (in .env oder Systemumgebung):
* NEXTCLOUD_URL Basis-URL, z.B. https://cloud.example.com
* NEXTCLOUD_USER Benutzername
* NEXTCLOUD_PASS Passwort oder App-Passwort
* NEXTCLOUD_FOLDER Import-Ordner, z.B. /Belege/Import (Standard: /Belege/Import)
* NEXTCLOUD_DONE Erledigte-Ordner, z.B. /Belege/Importiert (leer = Datei löschen)
* Für Cronjob (auf dem Host):
* *\/15 * * * * docker compose -f /opt/steuerkram/docker-compose.yml exec -T web \
* php scripts/nextcloud-import.php >> /var/log/steuerkram-import.log 2>&1
*/
declare(strict_types=1);
chdir(dirname(__DIR__));
// .env laden falls vorhanden
// DB-Zugangsdaten aus .env laden (für CLI-Kontext ohne Apache-Umgebung)
if (file_exists('.env')) {
foreach (file('.env', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
if (str_starts_with(trim($line), '#') || !str_contains($line, '=')) {

View file

@ -29,7 +29,9 @@ class Setting
iban=?, bic=?, bank_name=?,
ustva_steuernummer=?, ustva_bundesland=?,
invoice_nr_prefix=?, beleg_nr_prefix=?,
payment_days_default=?, test_mode=?, ki_vorschlag_aktiv=?, ocr_aktiv=?
payment_days_default=?, test_mode=?, ki_vorschlag_aktiv=?, ocr_aktiv=?,
nextcloud_url=?, nextcloud_user=?, nextcloud_pass=?,
nextcloud_folder=?, nextcloud_done=?
WHERE id=1',
[
$data['firma'] ?? '',
@ -54,6 +56,11 @@ class Setting
isset($data['test_mode']) ? 1 : 0,
isset($data['ki_vorschlag_aktiv']) ? 1 : 0,
isset($data['ocr_aktiv']) ? 1 : 0,
$data['nextcloud_url'] ?: null,
$data['nextcloud_user'] ?: null,
$data['nextcloud_pass'] ?: null,
$data['nextcloud_folder'] ?: '/Belege/Import',
$data['nextcloud_done'] ?: null,
]
);
}

View file

@ -6,16 +6,17 @@ namespace Steuerkram\Services;
use Steuerkram\Database;
use Steuerkram\Models\Beleg;
use Steuerkram\Models\Setting;
/**
* Importiert Belege aus einem Nextcloud-Ordner via WebDAV.
*
* Konfiguration über Umgebungsvariablen:
* NEXTCLOUD_URL – Basis-URL der Nextcloud, z.B. https://cloud.example.com
* NEXTCLOUD_USER – Benutzername
* NEXTCLOUD_PASS – Passwort oder App-Passwort
* NEXTCLOUD_FOLDER – Pfad zum Import-Ordner, z.B. /Belege/Import
* NEXTCLOUD_DONE – Pfad für verarbeitete Dateien (optional), z.B. /Belege/Importiert
* Konfiguration über Einstellungen → Nextcloud-Belegimport (gespeichert in company_settings):
* nextcloud_url – Basis-URL der Nextcloud, z.B. https://cloud.example.com
* nextcloud_user – Benutzername
* nextcloud_pass – Passwort oder App-Passwort
* nextcloud_folder – Pfad zum Import-Ordner, z.B. /Belege/Import
* nextcloud_done – Pfad für verarbeitete Dateien (optional), z.B. /Belege/Importiert
*
* Ablauf pro Datei:
* 1. PROPFIND → Dateiliste
@ -47,11 +48,12 @@ class NextcloudImportService
public function __construct()
{
$this->baseUrl = rtrim(getenv('NEXTCLOUD_URL') ?: '', '/');
$this->user = getenv('NEXTCLOUD_USER') ?: '';
$this->pass = getenv('NEXTCLOUD_PASS') ?: '';
$this->folder = '/' . trim(getenv('NEXTCLOUD_FOLDER') ?: 'Belege/Import', '/');
$doneRaw = getenv('NEXTCLOUD_DONE') ?: '';
$cfg = Setting::get();
$this->baseUrl = rtrim($cfg['nextcloud_url'] ?? '', '/');
$this->user = $cfg['nextcloud_user'] ?? '';
$this->pass = $cfg['nextcloud_pass'] ?? '';
$this->folder = '/' . trim($cfg['nextcloud_folder'] ?: 'Belege/Import', '/');
$doneRaw = $cfg['nextcloud_done'] ?? '';
$this->doneFolder = $doneRaw !== '' ? ('/' . trim($doneRaw, '/')) : null;
$this->davBase = $this->baseUrl . '/remote.php/dav/files/' . rawurlencode($this->user);
}

View file

@ -172,6 +172,55 @@
</div>
</div>
<!-- Nextcloud-Import -->
<div class="card mb-2">
<div class="card-header"><div class="card-title">Nextcloud-Belegimport</div></div>
<div class="card-body">
<p class="text-muted text-sm" style="margin:0 0 .75rem">
Belege werden automatisch per WebDAV aus dem angegebenen Nextcloud-Ordner importiert.
Verarbeitete Dateien werden in den Erledigte-Ordner verschoben (oder gelöscht, wenn leer).
</p>
<div class="form-group">
<label>Nextcloud-URL</label>
<input type="url" name="nextcloud_url"
value="<?= $h($settings['nextcloud_url'] ?? '') ?>"
placeholder="https://cloud.example.com">
</div>
<div class="form-grid form-grid-2">
<div class="form-group">
<label>Benutzername</label>
<input type="text" name="nextcloud_user"
value="<?= $h($settings['nextcloud_user'] ?? '') ?>"
autocomplete="off">
</div>
<div class="form-group">
<label>App-Passwort</label>
<input type="password" name="nextcloud_pass"
value="<?= $h($settings['nextcloud_pass'] ?? '') ?>"
autocomplete="new-password"
placeholder="<?= !empty($settings['nextcloud_pass']) ? '(gespeichert)' : '' ?>">
<div class="form-hint">Empfohlen: App-Passwort aus Nextcloud → Einstellungen → Sicherheit</div>
</div>
</div>
<div class="form-group">
<label>Import-Ordner</label>
<input type="text" name="nextcloud_folder"
value="<?= $h($settings['nextcloud_folder'] ?? '/Belege/Import') ?>"
placeholder="/Belege/Import">
</div>
<div class="form-group">
<label>Erledigte-Ordner <span class="text-muted">(leer = Datei löschen)</span></label>
<input type="text" name="nextcloud_done"
value="<?= $h($settings['nextcloud_done'] ?? '') ?>"
placeholder="/Belege/Importiert">
</div>
<div class="form-hint">
Import manuell starten:
<code>docker compose exec web php scripts/nextcloud-import.php</code>
</div>
</div>
</div>
<div class="card mb-2">
<div class="card-header"><div class="card-title">Bankdaten</div></div>
<div class="card-body">