Commit Graph

98 Commits

Author SHA1 Message Date
dfuhrmann3 58e589aa7a ui: remove BT-49 required-asterisk; drop noisy serial-numbers caption
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 15:58:37 +02:00
dfuhrmann3 3dcb293ba4 ui: clearer BT-49 blocker hint for XRechnung (guide to Leitweg-ID + scheme 0204)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 15:54:00 +02:00
dfuhrmann3 e6897bd263 ui: larger, more prominent tabs + hint to check all three tabs before export
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 15:49:06 +02:00
dfuhrmann3 34251a7ad2 fix(bt-49): use 'X' placeholder + orange warning for ZUGFeRD without buyer address
ZUGFeRD (B2B) ohne Kunden-E-Mail: statt leerem BT-49 wird der Platzhalter 'X' gesetzt (Feld fehlt
nicht komplett), dazu eine orange Warnung (st.warning), dass eine echte Empfaenger-E-Mail besser
waere. XRechnung bleibt hart blockierend.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 15:45:37 +02:00
dfuhrmann3 d2d09054d2 fix(bt-49): block only for XRechnung; soft warning (not blocker) for ZUGFeRD
XRechnung: BT-49 bleibt Pflicht (blockiert bei leer). ZUGFeRD (B2B): leer ist erlaubt, es wird
nur ein Hinweis angezeigt, dass eine Empfaenger-E-Mail besser waere (Peppol R010).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 15:38:46 +02:00
dfuhrmann3 308cddedef fix(bt-10): fall back to customer number when no Leitweg-ID (BR-DE-15)
Validatoren bemaengelten leeres BT-10 (Kaeuferreferenz, in XRechnung Pflicht). BT-10 nutzt jetzt
die Leitweg-ID (Behoerden) und faellt sonst auf die Kundennummer zurueck - so ist das Feld nie
leer, BT-46 (Kundennummer) bleibt zusaetzlich erhalten. UI-Blocker/Hilfetext angepasst.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 15:29:57 +02:00
dfuhrmann3 1851ed7074 fix(parser): stop description scan at sub-position numbers like '2.1' (ZenIT R26-105)
Bei Unterpositionsnummern ('N.M', z.B. 2.1) lief der Beschreibungs-Scan nach oben ueber die
Referenzzeilen hinweg -> Artikelname war faelschlich die Auftragsbestaetigungs-Zeile und die
Beschreibung enthielt Referenzen + Positionsnummer. Jetzt bricht der Scan auch bei gegliederten
Nummern ab. Seriennummer-Fragmente (reine Ziffern ohne Punkt) bleiben unberuehrt.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 15:15:38 +02:00
dfuhrmann3 71bb9885c6 feat: auto-detect invoice type (BT-3) from title (Teilrechnung->326)
'Teilrechnung' im Rechnungstitel setzt den Rechnungstyp automatisch auf 326, 'Korrekturrechnung'
auf 384; sonst 380. Das Dropdown ist mit dem erkannten Typ vorbelegt und bleibt aenderbar.
Verifiziert gegen 7 echte Rechnungen (ZenIT -> 326, alle anderen -> 380).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 15:08:56 +02:00
dfuhrmann3 ac233baa2f feat: BT-41 Bearbeiter, BT-34/BT-43 split, Ihr Auftrag->BT-13, Referenznummer->Freitext
- BT-41: Bearbeiter wird aus der Rechnung erkannt (deterministisch) und als editierbares
  Kopfdaten-Feld gefuehrt; ersetzt das fixe 'Geschaeftsfuehrung' (kein Fallback, leer bleibt leer).
- BT-34 und BT-43 als zwei getrennte, editierbare Verkaeufer-Felder (elektronische Adresse vs.
  Kontakt-E-Mail), beide vorbelegt mit der office-Mail.
- 'Ihr Auftrag' deterministisch in BT-13 (statt LLM-Fehlzuordnung nach BT-14).
- 'Referenznummer' (z.B. SAP) hat kein EN16931-Feld -> in den Freitext (BT-22).
- Generatoren fallen ohne die neuen Keys auf VERKAEUFER zurueck (Golden-Verhalten unveraendert).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 15:03:51 +02:00
dfuhrmann3 f92c4ffac6 feat: clear data panel on new upload; deterministic doc-reference routing (Vergabeangebot->BT-17)
- Rechts angezeigte Rechnungsdaten werden verworfen, sobald eine neue/andere PDF geladen wird
  (nicht mehr die vorige Rechnung bis zum erneuten Extrahieren).
- extract_document_references(): Auftragsbestaetigung->BT-14, Lieferschein->BT-16,
  Vergabeangebot->BT-17 deterministisch aus den Referenzzeilen; korrigiert LLM-Fehlzuordnung
  (Vergabeangebot landete faelschlich in BT-12 Vertrag). Verifiziert gegen 7 echte Rechnungen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 14:49:35 +02:00
