Klausur: Fach aus Lerngruppe übernehmen, Rückgabedatum erfassen

- Fach kommt jetzt aus der Lerngruppe statt manuell pro Klausur
  eingegeben zu werden: Fach-Feld im Anlegen-Dialog der Lerngruppe
  ist nicht mehr auf Typ "Kurs" beschränkt, da eine Gruppe genau ein
  Fach unterrichtet (bei zwei Fächern legt man zwei Gruppen an). Im
  Klausur-Dialog ist das Fach dadurch nur noch read-only Kontext statt
  eines redundanten Eingabefelds.
- Neues Feld Exam.ReturnedAt: wird beim Statuswechsel auf "Zurück-
  gegeben" automatisch mit dem heutigen Datum belegt (und beim
  Zurücknehmen des Status wieder geleert), ist im Klausur-Dialog aber
  auch manuell nachträglich korrigierbar. Sichtbar als eigene Spalte
  im Klausuren-Tab.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-11 23:16:52 +02:00
co-authored by Claude Sonnet 5
parent 21378bbebd
commit 8cbd4475d7
6 changed files with 40 additions and 12 deletions
@@ -19,12 +19,13 @@ public partial class ExamDialogViewModel : ObservableObject
private readonly int _gradeLevel;
private readonly Exam? _editingExam;
private readonly List<GradingKeyEntry> _gradingKey;
private readonly string _subjectName;
[ObservableProperty] private string _title = "";
[ObservableProperty] private string _dateText = DateOnly.FromDateTime(DateTime.Today).ToString("dd.MM.yyyy");
[ObservableProperty] private string _subject = "";
[ObservableProperty] private int? _examNumber;
[ObservableProperty] private string _notes = "";
[ObservableProperty] private string _returnedAtText = "";
[ObservableProperty] private string _validationMessage = "";
[ObservableProperty] private double _totalPoints;
[ObservableProperty] private bool _hasCompetencyCatalog;
@@ -40,6 +41,10 @@ public partial class ExamDialogViewModel : ObservableObject
public string DialogTitle => _editingExam is null ? "Neue Klausur anlegen" : "Klausur bearbeiten";
public string SaveButtonText => _editingExam is null ? "Anlegen" : "Speichern";
/// Fach kommt von der Lerngruppe, nicht editierbar (jede Gruppe unterrichtet ein Fach).
public string SubjectDisplay => string.IsNullOrWhiteSpace(_subjectName)
? "Kein Fach hinterlegt (siehe Lerngruppe)" : $"Fach: {_subjectName}";
public ExamDialogViewModel(IExamRepository exams, ICompetencyDomainRepository competencyDomains,
Guid groupId, Guid? subjectId, int gradeLevel, GradingSystem gradingSystem,
string defaultSubjectName, Exam? editingExam, Exam? duplicateSource)
@@ -47,6 +52,7 @@ public partial class ExamDialogViewModel : ObservableObject
_exams = exams; _competencyDomains = competencyDomains;
_groupId = groupId; _subjectId = subjectId; _gradeLevel = gradeLevel;
_editingExam = editingExam;
_subjectName = defaultSubjectName;
HasCompetencyCatalog = subjectId.HasValue
&& _competencyDomains.GetBySubjectAndGrade(subjectId.Value, gradeLevel).Count > 0;
@@ -59,9 +65,9 @@ public partial class ExamDialogViewModel : ObservableObject
DateText = isDuplicate
? DateOnly.FromDateTime(DateTime.Today).ToString("dd.MM.yyyy")
: source.Date.ToString("dd.MM.yyyy");
Subject = source.Subject;
ExamNumber = source.ExamNumber;
Notes = source.Notes ?? "";
ReturnedAtText = isDuplicate ? "" : source.ReturnedAt?.ToString("dd.MM.yyyy") ?? "";
_gradingKey = source.GradingKey
.Select(k => new GradingKeyEntry { Grade = k.Grade, MinPercent = k.MinPercent }).ToList();
foreach (var t in source.Tasks.OrderBy(t => t.Nr))
@@ -70,7 +76,6 @@ public partial class ExamDialogViewModel : ObservableObject
}
else
{
Subject = defaultSubjectName;
_gradingKey = gradingSystem == GradingSystem.Grades1To6
? GradingService.DefaultKey1To6() : GradingService.DefaultKey0To15();
}
@@ -164,13 +169,24 @@ public partial class ExamDialogViewModel : ObservableObject
ValidationMessage = "Datum im Format TT.MM.JJJJ eingeben.";
return;
}
DateOnly? returnedAt = null;
if (!string.IsNullOrWhiteSpace(ReturnedAtText))
{
if (!DateOnly.TryParseExact(ReturnedAtText, "dd.MM.yyyy", null, DateTimeStyles.None, out var r))
{
ValidationMessage = "Rückgabedatum im Format TT.MM.JJJJ eingeben.";
return;
}
returnedAt = r;
}
Result = _editingExam ?? new Exam { GroupId = _groupId };
Result.Title = Title.Trim();
Result.Date = date;
Result.Subject = Subject.Trim();
Result.Subject = _subjectName.Trim();
Result.ExamNumber = ExamNumber;
Result.Notes = string.IsNullOrWhiteSpace(Notes) ? null : Notes.Trim();
Result.ReturnedAt = returnedAt;
Result.Tasks = Tasks.Select(t => t.ToModel()).ToList();
Result.GradingKey = _gradingKey;
_exams.Save(Result);