feat: Abwesenheits-Hinweise, Fehlquote bei Zeugnisnoten, Gruppen-Dokumentation

- Schnellbewerten-Dialog: abwesende Schüler werden gedimmt und mit ihrem
  Anwesenheitsstatus statt der Aspektbeschriftung angezeigt, damit keine
  Mitarbeitsnote für nicht anwesende Schüler vergeben wird.
- Zeugnisnoten-Dialog: zeigt je Schüler die Fehlquote im gewählten
  Zeitraum, ab 50 % hervorgehoben (informativ, keine automatische
  Notenänderung).
- Gruppen-Tab "Dokumentation" (bisher Platzhalter) implementiert: listet
  alle Dokumentationseinträge der Gruppen-Schüler, mit Schüler-Filter und
  optionalem "Nur dieser Unterricht"-Schalter. Einträge aus anderen
  Lerngruppen werden standardmäßig mitangezeigt, aber gedimmt. Der
  Dokumentationsdialog bekommt dafür einen optionalen Schüler-Picker.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-18 19:45:01 +02:00
co-authored by Claude Sonnet 5
parent f2cb3c98c6
commit a0f44f1b25
19 changed files with 725 additions and 26 deletions
@@ -187,6 +187,60 @@ public sealed class DocumentationDialogViewModelTests
Assert.NotEqual("", vm.AttachmentError);
}
[Fact]
public void OhneStudentOptions_CanPickStudentIstFalse()
{
var vm = new DocumentationDialogViewModel(Guid.NewGuid(), null, new FakeAttachmentStorage());
Assert.False(vm.CanPickStudent);
}
[Fact]
public void MitStudentOptions_OhneAuswahl_SaveSetztFehlerUndSpeichertNicht()
{
var anna = new StudentOption(Guid.NewGuid(), "Anna Beispiel");
var vm = new DocumentationDialogViewModel(Guid.Empty, null, new FakeAttachmentStorage(), [anna])
{
Title = "Vorfall", TypeName = "Vorkommnis",
};
vm.SaveCommand.Execute(null);
Assert.Null(vm.Result);
Assert.NotEqual("", vm.StudentError);
}
[Fact]
public void MitStudentOptions_AuswahlGetroffen_SaveUebernimmtSchuelerUndGruppe()
{
var groupId = Guid.NewGuid();
var anna = new StudentOption(Guid.NewGuid(), "Anna Beispiel");
var ben = new StudentOption(Guid.NewGuid(), "Ben Muster");
var vm = new DocumentationDialogViewModel(Guid.Empty, null, new FakeAttachmentStorage(),
[anna, ben], groupId)
{
Title = "Vorfall", TypeName = "Vorkommnis", SelectedStudent = ben,
};
vm.SaveCommand.Execute(null);
Assert.NotNull(vm.Result);
Assert.Equal(ben.Id, vm.Result!.StudentId);
Assert.Equal(groupId, vm.Result.GroupId);
}
[Fact]
public void MitStudentOptions_Bearbeiten_SchuelerIstVorausgewaehlt()
{
var anna = new StudentOption(Guid.NewGuid(), "Anna Beispiel");
var ben = new StudentOption(Guid.NewGuid(), "Ben Muster");
var existing = new Documentation { StudentId = ben.Id, Title = "Alt" };
var vm = new DocumentationDialogViewModel(ben.Id, existing, new FakeAttachmentStorage(), [anna, ben]);
Assert.Equal(ben, vm.SelectedStudent);
}
[Fact]
public void DiscardUnsavedAttachments_EntferntNurNieGespeicherteAnhaenge()
{