WORDTEMPLATESERVICE - TECHNISCHE REFERENZ
==========================================

Stand: 2026-01-27
Status: Produktiv (v1.1)

Der WordTemplateService fuellt Word-Vorlagen mit Daten aus einer
JSON-Struktur. Er ist ein allgemeiner BACH-Service, der vom
Foerderbericht-System genutzt wird.

Datei: skills/_services/document/word_template_service.py


PLATZHALTER-SYSTEM
==================

Platzhalter in der Word-Vorlage haben das Format: {{NAME}}

  Beispiele:
    {{NAME}}                 → "Felix Bergmann"
    {{GEBURTSDATUM}}         → "22.07.2016"
    {{SACHBEARBEITER}}       → "Frau Hoffmann"
    {{DIAGNOSEN}}            → Diagnose-Text

  Regeln:
  - Doppelte geschweifte Klammern: {{ und }}
  - Grossbuchstaben mit Unterstrichen
  - Platzhalter koennen in Paragraphen ODER Tabellenzellen stehen
  - Ein Platzhalter kann ueber mehrere Runs verteilt sein
    (Word fragmentiert Text intern in Runs)


RUN-FRAGMENTIERUNG
==================

Word speichert Text nicht als zusammenhaengenden String, sondern als
"Runs" — Textfragmente mit eigener Formatierung. Ein Platzhalter wie
{{NAME}} kann so gespeichert sein:

  Run 1: "{{NA"
  Run 2: "ME}}"

Der Service erkennt dies und fuegt Runs zusammen:
  1. Alle Runs eines Paragraphen zu einem String verketten
  2. Platzhalter im Gesamtstring suchen
  3. Ersetzung durchfuehren
  4. Ergebnis in den ersten Run schreiben, restliche Runs leeren


TABELLEN-VERARBEITUNG
=====================

DYNAMISCHE FOERDERZIEL-TABELLEN
---------------------------------
Die Vorlage enthaelt eine Foerderziele-Tabelle mit Platzhalter-Zeilen:

  | ICF-Code | Zielformulierung | Ist-Stand | Erreicht |
  |----------|------------------|-----------|----------|
  | {{Z1_C}} | {{Z1_ZIEL}}      | {{Z1_IST}}| {{Z1_E}} |
  | {{Z2_C}} | {{Z2_ZIEL}}      | {{Z2_IST}}| {{Z2_E}} |

Der Generator:
  1. Fuellt vorhandene Platzhalter-Zeilen mit Daten
  2. Entfernt ueberzaehlige Platzhalter-Zeilen
  3. Fuegt bei Bedarf neue Zeilen hinzu (Zeile klonen)


ICF-BEREICHS-FILTERUNG (3-PHASEN-ALGORITHMUS)
-----------------------------------------------
Inaktive ICF-Bereiche werden aus dem Dokument entfernt:

  Phase 1: UEBERSCHRIFT FINDEN
    Suche nach Bereichsnamen in der Tabelle (z.B. "Mobilitaet").
    Identifiziere die Zeile mit der Bereichs-Ueberschrift.

  Phase 2: INHALTSZEILEN IDENTIFIZIEREN
    Ab der Ueberschrift alle folgenden Zeilen sammeln,
    bis die naechste Bereichs-Ueberschrift oder das Tabellenende
    erreicht wird.

  Phase 3: ZEILEN ENTFERNEN
    Alle identifizierten Zeilen (Ueberschrift + Inhalt) entfernen.
    Von unten nach oben loeschen, damit Indizes stabil bleiben.

  WICHTIG: vMerge-Zellen (vertikal zusammengefuegt) muessen
  beruecksichtigt werden — sonst bleiben leere Zellen stehen.


VMERGE-BEHANDLUNG
=================

Word-Tabellen koennen vertikal zusammengefuegte Zellen haben (vMerge).
Diese bestehen aus:
  - Einer "restart"-Zelle (Beginn der Zusammenfuehrung)
  - Mehreren "continue"-Zellen (Fortsetzung, visuell unsichtbar)

