WIP (unstable): Klassenlehrer-Tab (fremde Klassenbucheinträge + Fehlzeiten der Klasse)

Neuer Tab in der Gruppendetailansicht (LearningGroup.IsClassTeacher-Flag), zeigt
Klassenbucheinträge anderer Lehrkräfte sowie Fehlzeiten der ganzen Klasse über alle
Fächer, pro Schüler*in und Tag zusammengefasst. Beides rein lesend, kein Übernehmen
in lokale Daten. Fehlzeiten-Bericht (AbsencePerStudent) adressiert die Klasse über
"KL"+getKlassen-ID, automatisch aufgelöst - noch nicht mit echtem WebUntis-Zugang
gegengeprüft (siehe TODO.md).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-25 21:19:39 +02:00
co-authored by Claude Sonnet 5
parent f9f5f75aa8
commit 7245196689
17 changed files with 649 additions and 7 deletions
+47 -5
View File
@@ -1277,11 +1277,53 @@ eigenen Unterricht abfragt und deshalb mit den regulären Lehrkraft-Rechten funk
Auch hier keine externe Schülerkennung, nur der Name — Namensabgleich soll deshalb zusätzlich auf
Klasse+Fach aus der Zeile scopen (→ genau eine lokale Lerngruppe), nicht global über alle Schüler.
Abgleichsdialog (Diff gegen `Documentation`, Übernehmen in beide Richtungen) noch nicht gebaut.
- **Idee, noch nicht geplant ("Klassenlehrer"-Feature):** Der "-alle-"-Bericht enthält für die
eigene Klasse auch Einträge, die andere Lehrkräfte in deren Fächern angelegt haben (`Benutzer`
≠ eigener Login) — für den reinen Dokumentations-Abgleich (eigene Einträge synchron halten) werden
die herausgefiltert. Eine Klassenlehrer-Übersicht, die stattdessen genau diese fremden Einträge zur
eigenen Klasse zeigt, wäre ein eigenständiges, größeres Feature und ist bewusst zurückgestellt.
- [x] **"Klassenlehrer"-Feature, Schritt 1 (Klassenbuch fremder Einträge, August 2026):** Der
"-alle-"-Bericht enthält für die eigene Klasse auch Einträge, die andere Lehrkräfte in deren
Fächern angelegt haben (`Benutzer` ≠ eigener Login) — für den reinen Dokumentations-Abgleich
(eigene Einträge synchron halten) werden die herausgefiltert. Neues Flag
`LearningGroup.IsClassTeacher` ("Klassenlehrer/-in dieser Klasse", Stammdaten-Checkbox, keine
Migration nötig) blendet einen neuen Tab "Klassenlehrer" in der Gruppendetailansicht ein —
bewusst ein eigenes Flag statt `IsOwnClass` (das ist rein die Kalenderfarb-Markierung und
mehrfach setzbar für Klasse + zugehörige Kurse, würde den Tab sonst versehentlich auch bei
Kursen zeigen). `WebUntisIntegrationService.GetForeignClassRegisterEventsAsync` ist das
Spiegelbild von `GetOwnClassRegisterEventsAsync`: derselbe "-alle-"-Rohbericht, aber Einträge
anderer Lehrkräfte statt der eigenen, zusätzlich auf die übergebene Klasse eingeschränkt (kein
neuer WebUntis-Bericht nötig). `ClassTeacherTabViewModel`/`ClassTeacherTabView` zeigen die
Liste rein lesend an (Datum, Schüler*in, Fach/Lehrkraft, Kategorie, Text) — kein
"Übernehmen"-Command wie beim Dokumentations-Abgleich, da es fremde Einträge sind, keine
eigenen zum lokalen Synchronisieren.
**Nicht Teil dieses Schritts:** Fehlzeiten der Klasse aus fremdem Unterricht — dafür fehlt noch
ein per Netzwerk-Mitschnitt zu ermittelnder klassenbezogener Fehlzeiten-Bericht ohne `lessonId`
(vermutlich `klasseId`/`teacherId` statt `lsid`); folgt als eigener Schritt, sobald die
Query-Parameter bekannt sind. Ebenfalls zurückgestellt: Dokumentation/Behördenschriftverkehr als
eigenständiger, WebUntis-unabhängiger Baustein.
- [x] **"Klassenlehrer"-Feature, Schritt 2 (Fehlzeiten aus fremdem Unterricht, August 2026):** Der
gesuchte Bericht ist `reports.do?name=AbsencePerStudent&klasseOrStudentgroupId=KL<id>&studentId=-1`
(per Netzwerk-Mitschnitt gefunden) — Query-Parameter sind bis auf `name`/`klasseOrStudentgroupId`/
`studentId` identisch mit `ClassregEventPerStudent`. `klasseOrStudentgroupId` ist `"KL"` +
die `getKlassen`-interne Klassen-ID (dasselbe Element-Kürzel-Schema wie `kl`/`te`/`su`/`ro` bei
anderen Berichten) — **kein manuelles Feld nötig**, `WebUntisIntegrationService.ResolveClassIdAsync`
löst sie pro Aufruf über `getSchoolyears`+`getKlassen` und den Klassennamen auf (analog zum
bestehenden Klassen-Auswahldialog). Das CSV-Format ist **nicht** identisch mit `AbsencePerLesson`
(ursprüngliche Vermutung anhand echter Daten widerlegt) — eigenes Spaltenschema, eine Zeile pro
Fehlstunde, neuer Parser `WebUntisClassAbsenceParser`/Modell `UntisClassAbsenceEntry`. Anders als
`AbsencePerLesson` liefert `Status` hier einen Klartext-Wert direkt (im Sample nur `"nicht
entsch."` beobachtet, andere Werte nicht bestätigt), es braucht also keine Status-Heuristik.
Der Header `Text` kommt zweimal vor (eine immer-leere Spalte, dann die eigentliche Tagesnotiz) —
der bestehende Dictionary-per-Header-Parse-Stil überschreibt das zufällig richtig, im Parser
kommentiert statt stillschweigend vorausgesetzt. `Fehltage` (0/1, `CountsAsFullDay`) ist laut
Nutzer-Angabe der auf eine ganze Zahl abgerundete Fehlzeit-Tagesanteil: bleibt 0, bis auch die
letzte Unterrichtsstunde des Tages als versäumt gilt, erst deren Zeile trägt dann den Wert 1.
Im Klassenlehrer-Tab (Nutzer-Feedback) **pro Schüler*in und Tag gruppiert** dargestellt statt
einer Zeile pro Fehlstunde — `ClassAbsenceDaySummaryRow.GroupByStudentAndDay` fasst Fehlstunden/
-minuten zusammen und sammelt Fächer/Status/Gründe als distinkte Listen. Rein Ansicht, kein
Abgleich/Übernehmen in lokale Anwesenheitsdaten; eigene und fremde Fächer erscheinen bewusst
beide ungefiltert.
**Zurückgestellte Idee:** ein Detail-Drill-down pro Schüler*in (z. B. Heatmap der gefehlten
Einzelstunden, Wochenansicht mit Verspätung/vorzeitigem Verlassen) — noch offen, ob im selben Tab
oder über einen eigenen Tab/Dialog "in die Tiefe" erreichbar; die Rohdaten
(`UntisClassAbsenceEntryDto`) sind dafür schon vollständig vorhanden, nur noch nicht in der UI
genutzt.
### 4.4 Wochen-/Tagesansicht
- [x] **4.4.1** Kalenderansicht über alle Gruppen: Woche und Tag — siehe Nachtrag zu 4.3