docs: Design und Plan „Duplikat → neue Version“
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
bc2d1cd4b7
commit
62d81dc25f
2 files changed
+512
No files matched your search
@@ -0,0 +1,225 @@
|
||||
# Duplikat → neue Version (Design)
|
||||
|
||||
Stand: 02.11.2026
|
||||
|
||||
## Worum es geht
|
||||
|
||||
Wird ein Beleg ein zweites Mal mit derselben **internen Belegnummer** nach
|
||||
Paperless gebracht, soll er nicht als zweites, eigenständiges Dokument landen.
|
||||
Stattdessen sieht der Benutzer beide Belege nebeneinander und entscheidet:
|
||||
|
||||
- **Als neue Version hinzufügen** – die Datei wird über die Versionsfunktion
|
||||
von Paperless-NGX an das vorhandene Dokument gehängt.
|
||||
- **Verwerfen** – der Beleg wird nicht importiert.
|
||||
|
||||
Typische Fälle:
|
||||
|
||||
1. **Korrigierte Rechnung**: Lieferant schickt eine fehlerbereinigte Fassung mit
|
||||
derselben Rechnungsnummer.
|
||||
2. **Nachträglich geteilt**: Ein Dokument enthielt zwei Belege. Der Benutzer
|
||||
teilt das PDF **von Hand** und sendet es neu; der Teil mit der bereits
|
||||
vergebenen Belegnummer wird zur neuen Version.
|
||||
|
||||
## Ziele
|
||||
|
||||
- Gleicher Vergleichsdialog im **E-Mail-Import** und im **Posteingang (Scanner)**.
|
||||
- Oben im Dialog eine Leiste mit **Auffälligkeiten**: abweichende
|
||||
**Seitenzahl** und abweichende **Wortzahl**. Darunter beide PDFs nebeneinander.
|
||||
- Maßgeblich für „Belegnummer existiert schon“ ist **Paperless** (Custom Field 7
|
||||
= interne Belegnummer). Das ist die wichtige Prüfung.
|
||||
|
||||
## Nicht-Ziele
|
||||
|
||||
- Umbau der Task-Bearbeitung – läuft unverändert weiter.
|
||||
- **Checksummen-Duplikate umgehen** (gleiche Datei erneut importieren) – bleibt
|
||||
wie heute, wird in `docs/todos.md` notiert.
|
||||
- Inhaltliche Analyse (Beträge, Datum, Positionen) für die Auffälligkeiten –
|
||||
dafür gibt es noch keine Auswertung.
|
||||
- Metadaten des vorhandenen Dokuments ändern (Titel, Tags, Custom Fields,
|
||||
Korrespondent bleiben unverändert; nur die Datei kommt als Version dazu).
|
||||
- Nachgelagerte Automatik für die Version (Postprocessing-Regeln, Mail,
|
||||
WebDAV-Export, Agrarmonitor-Austausch/Storno) – wird vorerst **unterdrückt**,
|
||||
die fachliche Logik kommt später (siehe Todos).
|
||||
|
||||
## Anti-Ziele (wäre ein Fehlschlag, auch wenn es „funktioniert“)
|
||||
|
||||
- Ein Beleg mit vorhandener Belegnummer landet doch als zweites Dokument in
|
||||
Paperless, ohne dass der Benutzer es so entschieden hat.
|
||||
- Eine Version wird an das **falsche** Dokument gehängt.
|
||||
- „Verwerfen“ lässt eine reservierte Belegnummer oder einen halb angelegten
|
||||
Task zurück.
|
||||
|
||||
## Paperless-API (am Live-System geprüft, API v10)
|
||||
|
||||
- `POST /api/documents/{id}/update_version/` – multipart, Feld `document`
|
||||
(Datei, Pflicht), `version_label` (optional, max. 64 Zeichen). Antwort: String
|
||||
(vermutlich die Consume-Task-ID; Verarbeitung asynchron).
|
||||
- `PATCH|DELETE /api/documents/{id}/versions/{version_id}/` – Label ändern/löschen.
|
||||
- `DocumentVersionInfo`: `id`, `added`, `version_label`, `checksum`, `is_root`.
|
||||
|
||||
## Ablauf E-Mail-Import (`MailImportWizard.tsx`)
|
||||
|
||||
Schritte: 0 Zuordnung → 1 Bearbeitung → 2 Abschluss.
|
||||
|
||||
1. In Schritt 1 („Bearbeitung“) hat ein Beleg den Modus **Manuell** und eine
|
||||
Belegnummer (Jahr + 6-stellige Nummer → `JJJJ-NNNNNN`).
|
||||
2. Beim Klick auf **Weiter** (Schritt 1 → 2) prüft das Backend für jeden
|
||||
manuellen Beleg in Paperless, ob die Belegnummer schon vergeben ist (CF7 und
|
||||
ASN, siehe „Eindeutigkeit des Treffers“).
|
||||
3. Gibt es Treffer, öffnet sich **vor** dem Schrittwechsel der Vergleichsdialog
|
||||
– nacheinander für jeden betroffenen Beleg.
|
||||
- Links: vorhandenes Dokument aus Paperless. Rechts: der neue Beleg (bei
|
||||
geteilten Anhängen nur die gewählten Seiten).
|
||||
- **Als neue Version hinzufügen** → Beleg wird für den Import als
|
||||
„Version zu Dokument X“ markiert.
|
||||
- **Verwerfen** → Beleg wird auf `IGNORE` gestellt. Stehen danach alle Belege
|
||||
der Mail auf `IGNORE`, greift die bestehende Logik (Mail als ignoriert
|
||||
markieren).
|
||||
- Dialog schließen (X) ohne Entscheidung → kein Schrittwechsel, der Benutzer
|
||||
bleibt in Schritt 1.
|
||||
4. Beim **Import ausführen** werden Version-Belege nicht per `post_document`
|
||||
hochgeladen, sondern per `update_version` an Dokument X gehängt.
|
||||
- Die ASN-Sperre (`validateAsnNotExists`) und der Belegnummer-Duplikatcheck
|
||||
entfallen für diese Belege – sonst würde der Import abbrechen.
|
||||
- Hochgeladen wird wie beim normalen Import das Original-PDF bzw. die
|
||||
gewählten Seiten, ohne eingebrannten Stempel.
|
||||
- Kein neuer Enrichment-Task in der `tasks`-Tabelle nötig (Metadaten bleiben).
|
||||
- Im `Attachment`-Datensatz wird die Dokument-ID X unter dem jeweiligen
|
||||
Bereich eingetragen, damit der Anhang als importiert gilt.
|
||||
5. Die Checksummen-Prüfung (`recheckDuplicates`) bleibt unverändert.
|
||||
|
||||
## Ablauf Posteingang (`InboxDetailPage.tsx`, `inbox-postprocessor`)
|
||||
|
||||
Heute: `runPaperless` meldet ein Duplikat mit `duplicateOfDocumentId`; der
|
||||
Wizard bietet „Neue Version erstellen“ (= Duplikatprüfung überspringen und als
|
||||
zweites Dokument hochladen), „Vergleichen“ und „Überspringen“. Im
|
||||
Vergleichsdialog ist „Neue Version anlegen“ noch ein TODO.
|
||||
|
||||
Neu:
|
||||
|
||||
- Liefert der Duplikat-Treffer eine Paperless-Dokument-ID, öffnet sich der
|
||||
Vergleichsdialog **automatisch**.
|
||||
- **Als neue Version hinzufügen** → Backend verarbeitet den Abschnitt erneut,
|
||||
lädt die fertige PDF (nach allen Bearbeitungen/Stempeln) aber per
|
||||
`update_version` an Dokument X hoch statt per `post_document`. Danach ist der
|
||||
Abschnitt „erfolgreich“.
|
||||
- **Verwerfen** → entspricht dem heutigen „Überspringen“ (Text wird umbenannt).
|
||||
- Der bisherige Weg „Duplikatprüfung überspringen und als eigenes Dokument
|
||||
hochladen“ entfällt in der Oberfläche.
|
||||
- Duplikate **ohne** Dokument-ID (Checksumme, lokaler Task ohne
|
||||
`PaperlessDocumentID`) behalten den heutigen Weg: nur Verwerfen/Überspringen.
|
||||
- Rechts im Dialog wird der **betroffene Abschnitt** gezeigt, nicht das ganze
|
||||
Inbox-Dokument (heute zeigt der Dialog das ganze Dokument).
|
||||
|
||||
## Nachgelagerte Automatik unterdrücken
|
||||
|
||||
Entscheidung des Nutzers: Nach dem Hinzufügen einer Version bekommt das
|
||||
(Stamm-)Dokument den Tag **„neue Version hochgeladen“ (ID 21)**. Der Nutzer
|
||||
konfiguriert die Postprocessing-Regeln so, dass Belege mit Tag 21 ignoriert
|
||||
werden. Im Code gibt es **keine** eigene Unterdrückung (keine Markierung, keine
|
||||
Änderung an der Webhook-Warteschlange).
|
||||
|
||||
- Reihenfolge: **erst** Tag 21 setzen (Tags lesen, 21 ergänzen, vorhandene
|
||||
behalten), **dann** `update_version`. Schlägt der Versions-Upload fehl, wird
|
||||
Tag 21 wieder entfernt – aber nur, wenn er vorher nicht schon gesetzt war.
|
||||
- Entfernen von Tag 21 ist Sache des Nutzers.
|
||||
- Die Anreicherung in `processDocumentById` (Tag 17, bereit/nicht bereit,
|
||||
Titel-Template) läuft beim Webhook weiterhin – nur die Regeln greifen nicht.
|
||||
|
||||
Im **Posteingang** betrifft die Abfrage nur die Aktion „An Paperless senden“.
|
||||
Die übrigen Aktionen des Barcode-Templates (MAIL, EXPORT) davor und danach
|
||||
laufen normal: Die Aktionen davor sind beim Erkennen des Duplikats bereits
|
||||
gelaufen und werden nicht wiederholt; die Aktionen danach werden nach der
|
||||
Entscheidung (Version **oder** Verwerfen) ganz normal ausgeführt.
|
||||
|
||||
## Vergleichsdialog (gemeinsame Komponente)
|
||||
|
||||
- Eine Komponente für beide Stellen (aus `CompareModal` herauslösen).
|
||||
- Titel z. B. „Belegnummer 2026-000123 existiert bereits“.
|
||||
- **Auffälligkeiten-Leiste** oben (Ant Design `Alert`/`Tag`s):
|
||||
- Seitenzahl: „Seiten: 2 (vorhanden) → 3 (neu)“ – hervorgehoben bei Abweichung.
|
||||
- Wortzahl: „Wörter: 412 → 398“ – hervorgehoben bei Abweichung.
|
||||
- Ist eine Zahl nicht ermittelbar (z. B. PDF ohne Textebene), steht dort
|
||||
„nicht ermittelbar“ statt einer Abweichung.
|
||||
- Keine Abweichung → kurzer neutraler Hinweis „Seiten- und Wortzahl gleich“.
|
||||
- Darunter beide PDFs nebeneinander (mobil untereinander), wie heute.
|
||||
- Knöpfe: **Verwerfen** / **Als neue Version hinzufügen** (primär).
|
||||
|
||||
### Kennzahlen ermitteln (Backend-Endpunkt)
|
||||
|
||||
- Vorhanden (Paperless): Seitenzahl aus `page_count` des Dokuments, Wortzahl aus
|
||||
dessen `content` (OCR-Text von Paperless). Verglichen wird mit der aktuellen
|
||||
(neuesten) Fassung des Dokuments.
|
||||
- Neu: Seitenzahl per `pdf-lib`, Wortzahl aus der Textebene per `pdf-parse`
|
||||
(beides bereits Abhängigkeiten im Backend). Keine Textebene → „nicht
|
||||
ermittelbar“.
|
||||
- Wortzählung: Text an Leerraum trennen, nur Tokens mit mindestens einem
|
||||
Buchstaben oder einer Ziffer zählen.
|
||||
|
||||
## Versionsbezeichnung
|
||||
|
||||
`version_label` = „Korrektur vom TT.MM.JJJJ“ (Datum des Hinzufügens). Max. 64 Zeichen.
|
||||
|
||||
## Eindeutigkeit des Treffers
|
||||
|
||||
Geprüft wird immer gegen Paperless, und zwar über **beide** Merkmale, die aus
|
||||
der internen Belegnummer folgen:
|
||||
|
||||
- CF7 = interne Belegnummer (z. B. `2026-000123`)
|
||||
- ASN = interne Belegnummer ohne Bindestrich (z. B. `2026000123`) – auch im
|
||||
Posteingang, unabhängig von einem im Template separat hinterlegten ASN-Feld.
|
||||
|
||||
„Als neue Version hinzufügen“ wird nur angeboten, wenn alle Treffer auf **genau
|
||||
ein** Dokument zeigen. Zeigen CF7- und ASN-Treffer auf verschiedene Dokumente
|
||||
oder gibt es mehrere CF7-Treffer, zeigt der Dialog einen Hinweis und bietet nur
|
||||
**Verwerfen** an. Dafür muss die Suche alle Treffer liefern, nicht nur den ersten.
|
||||
|
||||
## Am Live-System zu prüfen (vor/bei der Umsetzung)
|
||||
|
||||
- Antwort von `update_version` (Task-ID?) und wie der Abschluss erkennbar ist.
|
||||
- Liefern CF7-Suche, `GET /documents/{id}/` (`content`, `page_count`) und
|
||||
`/download/` bei einem versionierten Dokument die Stamm-ID bzw. die neueste
|
||||
Fassung? `update_version` muss immer auf die Stamm-ID zielen.
|
||||
|
||||
## Todos-Einträge
|
||||
|
||||
In `docs/todos.md` ergänzen:
|
||||
|
||||
1. „Duplikatprüfung per Checksumme gezielt umgehen können, wenn ein bereits
|
||||
importiertes Dokument bewusst erneut importiert (z. B. geteilt) werden soll.“
|
||||
2. „Neue Version eines Belegs in Agrarmonitor nachziehen (derzeit unterdrückt):
|
||||
- Beleg noch im AM-Posteingang → dort löschen und neue Fassung senden.
|
||||
- Beleg verarbeitet, aber nicht gebucht → im jeweiligen Einkauf das
|
||||
vorhandene Dokument löschen und die neue Fassung hochladen.
|
||||
- Beleg bereits gebucht → Storno-Beleg zum gebuchten Beleg erstellen und die
|
||||
neue Fassung über die jeweilige E-Mail-Adresse neu in den AM-Posteingang
|
||||
senden.
|
||||
Außerdem klären, ob Postprocessing-Regeln (Mail an Buchhaltung, Export) für
|
||||
Versionen laufen sollen.“
|
||||
3. „Task-Bearbeitung (`PaperlessTaskProcessorService`, 30-s-Cron) auf den
|
||||
Paperless-Webhook umstellen. Beim Upload werden die Metadaten schon gesetzt;
|
||||
übrig bleiben Owner entfernen, Notizen, Anlage-Verknüpfung (Feld 8) und die
|
||||
lokale Buchführung (Task/Attachment/documents) – die brauchen die
|
||||
Dokument-ID nach dem Consume.“
|
||||
|
||||
## Dem Umsetzer überlassen
|
||||
|
||||
- Schnitt der Backend-Endpunkte (eigener Endpunkt für „Belegnummern prüfen“ und
|
||||
„Kennzahlen“, oder zusammengefasst).
|
||||
- Wie das Ergebnis von `update_version` verfolgt wird (Task-Polling wie beim
|
||||
normalen Upload, sofern die Antwort eine Task-ID ist).
|
||||
- Tests: mindestens Unit-Tests für Wortzählung/Auffälligkeiten und für die
|
||||
Entscheidung Upload vs. Version im Backend.
|
||||
|
||||
## Eigene Entscheidungen (nicht ausdrücklich vom Nutzer)
|
||||
|
||||
- Versionsbezeichnung „Korrektur vom …“.
|
||||
- Version nur bei eindeutigem Treffer (CF7 und ASN zeigen auf dasselbe
|
||||
Dokument); sonst nur Verwerfen.
|
||||
- E-Mail-Import: Version wird wie normale Importe ohne eingebrannten Stempel
|
||||
hochgeladen; keine erneute Barcode-Notiz (die hat das Stammdokument schon).
|
||||
|
||||
- Automatisches Öffnen des Dialogs im Posteingang; Wegfall von „als eigenes
|
||||
Dokument hochladen“.
|
||||
- Dialog schließen ohne Entscheidung = im Schritt bleiben.
|
||||
- Rechts nur der betroffene Abschnitt statt des ganzen Inbox-Dokuments.
|
||||
Reference in new issue
Block a user