751 lines
48 KiB
Markdown
751 lines
48 KiB
Markdown
# Changelog
|
||
|
||
---
|
||
|
||
## 2026-06-11 – Feature: CSV-Importformat aus „Neue Direktverbindung"-Dialog anlegen (Issue #102)
|
||
|
||
- **`bank/fints.php`:** Neue Auswahl „+ CSV-Importformat…" im Anbieter-Dropdown des „Neue Direktverbindung"-Dialogs; zeigt Felder für Trennzeichen, Anführungszeichen, Datumsformat, Dezimal-/Tausendertrennzeichen, Headerzeile und übersprungene Zeilen
|
||
- **`BankController::direktStore()`:** Behandelt `provider_id === '__csv__'` gesondert – legt einen `bank_sources`-Eintrag mit `type='csv'` und `provider_id=NULL` an (Standard-Spaltenzuordnung: Buchungstag=0, Wertstellung=1, Vorgang=2, Betrag=4) und leitet zur Feinabstimmung nach `/settings/bankimport` weiter
|
||
|
||
## 2026-06-08 – Fix: KI-Verbindungstest mit Diagnoseinformationen (Issue #55)
|
||
|
||
- **`LlmService`:** Neue Methode `testConnection()` gibt detaillierte Diagnose zurück (cURL-Fehlernummer/-meldung, HTTP-Code, Antwortzeit, verfügbare Modelle)
|
||
- **`LlmService`:** `probeOllama()` schreibt bei cURL-Fehlern jetzt einen Eintrag ins PHP-Fehlerlog (`docker compose logs web`)
|
||
- **Einstellungsseite:** Neuer Button „Verbindung testen" im KI-Abschnitt; zeigt bei Erfolg verfügbare Modelle, bei Fehler cURL-Fehler, URL und Firewall-Hinweis an
|
||
- **Route:** `POST /settings/llm-test` → `SettingsController::llmTest()`
|
||
- **`BelegController`:** Bei Verbindungsfehler wird jetzt `[]` statt `null` gespeichert (verhindert endlose Auto-Retry-Schleife); Fehlermeldung differenziert zwischen „Ollama nicht erreichbar" und „kein Vorschlag generiert"
|
||
- **Beleg-Detailseite:** Zeigt bei Verbindungsfehler spezifische Meldung „Ollama nicht erreichbar" mit Link zu den Einstellungen statt der generischen Warnung
|
||
|
||
## 2026-06-01 – Fix: EN16931-Validierungsfehler in ZUGFeRD-Rechnungen
|
||
|
||
- **[BR-FX-EN-04]** behoben: `ZugferdService` setzt jetzt BT-72 (Liefer-/Leistungsdatum) via `setDocumentSupplyChainEvent()`; das Datum wird aus dem Feld `leistungszeitraum` geparst (Format `DD.MM.YYYY` → direkt; Format `MM.YYYY` → letzter Tag des Monats; sonst Fallback auf Rechnungsdatum)
|
||
- **[PEPPOL-EN16931-R008]** behoben: Leere Strings in optionalen Adressfeldern (Straße, PLZ, Ort) werden als `null` übergeben, sodass keine leeren XML-Elemente entstehen
|
||
|
||
## 2026-05-28 – Feature: Buchungsvorlagen im Buchungsdialog
|
||
|
||
- **Datenbank:** 3 neue Tabellen `buchungsvorlagen`, `buchungsvorlage_felder`, `buchungsvorlage_regeln` (Migrationen 078–080); initiale Vorlage "Essensbeleg n. abzugsfähig (nur USt.)" per Migration 080 eingespielt
|
||
- **Buchungsdialog** (`/belege/{id}`): Neues Vorlagen-Badge (gelb) zwischen Bank-Badge und Buchungsformular; Auswahlbox mit aktiven Vorlagen; Vorlage auswählen öffnet modalen Dialog mit Felder-Gruppen und Live-USt-Berechnung
|
||
- **Modal:** Feldgruppe 1 (Metadaten: Lieferant, Rechnungsnr., Belegdatum, Brutto-Anzeige), Feldgruppe 2 (USt-Zeilen mit Netto↔Brutto-Live-Berechnung), Feldgruppe 3 (Zahlungskonto; 1200 vorausgewählt wenn Bankbuchung, sonst 1210)
|
||
- **Buchungslogik:** `VorlageBuchungsService` interpretiert JSON-Buchungsregeln und ruft `Booking::create()` direkt auf (keine automatischen Kindzeilen, da Konten explizit); Metafelder werden über `Beleg::updateMeta()` gespeichert
|
||
- **Pflege-UI:** `/einstellungen/buchungsvorlagen` – CRUD-Oberfläche für Vorlagen, Felder und Buchungsregeln; Navigationslink unter Einstellungen
|
||
- **Test 42:** `42_BuchungsvorlageTest.php` prüft CRUD, Buchungsausführung, korrekte Konten und `neq_zero`-Bedingung
|
||
|
||
## 2026-05-24 – Fix: EÜR-Zeilennummern auf amtliche Anlage EÜR 2025 korrigiert
|
||
|
||
- `migrations/075_euer_zeilen_korrektur.sql`: alle `euer_zeile`-Werte in `accounts` gemäß amtlicher Anlage EÜR 2025 neu zugeordnet (zuvor internes Schema ohne Bezug zum amtlichen Formular)
|
||
- `EuerCalculator.php`: Sonderbehandlung für nicht abziehbare BA von `euer_zeile='51'` auf `'74'` umgestellt (Zeile 74 = „Nicht abziehbare Beträge" der amtlichen Anlage EÜR)
|
||
- `accounts/form.php`: `$euerZeilen`-Array vollständig durch amtliche Zeilen 12–72 und 74 ersetzt; alle Beschriftungen entsprechen exakt dem Formulartext der Anlage EÜR 2025
|
||
|
||
## 2026-05-24 – Feature: EÜR Anlageliste CSV/PDF-Export
|
||
|
||
- EÜR-Ansicht: Kopfzeile der Anlageliste-Karte enthält jetzt rechtsbündig „Herunterladen: [CSV] [PDF]"
|
||
- CSV-Export: `GET /tax/euer/{year}/anlageliste/csv` – alle 9 Spalten mit UTF-8 BOM (Excel-kompatibel), Semikolon-getrennt, inkl. Summenzeile
|
||
- PDF-Export: `GET /tax/euer/{year}/anlageliste/pdf` – A4 Querformat, enge Spaltenbreiten sodass alle 9 Spalten auf eine Seite passen; neuer `PdfAnlagelisteService`
|
||
- EÜR-Karte: heller „PDF herunterladen"-Button entfernt; Topbar-Button umbenannt zu „PDF"
|
||
|
||
---
|
||
|
||
## 2026-05-24 – Feature: AFA-Buchung stornieren/löschen in AfA-Tabelle
|
||
|
||
- AfA-Tabelle im Asset-Edit-Modal: Gebuchte Zeilen zeigen neben dem grünen Haken einen Storno-Button (Undo-Pfeil, alle Modi) und im Testmodus zusätzlich einen Papierkorb-Button
|
||
- Storno legt eine Gegenbuchung (`buchungstyp=AfA`, `is_reversal=1`, negativer Betrag) an und setzt `afa_booking_id` auf NULL → der Pfeil-aus-Box-Button erscheint wieder
|
||
- Löschen (Testmodus) löscht die AFA-Buchung direkt und setzt `afa_booking_id` auf NULL
|
||
- Neuer Controller: `POST /assets/{id}/depreciation/{rowId}/reverse` und `…/delete`
|
||
- `AssetDepreciation::setBookingId()` akzeptiert jetzt `?int` (null erlaubt)
|
||
|
||
---
|
||
|
||
## 2026-05-24 – Feature: Buchungsjournal-Filter Buchungstyp + EÜR-Anlageliste
|
||
|
||
- Buchungsjournal: neues Filterfeld „Buchungstyp" (Einnahme / Ausgabe / AfA); vorbelegt mit „Alle Typen"
|
||
- Buchungsjournal: AfA-Buchungen (ohne Beleg) werden jetzt korrekt angezeigt (`LEFT JOIN belege`); Beleg-Zelle zeigt „–" wenn kein Beleg
|
||
- Buchungsjournal: Badge für Buchungstyp `AfA` in grau (badge-gray)
|
||
- EÜR-Ansicht: neue Tabelle „Anlagegüter {Jahr}" unterhalb der EÜR mit Spalten Anlage-ID, Bezeichnung, Anschaffungsdatum, Anschaffungskosten, Nutzungsdauer, AfA Vorjahre (kumulierte gebuchte AfA-Buchungen), Restbuchwert Vorjahr, AfA {Jahr} (gebuchte AfA des Jahres), Restbuchwert 31.12.{Jahr}; Summenzeile am Ende
|
||
- `Asset::anlageliste(int $year)` als neue Modell-Methode (single query mit Subqueries)
|
||
|
||
---
|
||
|
||
## 2026-05-24 – Feature: AfA-Tabelle anteilig nach Anschaffungsmonat
|
||
|
||
- Das erste Abschreibungsjahr wird anteilig nach Restmonaten berechnet: der Anschaffungsmonat zählt voll (Januar = 12 Monate, April = 9 Monate usw.)
|
||
- Das letzte Jahr erhält automatisch die verbleibenden Monate (12 − Monate des ersten Jahres); bei Januar-Kauf entfällt das extra letzte Jahr
|
||
- Die Cent-Option (`cent_im_ersten_jahr`) bleibt davon unberührt: der Cent-Rest geht weiterhin vollständig ins erste Jahr, ohne Aufteilung auf das letzte Jahr
|
||
- Sofortabschreibung (`nutzungsdauer = 0`) ist unverändert
|
||
- Neuer Test `41_AfaAnteiligTest` prüft April-, Oktober-, Juli-, Dezember- und Januar-Käufe sowie die Cent-Option mit anteiligem Jahr
|
||
|
||
---
|
||
|
||
## 2026-05-22 – Feature: „Abrufen ab"-Auswahl für Direktverbindungen
|
||
|
||
- Im Bearbeiten-Dialog jeder FinTS- bzw. API-Direktverbindung gibt es ein neues Dropdown **Abrufen ab** mit den Optionen *Ab letztem Abruf (00:00 Uhr)* (Default), *Letzte 7 Tage*, *Aktueller Monat (ab 01.)*, *Letzte 30 Tage*, *Ohne Datum (letzte 365 Tage)*
|
||
- Die Auswahl gilt nur für den nächsten Abruf: nach erfolgreichem Lauf setzt `BankSource::updateLastFetched()` `fetch_range` wieder auf `'last_fetched'` zurück
|
||
- Migration `072_bank_sources_fetch_range.sql` ergänzt die neue ENUM-Spalte (Default `'last_fetched'`, bestehende Verbindungen verhalten sich unverändert)
|
||
- Logik in `BankSource::computeStartDate()` zentralisiert; `FinTsFetchService` und `PayPalNvpFetchService` nutzen sie. Neuer Test `39_BankFetchRangeTest` deckt alle fünf Range-Werte plus Fallbacks ab
|
||
|
||
---
|
||
|
||
## 2026-05-22 – Fix: FinTS-Konto-Auswahl wird jetzt gespeichert + Bearbeiten-Dialog mit Checkboxen
|
||
|
||
- **Bug:** Beim ersten Abruf erschien das Konto-Auswahl-Modal, das Speichern blieb aber hängen. Ursache war PHP-Session-Locking: der SSE-Stream `/bank/direkt/{id}/run` hielt die Session-Datei während des `awaitAccountSelection()`-Polling-Loops gesperrt, der parallele POST `/bank/direkt/{id}/accounts` blockierte beim `session_start()` → Deadlock bis Timeout
|
||
- **Fix:** Im SSE-Endpoint `session_write_close()` direkt nach dem Auth-Check; entstört zugleich die analog gelagerte TAN-Eingabe
|
||
- **UI:** Im Bearbeiten-Dialog einer FinTS-Verbindung erscheinen die gespeicherten Konten jetzt als Checkbox-Liste (statt nur als Text). Abhaken entfernt den Identifier beim Speichern aus `account_filter`; alle abgehakt verhält sich wie der Reset-Toggle
|
||
- Filter-Berechnung als `BankSource::computeFilterFromPost()` extrahiert, neuer Test `38_BankSourceFilterFromPostTest` deckt Reset, Teilauswahl, leere Auswahl und Schutz gegen Unterschieben fremder Identifier ab
|
||
|
||
---
|
||
|
||
## 2026-05-22 – Feature: APP_KEY Status & Generator in den Einstellungen
|
||
|
||
- Neuer Settings-Bereich unter dem Betriebsmodus zeigt Status des Verschlüsselungsschlüssels (`APP_KEY`): **Gesetzt** (grün, 64 Hex-Zeichen valide), **Ungültig** (falsches Format) oder **Fehlt** (leer)
|
||
- Bei fehlendem oder ungültigem Schlüssel: Button „Neuen Schlüssel generieren" → POST `/settings/generate-app-key` liefert `bin2hex(random_bytes(32))`, Anzeige im Code-Block mit Copy-Button
|
||
- Schlüssel wird nicht persistiert (Container hat keinen Schreibzugriff auf `.env`); Anleitung im UI: kopieren → in `.env` eintragen → `docker compose restart web`
|
||
|
||
---
|
||
|
||
## 2026-05-22 – UI: Einheitliche Icon-Buttons für Bearbeiten/Ansehen/Löschen
|
||
|
||
- **Bleistift-Icon** (transparent, ohne Hintergrund – Stil der Direktverbindungs-Kacheln) ersetzt alle „Bearbeiten"- und „Öffnen"-Buttons in `accounts/list`, `customers/show`, `customers/list`, `suppliers/list`, `useradmin/list`, `assets/list`, `belege/list`, `invoices/list`, `invoices/show`
|
||
- **Auge-Icon** (Kästchen mit Auge) ersetzt die PDF-Buttons in `invoices/list` (PDF), `invoices/show` (PDF herunterladen) sowie den „Ansehen"-Button in `tax/ustva_index`, um „nur ansehen" visuell vom „bearbeiten" abzugrenzen
|
||
- **Papierkorb-Icon** (transparent, Danger-Farbe) ersetzt alle „Löschen"-Buttons in `accounts/list`, `invoices/list`, `useradmin/list`, `suppliers/list`, `assets/list`, `belege/detail`, `settings/bankimport`, `bank/fints` und `settings/form`
|
||
- **Plus-Icon** (rund, btn-primary, 1,8rem) ersetzt alle „Neu anlegen/erstellen/hochladen"-Buttons – Topbars (`bank/fints`, Kunden, Lieferanten, Rechnungen, Belege, Wirtschaftsgüter, Konten), Dashboard-Schnellzugriff, Card-Header in `customers/show`, Aktionsspalte in `customers/list` und „Position hinzufügen" im Rechnungsformular
|
||
- `bank/index.php`: Button „Öffnen" → „Aktivieren" (Status-Toggle, semantisch eindeutiger)
|
||
|
||
---
|
||
|
||
## 2026-05-21 – Feature: FinTS-Direktverbindung + Vereinheitlichung der Bank-Importquellen
|
||
|
||
- **FinTS-Abruf** für Comdirect, DKB und weitere Banken über `nemiah/php-fints` (PHP-Lib für HBCI/FinTS 3.0). Leseabruf mit PIN; TAN-pflichtige Aktionen werden mit klarer Fehlermeldung abgebrochen
|
||
- **Verschlüsselung sensibler Felder**: Neuer `Crypto`-Service (AES-256-GCM, Magic-Prefix `enc:v1:`) verschlüsselt PayPal-Signature und FinTS-PIN. Schlüssel aus `APP_KEY` in `.env` – im Backup mitsichern, Verlust = Verlust aller verschlüsselten Werte
|
||
- **Datenmodell-Fusion**: Neue Tabelle `bank_sources` ersetzt `bank_import_formats` + `bank_connections` mit `type`-Spalte (`csv`/`api`/`fints`). `bank_import_batches.source_id` löst `format_id`/`connection_id` ab (alte Spalten bleiben vorerst bestehen für rollback-Sicherheit)
|
||
- **Route-Umbenennung**: `/bank/fints*` → `/bank/direkt*` (semantisch korrekt – PayPal ist keine FinTS-Verbindung). Topbar in /bank vereinheitlicht zu einer „Importieren"-Schaltfläche
|
||
- **NEU/Edit-Modal** zeigt typabhängig API-Felder (PayPal: App-Name, Kennwort, Signature, Sandbox) oder FinTS-Felder (BLZ, Benutzerkennung, PIN, optional FinTS-URL und IBAN-Filter)
|
||
- **`FinTsFetchService`**: Login → SEPA-Konten abrufen → Statements seit `last_fetched_at` (00:00) → Buchungen mit Hash-basierter `external_id` (IBAN+Datum+Betrag+Verwendungszweck) deduplizieren
|
||
- Migrationen 068 (bank_sources + Backfill), 069 (default_fints_url auf bank_providers für Comdirect/DKB)
|
||
- `scripts/encrypt_bank_secrets.php` – einmaliges idempotentes Verschlüsseln der Klartext-Werte nach Backfill
|
||
- Neue Tests 36 (Crypto-Roundtrip) und 37 (BankSource CRUD über alle drei Typen)
|
||
|
||
---
|
||
|
||
## 2026-05-17 – Feature: Automatischer Format-Vorschlag beim Bank-Import
|
||
|
||
- **Format-Vorschlag**: Wenn eine hochgeladene CSV keinem bekannten Format eindeutig entspricht, analysiert `BankImportParser::suggestFormat()` die Datei automatisch (Headerzeilen-Erkennung bei skip_rows 0–10, Delimiter-Erkennung, Keyword-basiertes Spalten-Mapping)
|
||
- **Session-gestützter Vorschlags-Flow**: Klick auf „Formate bearbeiten" speichert den Vorschlag via AJAX in der Session und öffnet die Einstellungsseite
|
||
- **Vorschlags-Card**: Auf `/settings/bankimport` erscheint der Vorschlag oberhalb bestehender Formate als ausfüllbares Formular mit vorausgefüllten Feldern (skip_rows, Delimiter, Spalten-Mapping mit erkannten Headernamen)
|
||
- **Explizites Speichern**: Neues Format wird erst nach Klick auf „Speichern" in der DB angelegt (POST `/settings/bankimport/create`); Verwerfen löscht die Session-Suggestion
|
||
- Neue Routen: `POST /settings/bankimport/suggest`, `POST /settings/bankimport/create`, `POST /settings/bankimport/dismiss-suggestion`
|
||
- Neues Model: `BankImportFormat::create()`; neuer Test 35
|
||
|
||
---
|
||
|
||
## 2026-05-17 – Feature: Automatische Format-Erkennung beim Bank-Import
|
||
|
||
- **Format-Erkennung**: Hochgeladene Datei wird automatisch gegen alle gespeicherten Formate geprüft; bei eindeutigem Match wird sofort importiert
|
||
- **Vorschau-Panel**: Wenn kein Format passt, zeigt die Upload-Seite Überschriften-Zeile, erste Werte-Zeile und die Spalten-Zuordnung (Wertstellung, Buchungstext, Wert) für das gewählte Format an; wechselt live beim Umschalten der Formatauswahl
|
||
- **„Formate bearbeiten"-Button** oben rechts verlinkt direkt auf die Einstellungsseite für Bankimport-Formate
|
||
- Neuer AJAX-Endpunkt `POST /bank/detect-format` in `BankController`; neue Methoden `peekRows()` und `isFormatMatch()` in `BankImportParser`
|
||
|
||
---
|
||
|
||
## 2026-05-17 – Feature: DKB-Importformat für Bankbuchungen
|
||
|
||
- **Neues Format „DKB Bank"**: 4 Skip-Zeilen, Semikolon-getrennt, Anführungszeichen-eingeschlossen
|
||
- Buchungstext wird konditionell zusammengesetzt: bei negativem Betrag aus Zahlungsempfänger + Verwendungszweck, sonst aus Zahlungspflichtiger + Verwendungszweck
|
||
- Migration 054 ergänzt drei neue Nullable-Spalten in `bank_import_formats` (`col_zahlungspflichtiger`, `col_zahlungsempfaenger`, `col_verwendungszweck`)
|
||
|
||
---
|
||
|
||
## 2026-05-16 – Refactor: Code-Qualität, Sicherheit und Konsistenz
|
||
|
||
- **CSRF-Schutz**: `Auth::generateCsrfToken()` / `validateCsrfToken()` neu; Router validiert Token bei allen POST/PUT/DELETE-Requests; base.php injiziert Token in Formulare und fetch-Aufrufe via JS; login.php erhält hidden Input
|
||
- **Path Traversal** in `BelegController::serveFile()` abgesichert (`realpath()` + Prefix-Check gegen Upload-Basisverzeichnis)
|
||
- **`mime_content_type()`** (deprecated) durch `finfo_file(finfo_open(FILEINFO_MIME_TYPE), ...)` in `BelegController`, `SettingsController`, `BankController` und `ImageCropService` ersetzt
|
||
- **XSS** in `topbarActions`: `View::buildQuery()` (neuer Helper) statt rohem `http_build_query($_GET)`
|
||
- **`@`-Unterdrückung** in `SettingsController` entfernt (ersetzt durch `file_exists()`-Prüfung)
|
||
- **BaseController**: gemeinsame `renderView()`-Methode zentralisiert; alle 13 Controller erben davon; lokale Duplikate entfernt
|
||
- **DB-Transaktionen**: `Booking::create()` und `Booking::reverse()` laufen jetzt in atomaren Transaktionen; `Database::beginTransaction/commit/rollBack` unterstützt verschachtelte Aufrufe via Tiefenzähler (TestCase-Isolation bleibt intakt)
|
||
- **`src/Constants.php`**: Buchungstypen und Steuerkontonummern (SKR03) als benannte Konstanten; Magic Strings in `Booking.php` ersetzt
|
||
- **Dokumentation**: `docs/funktionen.md` – Abschnitt „Bank buchen" ergänzt; UStVA-Kennzahlen (81, 89, 66, 61, 83) korrigiert; Eigenanteil-Konten (4920/4925) korrigiert
|
||
- **Tests**: `32_BankTransactionTest` (linkBeleg, unlinkBeleg, recalcStatus, findDuplicates) und `33_BankImportParserTest` (CSV-Parsing, BOM, Tausendertrenner, Fehlerfall) neu
|
||
|
||
---
|
||
|
||
## 2026-05-15 – Feature: Bankbuchung auf mehrere Belege aufteilen
|
||
|
||
- Migration 053: Junction-Tabelle `bank_transaction_belege` (bank_tx_id, beleg_id, betrag); `bank_transactions.beleg_id` entfernt; Status-ENUM um `teilweise` erweitert; bestehende Verknüpfungen automatisch migriert
|
||
- Neuer Status `teilweise`: wird gesetzt wenn mind. ein Beleg verknüpft ist, aber noch Restbetrag offen bleibt
|
||
- Standardfilter in der Bankübersicht zeigt jetzt „Offen & Teilweise"
|
||
- `bank/show.php`: Sektion „Verknüpfte Belege" mit Betrag je Beleg und Entfernen-Button; Restsaldo-Anzeige; Betrag-Eingabefeld pro Beleg in der Offene-Belege-Liste
|
||
- Beim Verknüpfen wird der zugeordnete Betrag an die Buchungsmaske weitergegeben (`alloc_betrag`)
|
||
- `BankTransaction::linkBeleg()` schreibt jetzt in Junction-Tabelle mit Betrag; `recalcStatus()` setzt Status automatisch; `unlinkBeleg()` entfernt Verknüpfung; `getLinkedBelege()` / `getRemainingBetrag()` neu
|
||
- Neue Route `POST /bank/{id}/unlink`
|
||
|
||
---
|
||
|
||
## 2026-05-15 – Feature: Dublettenprüfung beim Bank-Import
|
||
|
||
- Nach dem Upload wird geprüft, welche Buchungen bereits in der DB vorhanden sind (Abgleich über Buchungstag, Wertstellung, Betrag, Buchungstext)
|
||
- Werden Dubletten gefunden, erscheint eine Prüfseite mit zwei Tabellen: erkannte Dubletten (per Checkbox auswählbar) und neue Buchungen (werden immer importiert)
|
||
- „Alle auswählen / abwählen"-Buttons + Gesamtzähler zeigen an, wie viele Buchungen importiert werden
|
||
- Erst nach Bestätigung wird importiert; ohne Auswahl wird der Import übersprungen
|
||
- Migration 052: UNIQUE-Constraint auf `bank_transactions` entfernt (UI-Prüfung ist die primäre Schutzschicht)
|
||
- `BankTransaction::findDuplicates()`: neue Methode mit Batch-Abfrage gegen die DB
|
||
- `BankController::doImport()`: gemeinsame Import-Logik extrahiert (wird von `upload()` und `uploadConfirm()` genutzt)
|
||
|
||
---
|
||
|
||
## 2026-05-15 – Fix: Bank-Import-Duplikate verhindern
|
||
|
||
- Migration 051: UNIQUE-Constraint `(buchungstag, wertstellung, wert, buchungstext(200))` auf `bank_transactions`; bestehende Duplikate wurden dabei bereinigt
|
||
- `BankController::upload()`: Import läuft jetzt in einer DB-Transaktion – bei Fehler wird alles zurückgerollt statt einen unvollständigen Batch zu hinterlassen
|
||
- `BankController::upload()`: Dateiname-Prüfung vor dem Import – erneuter Upload derselben Datei wird mit Fehlermeldung abgelehnt
|
||
- `BankTransaction::filenameExists()`: neue Hilfsmethode zur Duplikat-Prüfung anhand Dateiname
|
||
|
||
---
|
||
|
||
## 2026-05-15 – Fix: Netto-Neuberechnung bei Kategorie-Wechsel in Bank-Buchungsmaske
|
||
|
||
- IIFE-Wrapper für `updateAutoUst` in einen `DOMContentLoaded`-Listener verschoben, damit er erst nach der Funktionsdefinition (späteres `<script>`-Tag) gesetzt wird und nicht sofort von ihr überschrieben wird.
|
||
|
||
---
|
||
|
||
## 2026-05-14 – Feature: Bank buchen
|
||
|
||
- Navigation: neuer Eintrag „Bank buchen" unter Belege & Buchungen
|
||
- Migration 049: Tabellen `bank_import_formats`, `bank_import_batches`, `bank_transactions`; Comdirect-Format als erster Eintrag
|
||
- `BankImportParser`: Parst CSV/TXT (quoted, Semikolon-getrennt) und XLSX (via ZipArchive/SimpleXML, kein Composer-Paket)
|
||
- Liste `/bank`: Suche + Filter (Jahr, Monat, Einnahme/Ausgabe, Status); Standard-Filter: offen; Einnahmen grün, Ausgaben rot
|
||
- Upload `/bank/upload`: Drag-&-Drop-Zone für CSV/TXT/XLSX + Format-Auswahl
|
||
- Detail `/bank/{id}`: Bank-Zeile oben; Beleg-Upload; Liste offener Belege zum Verknüpfen
|
||
- Status-Aktionen: „Ignorieren" / „Wieder öffnen"; Verknüpfen eines Belegs setzt Status auf „gebucht"
|
||
|
||
---
|
||
|
||
## 2026-05-14 – Feature: UStVA Kz 83 = ust81 + ust89 − Kz66 − Kz61
|
||
|
||
- `UstvaCalculator`: Kz 83 wird nun als `ust81 + ust89 − Kz66 − Kz61` berechnet (nicht mehr kontobasiert via ustva_kz='83')
|
||
- Test 29: angepasst (7%-Buchung auf korrektes Konto 8300; delta83-Erwartung aktualisiert)
|
||
|
||
## 2026-05-14 – Feature: UStVA Kz 61 aus ust89 abgeleitet (ReverseCharge-Symmetrie)
|
||
|
||
- `UstvaCalculator`: Kz 61 = ust89 (nicht mehr kontobasiert via Konto 1574) – fachlich korrekt, da VSt ig. Erwerb = USt ig. Erwerb
|
||
- `Booking::reverse()`: Hauptstornobuchung überträgt jetzt `steuerart` der Originalbuchung (fehlte bisher, wurde durch Kz-61-Kontoberechnung kaschiert)
|
||
|
||
## 2026-05-14 – Feature: UStVA Kz 81/89 auf volle Euro abgerundet
|
||
|
||
- `UstvaCalculator`: Kz 81 und 89 werden mit `floor()` auf volle Euro abgerundet; USt wird auf dem gerundeten Wert berechnet
|
||
- Darstellung: Kz 81/89 zeigen "1.234,- €" statt "1.234,00 €" (in Tabelle und Zusammenfassung)
|
||
- USt-Felder (ust81, ust89) bleiben als Dezimalzahl unverändert
|
||
- Test 31: prüft floor-Verhalten für Kz 81 und 89
|
||
|
||
## 2026-05-14 – Refactor: UStVA auf 5-Kennzahlen-Schema vereinfacht
|
||
|
||
- Migration 048: Kontenrahmen bereinigt – nur noch `ustva_kz` ∈ {81, 83, 61, 66} aktiv; 1571/1576 → 66, 1574 → 61, 1771/1774 → 83, alle anderen auf NULL
|
||
- `UstvaCalculator`: Nur noch Kz 81, 89, 66, 61, 83 + zwei Anzeigefelder (ust81, ust89 = Kz × 0,19, kein XML)
|
||
- Kz 83 ist jetzt „Vorauszahlung / Überschuss" = `(USt-Konten) − Kz 66 − Kz 61`
|
||
- `ElsterXmlService`: Export nur Kz 81/89 (ganzzahlig) + 66/61/83 (2 Dez); Kz 83 nur bei positivem Wert
|
||
- View `ustva_show.php`: Neue Sektionsgliederung, Zusammenfassungsbox aktualisiert
|
||
- Tests 5, 7, 13, 18, 28, 29, 30 auf neues Schema angepasst
|
||
|
||
---
|
||
|
||
## 2026-05-10 – Feature: ig. Erwerb 19 % ReverseCharge über Kindzeilen
|
||
|
||
- Migration 047: ustva_kz='91' für Konto 1774; Kindzeilen (1574/1774) für bestehende ig_erwerb_19-Buchungen
|
||
- `Booking::create()`: steuerart=ig_erwerb_19 erzeugt zwei Kindzeilen – VSt auf 1574 (Kz 67), USt auf 1774 (Kz 91)
|
||
- `UstvaCalculator`: Kz 67/91 jetzt kontobasiert via 1574/1774; Kz 93/94 (ig_erwerb_7) entfernt
|
||
- Buchungsformular: Option „ig. Erwerb 7 %" entfernt
|
||
- Test 7 auf neue Logik angepasst; Test 30 neu
|
||
|
||
---
|
||
|
||
## 2026-05-10 – Feature: USt-Buchungszeilen für Ausgangsrechnungen
|
||
|
||
- Migration 046: Konten 1771 (USt 7 %) und 1776 (USt 19 %) erhalten `ustva_kz='84'`/'83'`; bestehende Einnahme-Buchungen mit USt erhalten nachträglich USt-Kindzeilen
|
||
- `Booking::create()`: Bei Einnahme-Buchungen mit 7/19 % und `steuerart=normal` wird analog zur VSt-Kindzeile eine USt-Zeile auf 1771/1776 angelegt
|
||
- `UstvaCalculator`: Kz 83/84 jetzt kontobasiert via 1771/1776 (`betrag_netto`), nicht mehr via `betrag_ust` der Erlöskonten; `KZ_ACCOUNT_MAP` aktualisiert
|
||
- `Invoice::cancel()`: Nur Hauptbuchungen (`parent_booking_id IS NULL`) werden direkt storniert; Kindzeilen werden von `Booking::reverse()` mitaufgehoben (verhindert Doppelstorno)
|
||
- Tests 10 und 27 an geänderte Buchungsstruktur angepasst; Test 29 neu
|
||
|
||
---
|
||
|
||
## 2026-05-05 – Feature: Stornorechnung (§ 14 UStG)
|
||
|
||
### Hinzugefügt
|
||
- `migrations/042_invoice_storno_of_id.sql`: Neue Spalte `storno_of_id` in `invoices` (FK auf Original)
|
||
- `Invoice::createCancellation()`: Legt Stornorechnung mit negierten Beträgen an, setzt Original auf „Storniert", erzeugt GoBD-konforme Stornobuchungen
|
||
- Storno-Button in Rechnungsübersicht (`list.php`) und Detailansicht (`show.php`)
|
||
- Querverweise Original ↔ Stornorechnung in der Detailansicht
|
||
- PDF-Anpassung: Titel „STORNORECHNUNG", Referenzzeile, kein Zahlungshinweis, angepasster Dateiname
|
||
- Test `27_StornorechnungTest.php`
|
||
|
||
---
|
||
|
||
## 2026-04-28 – Feature: E-Rechnung / ZUGFeRD EN16931
|
||
|
||
### Hinzugefügt
|
||
- `src/Services/ZugferdService.php`: Erzeugt ZUGFeRD-konformes EN16931-XML und bettet es in den PDF-String ein (via `horstoeko/zugferd`)
|
||
- `src/Services/PdfInvoiceService.php`: PDF wird nach der mPDF-Generierung durch `ZugferdService::attachToPdf()` geleitet; Ausgabe erfolgt jetzt manuell per Header/echo statt `mpdf->Output('D')`
|
||
- Alle Ausgangsrechnungs-PDFs sind ab sofort gültige E-Rechnungen (ZUGFeRD EN16931 / Factur-X)
|
||
|
||
---
|
||
|
||
## 2026-04-27 – Feature: Neues Rechnungsnummernformat (PPPYYYYMM-nn)
|
||
|
||
### Geändert
|
||
- `src/Models/Invoice.php`: `generateRechnungsNr()` erzeugt jetzt das Format `PPPYYYYMM-nn` (Prefix + Jahr + Monat + zweistellige Sequenz, die bei Bedarf wächst); Zähler wird monatlich zurückgesetzt
|
||
- `migrations/038_invoice_nr_month.sql`: Neue Spalte `invoice_nr_month` in `company_settings`
|
||
|
||
---
|
||
|
||
## 2026-04-26 – Fix: Eigenanteil-Buchung als Einnahme statt Ausgabe
|
||
|
||
### Geändert
|
||
- `src/Models/Booking.php`: `upsertKorrekturbuchung()` setzt `buchungstyp` jetzt korrekt auf `Einnahme` (war fälschlich `Ausgabe`)
|
||
|
||
---
|
||
|
||
## 2026-04-26 – Feature #57: Lineare Abschreibungstabelle für Anlagegüter
|
||
|
||
### Hinzugefügt
|
||
- `migrations/035_assets_abschreibung_flags.sql`: Neue Spalten `automatisch_berechnet` und `cent_im_ersten_jahr` in `assets`
|
||
- `migrations/036_asset_depreciation_schedule.sql`: Neue Tabelle `asset_depreciation_schedule` (Jahr, Abschreibungsbetrag, Restwert)
|
||
- `src/Models/AssetDepreciation.php`: Berechnung (linear, Sofortabschreibung, Cent-Option), Persistenz
|
||
- `tests/26_AbschreibungstabelleTest.php`: 22 Tests für alle AfA-Szenarien
|
||
|
||
### Geändert
|
||
- `src/Models/Asset.php`: `create()` und `update()` speichern `automatisch_berechnet` und `cent_im_ersten_jahr`
|
||
- `src/Controllers/AssetController.php`: Abschreibungstabelle wird nach Speichern automatisch generiert; neue Endpunkte `/assets/depreciation-preview` (AJAX-Vorschau) und `/assets/{id}/depreciation` (manuelle Speicherung)
|
||
- `src/Views/assets/form.php`: Nutzungsdauer-Dropdown (sofort, 1–10, 12, 13, 15, 20, 25, 50 Jahre + individuell), Cent-Option, „AfA-Tabelle"-Button, Modal mit Auto/Manuell-Toggle und editierbarer Tabelle
|
||
- `public/index.php`: Neue Routen für Depreciation-Preview und -Speicherung
|
||
|
||
---
|
||
|
||
|
||
## 2026-04-26 – KI-Diagnose: Erreichbarkeitsprüfung und Fehlerlog für Ollama
|
||
|
||
### Geändert
|
||
- `src/Services/LlmService.php`: Neue Methode `isReachable()` für Diagnosezwecke; Fehlerlog in `callOllama()` bei cURL-Fehler oder leerer Antwort
|
||
- `src/Views/settings/form.php`: Einstellungsseite prüft jetzt aktiv, ob der Ollama-Server erreichbar ist (nicht nur ob er konfiguriert ist); zeigt bei Verbindungsfehler einen konkreten Hinweis auf `OLLAMA_HOST=0.0.0.0:11434`
|
||
|
||
---
|
||
|
||
## 2026-04-26 – Leistungszeitraum als freies Textfeld
|
||
|
||
### Geändert
|
||
- `migrations/034_leistungszeitraum_text.sql`: Spalten `leistungszeitraum_von` (DATE) und `leistungszeitraum_bis` (DATE) wurden durch eine einzige Textspalte `leistungszeitraum` (VARCHAR 255) ersetzt; bestehende Datumswerte werden automatisch migriert
|
||
- `src/Views/invoices/form.php`: Zwei Datumsfelder durch ein Freitextfeld „Leistungszeitraum" ersetzt, Grid von 4 auf 3 Spalten angepasst
|
||
- `src/Models/Invoice.php`: INSERT/UPDATE verwenden jetzt `leistungszeitraum` statt `leistungszeitraum_von`/`leistungszeitraum_bis`
|
||
- `src/Controllers/InvoiceController.php`: Datums-Defaults für `leistungszeitraum_von`/`leistungszeitraum_bis` entfernt
|
||
- `src/Views/invoices/show.php`: Leistungszeitraum-Anzeige vereinfacht (kein Datumsformat, direkter Textausgabe)
|
||
- `src/Services/PdfInvoiceService.php`: Leistungszeitraum-Ausgabe vereinfacht
|
||
|
||
---
|
||
|
||
## 2026-04-15 – KI-Erkennung: automatischer Aufruf aus Belegansicht entfernt
|
||
|
||
### Geändert
|
||
- `src/Views/belege/detail.php`: KI-Analyse wird nicht mehr automatisch beim Öffnen eines Belegs ausgelöst; stattdessen wird ein Hinweis "KI-Analyse wird im Hintergrund durchgeführt …" mit einem "Jetzt generieren"-Button angezeigt, wenn noch kein Vorschlag vorhanden ist
|
||
- Hintergrund: Die Analyse läuft bereits beim Nextcloud-Import (`ki-batch.php`); ein doppelter Aufruf aus der UI war überflüssig
|
||
|
||
---
|
||
|
||
## 2026-04-12 – Anlagevermögen: Anzeige-Fix und Daten-Backfill
|
||
|
||
### Fix
|
||
- Buchungstabellen (Beleg-Detail, Journal, UStVA-Drill-down, EÜR-Drill-down): Anlage-Spalte zeigt jetzt auch die Bezeichnung als Fallback, wenn `anlage_nr` leer ist
|
||
- `migrations/032_anlage_nr_backfill.sql`: Anlage-Nummern für bestehende Anlagegüter ohne `anlage_nr` werden nachgeneriert
|
||
|
||
---
|
||
|
||
## 2026-04-12 – Anlagevermögen (Wirtschaftsgüter)
|
||
|
||
### Neu
|
||
- Navigation: neuer Abschnitt „Betriebsvermögen" mit Menüpunkt „Anlagevermögen"
|
||
- `migrations/028_assets_anlagevermoegen.sql`: neue Tabelle `assets` für Wirtschaftsgüter
|
||
- `src/Models/Asset.php`: CRUD-Model mit automatischer laufender Nummer und Geschäftsjahrzuordnung
|
||
- `src/Controllers/AssetController.php`: Liste, Anlegen, Bearbeiten, Löschen
|
||
- `src/Views/assets/list.php`: Anlagenspiegel-Tabelle mit Bleistift- und Papierkorb-Aktionen
|
||
- `src/Views/assets/form.php`: Formular für Wirtschaftsgut (Bezeichnung, Anschaffungsdatum, Kosten, Zugänge, Abgänge, AfA, Nutzungsdauer, Notizen)
|
||
- `tests/20_AnlagevermoegensTest.php`: 14 Tests für CRUD-Operationen
|
||
|
||
---
|
||
|
||
## 2026-04-12 – EÜR-Korrekturen: Gewerbesteuer + Bewirtungskonten ohne VSt
|
||
|
||
### Geändert
|
||
- `migrations/028_euer_4320_bewirtung_ohne_vst.sql`: Gewerbesteuer (4320) von Z. 52 auf Z. 51 (§ 4 Abs. 5b EStG, KZ 165 nicht abzugsfähig)
|
||
- `migrations/028_euer_4320_bewirtung_ohne_vst.sql`: Konten 4652 (Bewirtung 70 % ohne VSt, Z. 44) und 4657 (Bewirtung 30 % ohne VSt, Z. 51) ergänzt
|
||
- `docs/kontenrahmen.md`: Dokumentation entsprechend aktualisiert
|
||
|
||
---
|
||
|
||
## 2026-04-12 – Klasse-0-Konten als Anlagevermögen klassifiziert
|
||
|
||
### Geändert
|
||
- `docs/kontenrahmen.md`: Alle 10 Klasse-0-Konten (0027–0480) von `Zahlungskonto` auf `Anlagevermögen` korrigiert
|
||
- `migrations/027_anlagevermögen_kontenart.sql`: Migration war bereits vorhanden und setzt die DB-Änderung beim nächsten Container-Start um
|
||
|
||
---
|
||
|
||
## 2026-04-12 – Backup: smarte Rotation und Lock-Schutz
|
||
|
||
### Geändert
|
||
- `scripts/backup.sh`: Rotation auf 7 Tages- / 4 Wochen- / 12 Monats-Buckets umgestellt (statt pauschaler 90-Tage-Löschung)
|
||
- `scripts/backup.sh`: `flock`-Lock verhindert parallele Läufe bei Verzögerungen
|
||
- `scripts/backup.sh`: Pfade sind absolut (Script funktioniert auch aus Cron ohne Verzeichniswechsel)
|
||
|
||
---
|
||
|
||
## 2026-04-12 – Uploads: named Volume → Bind Mount
|
||
|
||
### Geändert
|
||
- `docker-compose.yml`: Upload-Volume von named Volume (`steuerkram_uploads`) auf Bind Mount (`./uploads/`) umgestellt – konsistent mit `./data/mariadb/`
|
||
- `scripts/migrate-uploads-to-bindmount.sh`: Einmalige Migration hinzugefügt
|
||
|
||
### Update auf Produktiv-System
|
||
**Vor** `docker compose up` einmalig ausführen:
|
||
```bash
|
||
./scripts/migrate-uploads-to-bindmount.sh
|
||
```
|
||
Das Script kopiert alle Dateien aus dem named Volume in `./uploads/`, ist idempotent und gibt am Ende den Befehl zum Löschen des alten Volumes aus.
|
||
|
||
---
|
||
|
||
## 2026-04-11 – Buchungsbasierte Vorsteuer Kz 61/62 in UStVA
|
||
|
||
### Geändert
|
||
- `UstvaCalculator`: Kz 61 und 62 werden nicht mehr über `accounts.ustva_kz` geroutet, sondern direkt aus `bookings.ust_satz` ermittelt (`buchungstyp='Ausgabe'`, `betrag_ust != 0`). Damit reicht ein einziges Aufwandskonto für beide USt-Sätze – separate VSt19-/VSt7-Konten sind nicht mehr erforderlich
|
||
- `fetchBookingsForKz`: Drill-down für Kz 61/62 nutzt jetzt ebenfalls buchungsbasierte Filterung
|
||
- `BERICHTE.md`: Routing-Logik für Kz 61/62 dokumentiert
|
||
|
||
---
|
||
|
||
## 2026-04-10 – Nextcloud-Belegimport via WebDAV
|
||
|
||
### 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
|
||
- 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
|
||
|
||
---
|
||
|
||
## 2026-04-10 – UStVA Vorsteuer-Kz-Aufteilung (Migration 022)
|
||
|
||
### Fix
|
||
- Migration 022: Vorsteuer-Konten von `ustva_kz='66'` auf `'61'` (VSt19) bzw. `'62'` (VSt7) aufgeteilt – Kz 61, 62 und 66 wurden zuvor stets als 0 ausgewiesen
|
||
- `UstvaCalculator`: zweite Abfrage für steuerart-basierte EU-Kennzahlen (ig. Lieferung → Kz 41, Ausfuhr → Kz 44, ig. Erwerb → Kz 89/91/93/94); verhindert Doppelzählung gegenüber kontobasierter Berechnung
|
||
- `fetchBookingsForKz`: UNION-Abfrage aus Konto-Kz und steuerart für korrekten Drill-down
|
||
- Tests 4, 5, 6, 9: Kontonummern auf tatsächliche SKR03-Nummern korrigiert (8000→8400, 1400→1200)
|
||
|
||
---
|
||
|
||
## 2026-04-10 – Upload-Limit auf 20 MB erhöht
|
||
|
||
### Geändert
|
||
- `php/uploads.ini`: `upload_max_filesize` und `post_max_size` auf 20 MB gesetzt (zuvor PHP-Standard 2 MB)
|
||
- `Dockerfile`: bindet `php/uploads.ini` als PHP-Konfiguration ein
|
||
|
||
---
|
||
|
||
## 2026-04-10 – Belegtext-Speicherung für spätere Volltextsuche
|
||
|
||
### Neu
|
||
- Migration 021: Spalte `beleg_text MEDIUMTEXT` in `belege` – speichert den per `pdftotext` oder Tesseract-OCR extrahierten Volltext
|
||
- `KontierungsvorschlagService::extractText()`: neue public Methode zur Textextraktion (PDF + Bild), unabhängig vom KI-Vorschlag nutzbar
|
||
- Beim Generieren des KI-Vorschlags wird `beleg_text` automatisch befüllt (einmalig, nur wenn noch leer)
|
||
- `Beleg::saveBelegText()`: neue Methode im Model
|
||
|
||
---
|
||
|
||
## 2026-04-10 – OCR-Schalter unabhängig vom KI-Schalter
|
||
|
||
### Neu
|
||
- Einstellungen: separater Schalter „OCR-Texterkennung" (`ocr_aktiv`) zum unabhängigen Ein-/Ausschalten der Tesseract-OCR bei Bildbelegen (Migration 020)
|
||
- KI-Schalter und OCR-Schalter arbeiten nun vollständig unabhängig voneinander
|
||
- `KontierungsvorschlagService::isOcrEnabled()`: neue Methode, prüft OCR-Einstellung
|
||
- Bildbeleg-OCR wird nur noch ausgeführt, wenn `ocr_aktiv = 1`; PDF-Textextraktion via `pdftotext` läuft unabhängig davon
|
||
|
||
---
|
||
|
||
## 2026-04-02 – Kontenrahmen: Dokumentation und finale Korrekturen
|
||
|
||
### Neu
|
||
- `Kontenrahmen.md`: Vollständige Dokumentation aller SKR03-Systemkonten mit UStVA-Kennzahlen und EÜR-Zeilennummern
|
||
- Verweis auf `Kontenrahmen.md` in `README.md` ergänzt
|
||
|
||
### Geändert (Navigation)
|
||
- Kontenrahmen (`/accounts`) als eingerückter Untermenüpunkt unter „Einstellungen" in der Seitenleiste
|
||
- Konten-Tabelle aus `/settings` entfernt (war redundant zu `/accounts`)
|
||
|
||
### Geändert (UStVA-Kennzahlen, Migration 017)
|
||
- KZ `61` → `66` für alle VSt19-Konten (normale Inlands-Vorsteuer, § 15 Abs. 1 Nr. 1 UStG)
|
||
- KZ `62` → `66` für alle VSt7-Konten
|
||
- KZ `35` → `48` für 8100/8105/8110 (steuerfreie Umsätze ohne VoSt-Abzug)
|
||
- KZ `35` → `43` für 8120 (Ausfuhrlieferungen § 4 Nr. 1a UStG)
|
||
|
||
### Geändert (EÜR-Zeilennummern, Migration 019)
|
||
- 8400/8570/8720: Z. 14 → Z. 16 (19 %-Erlöse netto; Z. 14 = Kleinunternehmer brutto)
|
||
- 8120/8125: Z. 16 → Z. 18 (Ausfuhr/ig. Lieferungen)
|
||
- 8950: Z. 18 → Z. 21 (nicht steuerbare Innenumsätze)
|
||
- 4672: Z. 43 → Z. 51 (nicht abziehbarer Anteil Unternehmerreisekosten, § 4 Abs. 5 EStG)
|
||
- 4288: Z. 52 → Z. 65 (häusl. Arbeitszimmer abziehbar, eigene Zeile seit EÜR 2023)
|
||
- 4287: Z. 52 → Z. 66 (Tagespauschale häusl. Wohnung, eigene Zeile seit EÜR 2023)
|
||
- 4856: Z. 49 → Z. 37 (Sonderabschreibungen § 7b EStG)
|
||
|
||
### Kanonischer Seed (Migration 018)
|
||
- `018_seed_kontenrahmen_skr03_final.sql`: Alle 146 Systemkonten mit bereits korrekten UStVA-KZ und EÜR-Zeilen; Neuinstallationen erhalten den vollständigen aktuellen Stand ohne weitere Korrekturen
|
||
|
||
---
|
||
|
||
## 2026-04-01 – Feature: EÜR-Zeile in Konten-Übersicht anzeigen
|
||
|
||
### Neu
|
||
- Spalte „EÜR-Zeile" in der Konten-Liste (/accounts) ergänzt
|
||
- Zeigt den Wert `euer_zeile` je Konto an (z.B. 14, 26, 51, 52 oder „–" wenn leer)
|
||
|
||
## 2026-04-01 – Feature: Bewirtungsbelege (Konten 4650/4651) mit automatischem Split
|
||
|
||
### Neu
|
||
- Buchungen auf Konto 4650 (Bewirtungskosten VSt. 19%) oder 4651 (Bewirtungskosten VSt. 7%) werden automatisch aufgeteilt: 70 % auf das gewählte Konto, 30 % auf das Abzugskonto (4654 bzw. 4656)
|
||
- Neue Felder `bewirtungsgrund` und `teilnehmerliste` in der `bookings`-Tabelle (Migration 016)
|
||
- Im Buchungsformular erscheinen die beiden Felder automatisch, wenn 4650/4651 als Kategorie gewählt wird
|
||
- Vorhandene Buchungen zeigen Bewirtungsgrund und Teilnehmerliste in der Buchungsübersicht an
|
||
|
||
## 2026-04-01 – Bugfix: Nicht abzugsfähige Kosten (4654/4656) separat in EÜR unter KZ 165
|
||
|
||
### Behoben
|
||
- Konten mit `euer_zeile = '51'` (4654, 4656, 4635, 4636, 4289) fließen nicht mehr in `total_ausgaben` und `gewinn` ein
|
||
- Sie erscheinen in einem eigenen Abschnitt „Nicht abzugsfähige Betriebsausgaben (KZ 165)" in Web und PDF
|
||
- Migration 015 setzt `euer_zeile = '51'` für Konto 4656 (fehlte bisher)
|
||
|
||
---
|
||
|
||
## 2026-03-30 – Bugfix: 30 % Eigenanteil fließt jetzt korrekt in UStVA KZ 81/83
|
||
|
||
### Behoben
|
||
- `Booking::upsertEigenanteil30`: statt zwei Buchungen (8922 Netto + 1776 USt-Korrektur) wird
|
||
nur noch eine einzige Buchung auf 8922 mit echtem `ust_satz` und `betrag_ust` erzeugt
|
||
- `upsertKorrekturbuchung`: neue Parameter `ustSatz` und `betragUst`; UPDATE und INSERT setzen
|
||
jetzt `betrag_ust` und `betrag_brutto` korrekt
|
||
- Vorher: `betrag_ust = 0` auf 8922 → KZ 83 blieb leer; 1776-Buchung hatte keine UStVA-Wirkung
|
||
|
||
---
|
||
|
||
## 2026-03-30 – Kontenrahmen-Reset: DATEV SKR03 2026 (IST-Versteuerung)
|
||
|
||
### Geändert
|
||
- Alle Buchungen und Belege gelöscht (Testdaten)
|
||
- Gesamter Kontenrahmen durch DATEV SKR03 2026 (gültig ab 2026-01-01) ersetzt
|
||
- Neue Spalte `euer_zeile` in Tabelle `accounts`: Zeilennummer der Anlage EÜR
|
||
- 145 Konten neu angelegt: Klassen 0, 1, 3, 4, 8 (ohne Klasse 9 / ohne Verbindlichkeiten)
|
||
- Verfahren: IST-Versteuerung; Konto 1390 „Verrechnungskonto Ist-Versteuerung" enthalten
|
||
- UStVA-Kennzeichen korrekt nach DATEV: 81/86 (Umsätze), 61/62 (Vorsteuer), 35/41 (steuerfrei)
|
||
- Migration: `013_reset_kontenrahmen_skr03_2026.sql`
|
||
|
||
---
|
||
|
||
## 2026-03-30 – KI-gestützte Belegerkennung (experimentell) + 30 % Eigenanteil Telefon/Internet
|
||
|
||
### Neu
|
||
- Eigenanteil von 30 % bei Buchungen auf Telefon- und Internetkosten-Konten (4920/4925) wählbar
|
||
- Experimentelle KI-Beleganalyse: erkennt Buchungstyp, Betrag, Konto und Lieferant aus PDF/Bild-Belegen
|
||
- Setzt lokales LLM (z. B. Ollama/Mistral) oder Remote-API-Schlüssel voraus
|
||
- Hoher Ressourcenbedarf bei lokaler Ausführung; Ergebnisqualität mit Mistral bisher mäßig
|
||
- Getestet mit `ollama run mistral`
|
||
|
||
### Betrifft
|
||
- `src/Services/KontierungsvorschlagService.php`
|
||
- `src/Services/LlmService.php`
|
||
- `src/Views/belege/detail.php`, `list.php`
|
||
- `Dockerfile`, `docker-compose.yml`
|
||
|
||
---
|
||
|
||
## 2026-03-30 – Fix: Lieferant-Eingabe in Metadaten-Leiste speichert korrekt
|
||
|
||
### Geändert
|
||
- `supplier-persistent-input`: Nach erfolgreichem AJAX-Speichern wird das Texteingabefeld durch den Inline-Trigger-Span ersetzt – visuelle Bestätigung, dass der Lieferant gespeichert wurde
|
||
- Fehlerbehandlung (`try/catch`) hinzugefügt: bei fehlgeschlagenem Speichern bleibt das Feld editierbar
|
||
- Das versteckte Metaformular (`supplier_name_input`) wird nach AJAX-Speichern synchronisiert, damit ein späteres Absenden des Metaformulars den Lieferanten nicht überschreibt
|
||
|
||
### Betrifft
|
||
- `src/Views/belege/detail.php`
|
||
|
||
---
|
||
|
||
## 2026-03-30 – Lieferant inline editierbar + KI-Lieferantenerkennung
|
||
|
||
### Geändert
|
||
- Lieferant in der Beleg-Info-Bar ist jetzt direkt inline editierbar (Klick auf ✎), wie Belegdatum und Rechnungsnr.
|
||
- KI-Kontierungsvorschlag extrahiert nun auch den Lieferantennamen aus dem Beleg
|
||
- Nach KI-Analyse: bekannter Lieferant wird automatisch eingetragen; unbekannter Lieferant öffnet das Lieferantenfeld sofort mit Fokus
|
||
- KI-Badge zeigt Lieferantenname an, unbekannte Lieferanten werden als „(neu – bitte prüfen)" markiert
|
||
- Validierung in `KontierungsvorschlagService` prüft `zahlungskonto_id` und `kategorie_konto_id` jetzt gegen die korrekte Kontenart statt gegen alle Konten
|
||
|
||
### Betrifft
|
||
- `src/Services/KontierungsvorschlagService.php`
|
||
- `src/Views/belege/detail.php`
|
||
- `public/static/js/app.js`
|
||
|
||
---
|
||
|
||
## 2026-03-29 – EÜR: Spaltenauswahl nach Kontenart statt Buchungstyp
|
||
|
||
### Geändert
|
||
- `EuerCalculator::calculate()` wertet `accounts.kontenart` aus statt `buchungstyp`
|
||
- `Betriebseinnahme` → Einnahmen-Spalte, `Betriebsausgabe` → Ausgaben-Spalte
|
||
- `Privat`, `Zahlungskonto`, `Verbindlichkeit` als Kategorie-Konto werden nicht in der EÜR ausgewiesen
|
||
- Vorzeichen von `betrag_netto` werden beibehalten (kein `abs()` mehr) – negative Beträge mindern die jeweilige Spalte
|
||
- Buchungen desselben Kontos werden unabhängig vom `buchungstyp` zu einem Eintrag zusammengefasst
|
||
|
||
### Betrifft
|
||
- `src/Services/EuerCalculator.php`
|
||
- `BERICHTE.md` (EÜR-Kapitel aktualisiert)
|
||
|
||
---
|
||
|
||
## 2026-03-29 – UStVA: kontonummernbasierte Kennzahlenberechnung
|
||
|
||
### Geändert
|
||
- `UstvaCalculator::calculate()` wertet ausschließlich `accounts.ustva_kz` des Kategorie-Kontos aus – `buchungstyp` und `steuerart` werden nicht mehr benötigt
|
||
- `UstvaCalculator::fetchBookingsForKz()` filtert über `k.ustva_kz IN (...)` statt über Buchungsfelder
|
||
- Kz 83 und 84 kommen jetzt direkt aus `betrag_ust` der Erlöskonten (statt `Kz81 × 19 %`)
|
||
- Kz 91 und 94 kommen direkt aus `betrag_ust` der ig.-Erwerb-Konten (statt abgeleitet)
|
||
|
||
### Betrifft
|
||
- `src/Services/UstvaCalculator.php`
|
||
- Migration `010_ustva_kz_konto_mapping.sql`
|
||
- `BERICHTE.md` (UStVA-Kapitel vollständig neu)
|
||
|
||
### Migration 010 – Kontenanpassungen
|
||
- Alle Betriebsausgabe-Konten mit `steuercode='VSt19'`: `ustva_kz` von `'66'` auf `'61'`
|
||
- Alle Betriebsausgabe-Konten mit `steuercode='VSt7'`: `ustva_kz` von `'66'` auf `'62'`
|
||
- Neue Konten: 3425 „Innergemeinschaftliche Erwerbe 19 %" (`ustva_kz='89'`), 3420 „Innergemeinschaftliche Erwerbe 7 %" (`ustva_kz='93'`)
|
||
|
||
---
|
||
|
||
## 2026-03-28 – 30% Eigenanteil-Kennzeichnung und Korrekturbuchungen
|
||
|
||
### Hinzugefügt
|
||
- Checkbox „30% Eigenanteil buchen" in der Buchungszeilen-Erfassung (zwischen Nettobetrag und Submit-Button)
|
||
- Neues Feld `eigenanteil_30 TINYINT(1)` in der `belege`-Tabelle (Migration `009_beleg_eigenanteil_30.sql`)
|
||
- Der Checkbox-Wert wird beim Speichern einer Buchung in die Beleg-Metadaten übernommen
|
||
- Bei gesetzter Checkbox werden automatisch zwei Korrekturbuchungen angelegt oder aktualisiert:
|
||
- 30% des Nettobetrags an Konto 8922 (nicht abzugsfähiger Eigenanteil), Zahlungskonto 1800
|
||
- 30% der errechneten USt an Konto 1776 (Vorsteuerkorrektur), Zahlungskonto 1800 – nur wenn USt-Satz > 0
|
||
- Im Testmodus: bestehende Korrekturbuchungen werden direkt überschrieben
|
||
- Im Produktivmodus: bestehende Korrekturbuchungen werden GoBD-konform storniert und neu angelegt
|
||
|
||
### Betrifft
|
||
- `src/Views/belege/detail.php`
|
||
- `src/Controllers/BookingController.php`
|
||
- `src/Models/Booking.php` (neue Methoden `upsertEigenanteil30`, `upsertKorrekturbuchung`)
|
||
- Migration: `009_beleg_eigenanteil_30.sql`
|
||
|
||
---
|
||
|
||
## 2026-03-27 – DATEV-konformer SKR03 Kontenrahmen (#11)
|
||
|
||
### Geändert
|
||
- **Kontenrahmen**: Bisherige ~80 Konten durch DATEV-konformen SKR03 ersetzt (Migration `008_skr03_vollstaendig.sql`)
|
||
- **Umfang**: 157 Systemkonten aus Klassen 0 (Anlagevermögen), 1 (Zahlungsmittel, Vorsteuer, USt, Privat), 2 (Eigenkapital), 4 (Betriebsausgaben), 8 (Betriebseinnahmen)
|
||
- **EÜR-Fokus**: Keine Forderungs- oder Verbindlichkeitskonten (nicht bilanzierend)
|
||
- **Kompatibilität**: Alte Konten bleiben mit `is_system = 0` erhalten – bestehende Buchungen sind nicht betroffen
|
||
|
||
### Betrifft
|
||
- Migration: `008_skr03_vollstaendig.sql`
|
||
|
||
---
|
||
|
||
## 2026-03-27 – Ausgangsrechnungen in Dashboard/EÜR/UStVA (#8)
|
||
|
||
### Behoben
|
||
- **Seed-Skript**: `scripts/seed-testdata.php` rief `Invoice::finalize()` auf, ohne anschließend Beleg und Buchungen anzulegen – Ausgangsrechnungen fehlten daher in allen Auswertungen
|
||
- **Ursache**: `Invoice::finalize()` (Model) setzt nur Status und Rechnungsnummer; die Buchungserstellung liegt in `InvoiceController::createBelegAndBookings()` und wurde im Seed nicht aufgerufen
|
||
- **Fix**: Seed-Skript legt nach `Invoice::finalize()` nun Beleg und zugehörige Buchungen an (analog zur Controller-Logik), sodass Ausgangsrechnungen korrekt in EÜR, UStVA und Dashboard erscheinen
|
||
|
||
### Betrifft
|
||
- Skript: `scripts/seed-testdata.php`
|
||
- Test: `tests/09_InvoiceToReportsTest.php` (neu – End-to-End-Test Ausgangsrechnung → EÜR/UStVA/Dashboard)
|
||
|
||
---
|
||
|
||
## 2026-03-26 – Lieferantenmanagement (#7)
|
||
|
||
### Neu
|
||
- **Lieferantenverwaltung**: Neue Seite `/suppliers` zum Anlegen, Bearbeiten und Löschen von Lieferanten
|
||
- **Lieferant am Beleg**: Im Metadaten-Formular der Belegdetailseite kann ein Lieferant per Dropdown/Freitexteingabe ausgewählt werden; unbekannte Namen werden beim Speichern automatisch angelegt
|
||
- **Datenbank**: Tabelle `suppliers` (id, name) und Fremdschlüssel `supplier_id` in `belege`
|
||
- **Navigation**: Neuer Menüpunkt "Lieferanten" im Bereich Belege & Buchungen
|
||
|
||
### Betrifft
|
||
- Migration: `007_suppliers.sql`
|
||
- Model: `Supplier.php` (neu), `Beleg.php` (JOIN + updateMeta)
|
||
- Controller: `SupplierController.php` (neu), `BelegController.php`
|
||
- Views: `suppliers/list.php`, `suppliers/form.php` (neu), `belege/detail.php`, `layout/nav.php`
|
||
- Routes: `public/index.php`
|
||
- Test: `08_LieferantTest.php`
|
||
|
||
---
|
||
|
||
## 2026-03-26 – EÜR-Buchungsmodell (Soll/Haben → Einnahme/Ausgabe)
|
||
|
||
### Geändert
|
||
- **Buchungsmodell**: Doppelte Buchführung (Soll-Konto/Haben-Konto) durch reines EÜR-Modell ersetzt – jede Buchung hat nun `buchungstyp` (Einnahme/Ausgabe), `kategorie_konto_id` (Was?) und `zahlungskonto_id` (Wie bezahlt?)
|
||
- **Kontenarten**: Umbenannt von Aktiv/Passiv/Aufwand/Ertrag/Neutral zu Betriebseinnahme/Betriebsausgabe/Zahlungskonto/Verbindlichkeit/Privat
|
||
- **EÜR-Berechnung**: Vereinfacht – gruppiert direkt nach `buchungstyp` statt komplexer Soll/Haben-Ableitung
|
||
- **UStVA-Berechnung**: Verwendet `buchungstyp` statt Kontenart-Ableitung für USt/VSt-Zuordnung
|
||
- **UI-Terminologie**: Alle Bezeichnungen in Views, Journal, Dashboard und Formularen von Soll/Haben auf Typ/Kategorie/Zahlungskonto umgestellt
|
||
- **CSV-Export**: Spalten an neues Modell angepasst (Typ, Kategorie-Kto., Zahlungskonto-Kto.)
|
||
|
||
### Betrifft
|
||
- Schema (`001_initial_schema.sql`), Seed (`002_seed_skr03.sql`)
|
||
- Models: `Booking.php`, `Account.php`
|
||
- Services: `EuerCalculator.php`, `UstvaCalculator.php`
|
||
- Controllers: `BookingController.php`, `AccountController.php`, `InvoiceController.php`
|
||
- Views: `dashboard.php`, `journal.php`, `detail.php`, `accounts/form.php`, `accounts/list.php`
|
||
- JavaScript: `app.js`
|
||
- Tests: 02, 04, 05 aktualisiert + neuer Test 06 (EÜR-Buchungsmodell)
|
||
|
||
---
|
||
|
||
## 2026-03-25 – Session-Authentifizierung & Benutzerverwaltung
|
||
|
||
### Features
|
||
- **Session-Authentifizierung**: HTTP Basic Auth durch cookie-basierte Session-Authentifizierung ersetzt; Sessions laufen nach 24 Stunden absolut ab
|
||
- **Benutzerverwaltung** (`/useradmin`): Benutzer anlegen, bearbeiten (Benutzername und Passwort), deaktivieren und löschen; Passwörter mit bcrypt gehasht
|
||
- **Ersteinrichtungsflow**: Beim ersten Start ohne Benutzer ermöglicht `/login` das Anlegen des ersten Administrator-Accounts
|
||
- **Abmelden-Button** in der Seitenleiste
|
||
|
||
### Geändert
|
||
- `AUTH_USER` und `AUTH_PASS` entfernt – Zugangsdaten werden ausschließlich in der Datenbank verwaltet
|
||
- Neue Datenbanktabelle `users` (Migration `005_users.sql`)
|
||
|
||
### Behoben
|
||
- Fehler in `BelegController` behoben
|
||
|
||
---
|
||
|
||
## 2026-03-25 – Sicherheit, UX-Verbesserungen & Bugfixes
|
||
|
||
### Sicherheit
|
||
- **Timing-sicherer Login**: Passwort- und Benutzernamevergleich auf `hash_equals()` umgestellt (verhindert Timing-Angriffe)
|
||
- **SVG-Upload gesperrt**: Logo-Upload akzeptiert nur noch PNG und JPEG – SVG wurde entfernt (XSS-Risiko)
|
||
- **CSV-Injection-Schutz**: Felder im Buchungsjournal-CSV-Export werden gegen Formula-Injection (`=`, `+`, `-`, `@`) abgesichert
|
||
|
||
### Features
|
||
- **Inline-Editing**: Belegdatum und Rechnungsnr. können direkt in der Beleg-Detailansicht per Klick bearbeitet werden (kein Seitenreload)
|
||
- **Belegart-Filter**: Neue Filteroption in der Belegliste zum Filtern nach Belegart (Eingangsrechnung, Ausgangsrechnung, Quittung etc.)
|
||
- **Favicon & App-Icon**: Favicon für Browser-Tabs, Apple Touch Icon und Web-App-Manifest eingebunden
|
||
|
||
### Robustheit
|
||
- **Datenbankfehler-Handling**: PDO-Exceptions in Invoice-, Booking- und BelegController werden separat abgefangen und geloggt statt als generische Fehler zu erscheinen
|
||
|
||
---
|
||
|
||
## 2026-03-24 – Initiales Release
|
||
|
||
### Features
|
||
- **Basis-System**: MVC-Framework, Routing, Authentifizierung, Datenbank-Migrations-System
|
||
- **Ausgangsrechnungen**: Erstellen, Verwalten und PDF-Export von Ausgangsrechnungen
|
||
- **EÜR-Vorbereitung**: Einnahmen-Überschuss-Rechnung als PDF-Export
|
||
- **UStVA-Vorbereitung**: Umsatzsteuer-Voranmeldung inkl. XML-Export für elster.de
|