Beim Loeschen von Zeilen:
  - Wenn eine "continue"-Zelle in einer zu loeschenden Zeile liegt,
    muss geprueft werden ob die "restart"-Zelle oberhalb auch
    geloescht wird
  - Sonst entsteht ein korruptes Dokument

Der Service loest dies, indem er alle vMerge-Attribute aus Zellen
entfernt, bevor er Zeilen loescht.


CHECKBOX-HANDLING (SDT-ELEMENTE)
================================

Word-Checkboxen sind als Structured Document Tags (SDT) im XML
gespeichert. python-docx bietet KEINEN direkten Zugriff darauf.

Der Service manipuliert das XML direkt:

  Namespace: w14 = "http:/schemas.microsoft.com/office/word/2010/wordml"
  Element:   <w14:checkbox>
               <w14:checked w14:val="0"/>  ← 0=unchecked, 1=checked
             </w14:checkbox>

  Zugriff:
  1. Paragraph → XML-Element (paragraph._element)
  2. XPath-Suche nach SDT-Containern
  3. w14:checked Attribut setzen
  4. Visuelles Symbol aktualisieren (☐ → ☒)

  WICHTIG: Das visuelle Symbol (Unicode-Zeichen im Run) muss
  ZUSAETZLICH zum XML-Attribut aktualisiert werden, da manche
  Word-Versionen nur das Symbol anzeigen.


METHODEN-REFERENZ
=================

class WordTemplateService:

  fill_template(template_path, data_dict, output_path)
    Hauptmethode: Fuellt alle Platzhalter und speichert.

  replace_placeholders(doc, data_dict)
    Ersetzt {{PLATZHALTER}} in Paragraphen und Tabellen.

  fill_table(doc, table_name, rows_data)
    Fuellt eine benannte Tabelle mit Zeilendaten.

  filter_icf_sections(doc, active_sections)
    Entfernt inaktive ICF-Bereiche aus der Tabelle.

  set_checkbox(doc, checkbox_name, checked)
    Setzt eine SDT-Checkbox auf checked/unchecked.

  clone_row(table, source_row_idx)
    Klont eine Tabellenzeile fuer dynamische Inhalte.

  remove_row(table, row_idx)
    Entfernt eine Tabellenzeile (vMerge-sicher).


FEHLERBEHEBUNG
==============

  "Platzhalter nicht gefunden"
    → Pruefen ob der Platzhalter in der Vorlage ueber
      mehrere Runs verteilt ist (Word-Formatierung)
    → Vorlage oeffnen, Platzhalter neu eintippen (ohne Formatwechsel)

  "Checkbox aendert sich nicht"
    → SDT-Element im XML pruefen
    → Sowohl w14:checked ALS AUCH das visuelle Symbol aendern

  "Leere Zeilen nach Filterung"
    → vMerge-Zellen nicht korrekt behandelt
    → Alle vMerge-Attribute vor dem Loeschen entfernen

  "Dokument korrupt nach Bearbeitung"
    → Zeilen von unten nach oben loeschen (Index-Stabilitaet)
    → Keine Zeilen loeschen, die vMerge-restart fuer andere sind


EINSCHRAENKUNGEN
================

  - Bilder in Platzhaltern werden nicht unterstuetzt
  - Kopf-/Fusszeilen werden nicht durchsucht
  - Verschachtelte Tabellen: nur erste Ebene
  - Formatierung geht beim Run-Merge teilweise verloren
    (erster Run bestimmt die Formatierung)
  - SDT-Checkboxen: Nur Word 2010+ Format (w14 Namespace)


SIEHE AUCH
==========

  wiki/foerderbericht_system.txt      Systemarchitektur
  wiki/word_automation.txt            Word-Automatisierung allgemein
  skills/_services/document/               Service-Dateien
  skills/_templates/                       Word-Vorlagen
