Hausaufgaben feature und Stundeplan fix
CI / build-and-test (push) Canceled after 0s

This commit is contained in:
2026-09-08 18:01:42 +02:00
parent 86e114580f
commit e86125e5f9
7 changed files with 388 additions and 2 deletions
+66 -1
View File
@@ -982,7 +982,9 @@ angezeigten Woche geklebt, nicht nur in der einen Woche, zu der es gehört). Fü
berechnen `HolidayBadgeFor`/`IsLastBeforeExamFor` die Badges deshalb jetzt je Zelle am dort
gezeigten Datum statt an "heute" — das Bearbeiten-Raster (zeigt ohnehin nur das wiederkehrende
Muster ohne Datum) behält die alte, "heute"-verankerte Berechnung. Beim erneuten Navigieren in den
Stundenplan (Sidebar-Klick) springt die Ansicht wieder auf die laufende Woche zurück.
Stundenplan (Sidebar-Klick) sprang die Ansicht ursprünglich wieder auf die laufende Woche zurück
siehe "Nachtrag zu 4.3, Bugfix Wochennavigation (September 2026)" am Ende dieses Abschnitts, wo
dieses Verhalten auf Nutzer-Feedback hin wieder entfernt wurde.
**Nachtrag zu 4.3, fünfte Iteration (Aufsichten + Vertretung):** Nutzer-Feedback: zwischen manchen
Stunden ist auch Pausenaufsicht zu erledigen, und gelegentlich kommen Sonderfälle vor — eine
@@ -1930,6 +1932,69 @@ eigenen Unterricht abfragt und deshalb mit den regulären Lehrkraft-Rechten funk
Vorgänge je Klassen-Roster-Namen über denselben Namensabgleich wie die übrigen `Build*`-Methoden
dieser Klasse auf (`IVorgangRepository.GetByStudent`).
**Nachtrag zu 4.3, Bugfix Wochennavigation (September 2026):** Nutzer-Feedback: beim Planen der
nächsten Woche musste nach jedem kurzen Abstecher in einen anderen Bereich der Sidebar wieder
manuell zur zuvor betrachteten Woche zurückgeblättert werden ("man muss nicht nur einmal
hinspringen, sondern jedes Mal wieder neu"). Ursache war das in der vierten Iteration dokumentierte
Verhalten, dass `MainWindowViewModel.GetTimetable()` bei jedem erneuten Aufruf der Seitenleisten-
Navigation `TimetableViewModel.WeekOffset` explizit auf 0 zurücksetzte — obwohl `TimetableViewModel`
als DI-Singleton ohnehin über die gesamte Sitzung hinweg bestehen bleibt und `WeekOffset` daher ohne
diese Zeile ganz von selbst erhalten bliebe. Der Reset wurde entfernt; ein separater Zustands-
Singleton/eine statische Variable dafür war nicht nötig. Das erklärt vermutlich auch den zweiten
gemeldeten Effekt ("der Zurück-Button springt manchmal zwei Wochen zurück"): wer z.B. in Woche +1
plante, kurz wegnavigierte und danach einmal "" klickte, landete wegen des Resets in Woche -1 statt
der erwarteten Woche 0 — gefühlt ein Sprung um zwei Wochen, obwohl `PreviousWeekCommand`/
`NextWeekCommand` selbst korrekt je Klick nur um eine Woche verschieben (siehe
`NextWeek_BadgeGehoertZurAngezeigtenWoche_NichtZuHeute`, das zwei aufeinanderfolgende Klicks bewusst
als zwei Wochen erwartet). Der "Diese Woche"-Button existierte bereits seit der vierten Iteration
(`CurrentWeekCommand`, nur sichtbar wenn `!IsCurrentWeek`).
**Nachtrag zu 4.3, Abgleich fehlender Hausaufgaben (September 2026):** Nutzer-Feedback: negative
Klassenbucheinträge zur Kategorie "fehlende HA" sind ein brauchbares Signal, ob ein/e Schüler*in die
Hausaufgabe nicht gemacht hat, und sollen als Vorschlag mit der eigenen Erfassung
(`ParticipationEntry.Homework`) abgeglichen werden können — ausdrücklich nicht die erteilte
Hausaufgabe selbst (`Lesson.Homework`), das bleibt ein offener, separater Punkt.
- Neuer Dashboard-weiter Dialog `WebUntisHomeworkComparisonViewModel`/`WebUntisHomeworkComparisonDialog`
([LehrerApp.Desktop/ViewModels/Groups/WebUntisHomeworkComparisonViewModel.cs](LehrerApp.Desktop/ViewModels/Groups/WebUntisHomeworkComparisonViewModel.cs)),
Button "Fehlende Hausaufgaben abgleichen…" neben dem bereits vorhandenen "Klassenbuch
abgleichen…" auf dem Dashboard. Baut auf demselben Muster wie
`WebUntisDocumentationComparisonViewModel` (Dashboard-weit, da der WebUntis-"-alle-"-Bericht
klassenübergreifend ist) und `WebUntisLessonAbsenceComparisonViewModel` (schreibt wie dort über
`IParticipationRepository.GetBySessionAndStudent`/`Save`).
- **Filter:** `CategoryGroup == "Negativ"` und `CategoryName`/`Text` enthält "Hausauf" — dieselbe
Substring-Heuristik wie `ClassTeacherDetailsViewModel.ContainsHomework`, nur zusätzlich auf
negative Einträge eingeschränkt.
- **Fach-Erkennung:** Der Klassenbuch-Bericht liefert kein zuverlässiges Fach-Feld, aber laut Nutzer
enthält der mitgeschickte Text praktisch immer das Untis-Fachkürzel. Deshalb wird `Text` (Fallback
`CategoryName`) gegen `Subject.ShortName` alle Lerngruppen-Fächer abgeglichen (Wortgrenzen-Split,
nicht `Contains`, um kurze Kürzel nicht versehentlich in anderen Wörtern zu treffen); mehrdeutige
Kürzel (zwei Fächer mit demselben `ShortName`) werden bewusst nicht zugeordnet statt zu raten.
- **Lerngruppe/Stunde auflösen:** aus dem per Namensabgleich gefundenen `Student` werden über
`IGroupMembershipRepository.GetByStudent` alle am Eintragsdatum aktiven Mitgliedschaften
(`GroupMembershipService.IsActiveOn`) genommen und auf das erkannte Fach + Schuljahr des
Eintragsdatums eingeschränkt; bleibt mehr als eine Lerngruppe übrig, bleibt die Zeile unaufgelöst
statt irgendeine zu wählen (gleiches Vorsichtsprinzip wie beim Namensabgleich). Die
`ParticipationSession` der Lerngruppe am Eintragsdatum liefert dann die Stunde für
`IParticipationRepository`.
- **Kein Überschreiben (Kernanforderung):** eine Zeile wird nur vorausgewählt, wenn
`HomeworkDisplay.Effective(entry)` noch `null` ist, also lokal überhaupt noch nichts erfasst wurde
— jeder bereits vorhandene Status (auch ein bereits gesetztes "fehlt", nicht nur "Teilweise"/
"nachgereicht") bleibt unangetastet und wird nur zum Vergleich daneben angezeigt; die Checkbox
bleibt trotzdem bedienbar, falls doch bewusst überschrieben werden soll. Übernommen wird immer nur
`HomeworkStatus.MissingOpen` ("Nachreichen offen") — nie automatisch `MissingOverdue`, die weitere
Nachverfolgung bleibt laut Nutzer App-intern.
- **Bewusst kein Caching:** `GetOwnClassRegisterEventsAsync` wird wie beim bereits bestehenden
`WebUntisDocumentationComparisonViewModel` direkt (ungecacht) aufgerufen statt über
`UntisReportCacheService`, dessen Cache-Tabellen aktuell klassen-/`GetForeignClassRegisterEventsAsync`-
spezifisch aufgebaut sind (ein Schema-Umbau für die eigenen, klassenübergreifenden Einträge wäre ein
eigenständiger, deutlich größerer Umbau gewesen, siehe Nutzer-Rückfrage). Beide "eigene Einträge"-
Dialoge lösen pro Öffnen einen eigenen Live-Abruf aus; falls das in der Praxis stört, wäre eine
gemeinsame Cache-Erweiterung ein sinnvoller separater Nachtrag.
- Aus Konsistenz mit den beiden bestehenden, strukturell identischen Abgleichs-ViewModels bewusst
ungetestet gelassen: `WebUntisIntegrationService` ist `sealed` und nicht auf ein Interface
gemockt, `WebUntisLessonAbsenceComparisonViewModel`/`WebUntisDocumentationComparisonViewModel`
haben aus demselben Grund ebenfalls keine Tests.
### 4.4 Wochen-/Tagesansicht
- [x] **4.4.1** Kalenderansicht über alle Gruppen: Woche und Tag — siehe Nachtrag zu 4.3
("Heute"-Tab: Tagesliste unten angedockt, gruppenübergreifendes Wochenraster darüber, inkl.