dfuhrmann3 3832d5cdf2 feat(parser): deterministic pre-position free text into BT-22 (Task 3a)
- extract_pre_position_freetext(): liest den Vorlauftext zwischen Tabellenkopf ('Pos.') und
  erster Position direkt aus dem PDF-Text (ohne Referenzzeilen), statt sich auf das oft
  unvollstaendige LLM-Feld zu verlassen. Ersetzt invoice_note, wenn die Struktur erkannt wird.
  Verifiziert gegen 7 echte Rechnungen (vollstaendiger Freitext bei BIM/valantic/degewo/ZenIT,
  korrekt leer bei Gemeinde/Stadtwerke).
- ANGEBOT-Regex: Wortgrenze ergaenzt, damit 'VERGABEANGEBOT' (BT-17) nicht mehr faelschlich als
  'Angebot' erkannt und tender_id nicht mehr faelschlich geleert wird.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 13:03:51 +02:00
dfuhrmann3 3e0975102f fix(parser): recognize abbreviated unit 'pausch.' (Rechnung R26-231 Anfahrt)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 12:51:09 +02:00
dfuhrmann3 df81c011d3 fix(zugferd): robust factur-x embedding for varied PDF structures
Fehler 'unable to find page tree' beim ZUGFeRD-Export mancher PDFs (z.B. von PDF-XChange
erzeugte degewo-Rechnung): factur-x bettete die XML nicht ein und zerstoerte den Seitenbaum.

- build_zugferd_pdf versucht zuerst die Original-PDF; schlaegt das fehl (Absturz ODER XML
  nicht eingebettet), wird die PDF mit pikepdf normalisiert (neu gespeichert) und erneut
  versucht. Manche PDFs funktionieren nur original, andere nur normalisiert - beide Wege
  abgedeckt, Erfolgskontrolle via pdf_has_embedded_facturx.
- Neue Helfer normalize_pdf_bytes() und pdf_has_embedded_facturx() in invoice_logic.
- Verifiziert auf beiden echten Rechnungen (degewo -> Fallback, Gemeinde -> Original).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 11:48:48 +02:00
dfuhrmann3 29034d8501 fix(parser): capture positions with split serial numbers; keep Angebot out of BT-12/BT-17
- Positionsscan bricht nur noch bei der ECHTEN Positionsnummer (len(items)+1) ab, nicht
  bei alleinstehenden Ziffern-Fragmenten aufgesplitteter Seriennummern (Rechnung R26-224:
  Position wurde sonst ganz verworfen). Seriennummern landen jetzt in der Beschreibung (BT-154).
- Angebotsnummer wird aus Vertrag (BT-12)/Vergabeangebot (BT-17) entfernt, falls das LLM sie
  dort eingeordnet hat - Angebot gehoert nur in den Freitext (BT-22). Schema-Beschreibungen
  entsprechend praezisiert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 11:30:27 +02:00
dfuhrmann3 cd2bd56377 fix(parser): recognize 'pauschal' as a billing unit (Anfahrt-Position)
Rechnung R26-232 Position 3 (Anfahrt, '2,00 pauschal') wurde uebersprungen, weil
'pauschal' nicht in der Einheiten-Erkennung stand. Ergaenzt: Pauschale/Pauschal/Psch.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 11:06:01 +02:00
dfuhrmann3 5a9929aa9e feat: BT-46 Kundennummer, BT-10 Leitweg-ID, BT-17 Vergabeangebot, Angebot->Freitext, format-abh. Pflichtfelder
- Kundennummer jetzt BT-46 (eigenes Feld), getrennt von Leitweg-ID (BT-10)
- BT-10 Leitweg-ID: eigenes Feld, leer per Default; nur bei XRechnung Pflicht (BR-DE-15),
  bei ZUGFeRD optional (kein Blocker, kein XML-Eintrag wenn leer)
- BT-12 nur noch Vertrag; Vergabeangebot/Ausschreibung als neues Feld BT-17
  (UBL OriginatorDocumentReference, CII AdditionalReferencedDocument TypeCode 50)
- 'Angebot <Nr> vom <Datum>' wird erkannt und in den Freitext (BT-22) uebernommen
- BT-49 elektronische Adresse: bei ZUGFeRD optional (kein Blocker, in CII weggelassen wenn leer),
  bei XRechnung weiterhin Pflicht; Hinweis: E-Mail oder Netzwerkcode

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-13 10:38:56 +02:00
dfuhrmann3 9a7dca1498 feat: descriptive export filenames, Vorkasse note (BT-20), dynamic BT-49 scheme
- Export-Dateiname: <Rechnungsnummer>_<Empfaenger>_<Rechnungsdatum> (dateisicher)
- Vorkasse-Schalter schreibt Hinweis in Zahlungsbedingungen (BT-20); Zahlungsmittelcode unveraendert
- BT-49 elektronische Kaeufer-Adresse: Schema (BT-49-1) manuell waehlbar (EM/0204/0088), Default EM

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 11:03:32 +02:00
dfuhrmann3 27f6d8bab7 fix(cii): format ZUGFeRD BilledQuantity like UBL (no trailing 1.0000)
Ganze Mengen erscheinen als 1.00 statt 1.0000; gebrochene Mengen (z.B. 1.375
Tage) bleiben vollstaendig erhalten. Vereinheitlicht mit dem UBL-Generator.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 16:35:19 +02:00
dfuhrmann3 8a7990f95f refactor(ui): move ZUGFeRD validation hint from per-export box into footer
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 16:31:55 +02:00
dfuhrmann3 19cdff820d feat(ui): rename tabs to Kopfdaten/Adressen/Positionen
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 16:24:42 +02:00
dfuhrmann3 1992c30991 feat(ui): PDF-Text back under PDF preview; one-click export+download
- Extracted-text expander moved back to left column under PDF preview (PDF-Text tab removed, now 3 tabs)
- Export button now generates and downloads in a single click via st.download_button
- ZUGFeRD generation cached (st.cache_data) so it doesn't rerun on every keystroke

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 16:21:53 +02:00
dfuhrmann3 c07eb860fa feat(ui): group validation fields into tabs (Basis/Parteien/Positionen/PDF-Text)
Reduces scrolling - Summen und Export bleiben unterhalb der Tabs immer sichtbar.
Reine UI-Umgruppierung, keine Aenderung an Feldern oder Berechnungslogik.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 16:14:17 +02:00
dfuhrmann3 efdee4cfd6 feat: default export format to ZUGFeRD instead of XRechnung
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 16:01:53 +02:00
dfuhrmann3 36af456cd8 chore: keep tests, test-config and planning docs local-only (untrack from repo)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 15:57:09 +02:00
dfuhrmann3 e4f2315179 chore: ignore __pycache__/*.pyc in git and docker, untrack committed bytecode
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 15:49:56 +02:00
dfuhrmann3 656040b64b test 2026-07-07 15:36:46 +02:00
dfuhrmann3 16566ef858 chore: remove unused Decimal import from main.py (final review cleanup)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 15:32:37 +02:00
dfuhrmann3 3a621eb805 test: add end-to-end integration test covering all Phase 1 features together 2026-07-07 15:27:00 +02:00
dfuhrmann3 3b3a2dce90 feat: extend regex parser for IT-Systemhaus service periods, contract types, and serial numbers
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 15:16:30 +02:00
dfuhrmann3 0dd9916079 feat: add document-level discount (BT-21) and Skonto payment terms (BT-20) 2026-07-07 15:10:35 +02:00
dfuhrmann3 d7b851ae36 feat: support mixed VAT rates per line (BG-23) in both XML generators 2026-07-07 15:03:09 +02:00
dfuhrmann3 6ecd59e5ea feat: make payment means code (BT-81) dynamically selectable 2026-07-07 14:54:17 +02:00
dfuhrmann3 ae986b4f3f refactor: extract pure invoice logic into invoice_logic.py for testability
Move all dependency-free business logic (metadata schema, rounding/parsing
helpers, item extraction, and the XRechnung/ZUGFeRD XML generators plus the
PDF/A output-intent helpers) out of main.py into a new invoice_logic.py that
imports only pydantic and pikepdf. This makes the logic unit-testable without
a Streamlit runtime. Pure cut-and-paste, no behavior change; main.py now
imports these names from invoice_logic instead of defining them locally.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 13:43:13 +02:00
dfuhrmann3 4181346f4a docs: add Phase 1 backend implementation plan
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-07 13:32:04 +02:00
dfuhrmann3 994ad03387 Footer Text Update 2026-07-07 11:12:06 +02:00
dfuhrmann3 eb7aa73653 Update 2026-07-07 11:09:47 +02:00
dfuhrmann3 a0d80c5d08 Merge branch 'test-version' Update auf ZUGFeRD mit Konformität und PDF-Ansicht 2026-07-07 10:58:46 +02:00
dfuhrmann3 7b5cd86974 Test 2026-07-07 10:52:43 +02:00
dfuhrmann3 fa977594eb Test 2026-07-07 10:23:51 +02:00
dfuhrmann3 aad83afd54 Test 2026-07-07 10:03:41 +02:00
dfuhrmann3 ebf172276a Test 2026-07-07 09:49:28 +02:00
dfuhrmann3 e80d011c88 Test 2026-07-06 14:09:15 +02:00
dfuhrmann3 076e976298 Test 2026-07-06 13:42:28 +02:00
dfuhrmann3 75c9d113bc Test 2026-07-06 12:53:48 +02:00
dfuhrmann3 3e59cd188e Test 2026-07-06 11:22:11 +02:00
dfuhrmann3 37b7986831 Test 2026-07-06 11:12:39 +02:00
dfuhrmann3 ec8352682e Test 2026-07-06 10:54:43 +02:00
dfuhrmann3 381216d619 Test 2026-07-06 10:51:36 +02:00
dfuhrmann3 00fe916c06 Test 2026-07-06 10:30:35 +02:00
dfuhrmann3 a5c27f5475 Test 2026-07-06 10:13:30 +02:00