Files
LehrerApp/LehrerApp.Core/Models/Exam.cs
T
adminandClaude Sonnet 5.5 651c9cddf8 Förderarbeit als dritte Folgearbeits-Art ergänzen
Neben Wiederholung und Nachschreibarbeit gibt es im Arbeitsdialog die Art
Förderarbeit (Exam.IsSupportWork). Sie darf am Tag der ersten Arbeit liegen,
übernimmt dessen Datum als Vorschlag und ersetzt wie eine Nachschreibarbeit
nur fehlende Noten.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-22 20:55:27 +02:00

104 lines
4.8 KiB
C#

namespace LehrerApp.Core.Models;
public class Exam
{
public Guid Id { get; set; } = Guid.NewGuid();
public Guid GroupId { get; set; }
public string Title { get; set; } = "";
public DateOnly Date { get; set; }
public int? ExamNumber { get; set; }
public List<ExamTask> Tasks { get; set; } = [];
public List<GradingKeyEntry> GradingKey { get; set; } = [];
public ExamStatus Status { get; set; } = ExamStatus.Planned;
public DateOnly? ReturnedAt { get; set; }
public Niveau? Niveau { get; set; }
public string? Notes { get; set; }
public DateOnly? ApprovalGrantedAt { get; set; }
public DateOnly? AnnouncedAt { get; set; }
/// <summary>Stabile Kennung einer automatisch importierten Arbeit. Bleibt bei manuell
/// angelegten Klausuren null; aktuell wird der Präfix "webuntis-rest-exam:" verwendet.</summary>
public string? ExternalId { get; set; }
/// Verknüpft Parallelklausuren (gleiche Arbeit, mehrere Kurse) für den Kurs-Umschalter
/// auf der Klausuren-Hauptseite — Id der "Ursprungs"-Klausur, gesetzt beim Duplizieren
/// (siehe ExamDialogViewModel.Save).
public Guid? SharedExamGroupId { get; set; }
/// <summary>Optional verknüpfte ursprüngliche Arbeit derselben Lerngruppe.</summary>
public Guid? RepeatOfExamId { get; set; }
public RepeatGradeRule RepeatGradeRule { get; set; } = RepeatGradeRule.Better;
/// <summary>Art der Leistungsüberprüfung. Nur <see cref="ExamKind.Klausur"/> zählt in die
/// schriftliche Note; alle anderen Arten fließen unter "Sonstige" ein.</summary>
public ExamKind Kind { get; set; } = ExamKind.Klausur;
/// <summary>Nachschreibarbeit: inhaltlich eigene Arbeit für Schüler, die die verknüpfte
/// erste Arbeit (<see cref="RepeatOfExamId"/>) versäumt haben. Anders als eine Wiederholung
/// wird sie nur von diesen Schülern geschrieben und ersetzt deren fehlende Note.</summary>
public bool IsMakeUp { get; set; }
/// <summary>Förderarbeit: inhaltlich eigene Arbeit, die einzelne Schüler statt der verknüpften
/// ersten Arbeit schreiben — typischerweise am selben Tag, daher darf sie am Datum der ersten
/// Arbeit liegen. Zählt wie eine Nachschreibarbeit (ersetzt nur eine fehlende Note).</summary>
public bool IsSupportWork { get; set; }
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}
public class ExamTask
{
public int Nr { get; set; }
public string? Title { get; set; }
public double MaxPoints { get; set; }
public double Weight { get; set; } = 1.0;
/// <summary>Null gilt für beide Fassungen; A/B nur für die gewählte Fassung.</summary>
public ExamVariant? Variant { get; set; }
public bool IsBonus { get; set; }
public List<CompetencyReference> Competencies { get; set; } = [];
}
public class GradingKeyEntry
{
public string Grade { get; set; } = "";
public double MinPercent { get; set; }
}
public class GradingKeyTemplate
{
public Guid Id { get; set; } = Guid.NewGuid();
public string Name { get; set; } = "";
public GradingSystem GradingSystem { get; set; }
public List<GradingKeyEntry> Entries { get; set; } = [];
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}
public class ExamResult
{
public Guid Id { get; set; } = Guid.NewGuid();
public Guid ExamId { get; set; }
public Guid StudentId { get; set; }
public List<double> Points { get; set; } = [];
public double TotalPoints { get; set; }
public string? Grade { get; set; }
public bool Absent { get; set; }
public ExamVariant Variant { get; set; } = ExamVariant.A;
public string? Comment { get; set; }
public DateTime UpdatedAt { get; set; } = DateTime.UtcNow;
}
public enum ExamStatus { Planned, Conducted, Graded, Returned }
public enum ExamVariant { A, B }
public enum RepeatGradeRule { Better, Repeat, Original }
/// <summary>Reihenfolge ist persistiert (LiteDB speichert den Enum-Wert) — nur hinten anhängen.</summary>
public enum ExamKind { Klausur, Test, KontrollierteHausaufgabe, Sonstiges }
public static class ExamFollowUpExtensions
{
/// <summary>Nachschreib- und Förderarbeiten sind inhaltlich eigene Arbeiten nur für einzelne
/// Schüler: ihre Note ersetzt eine fehlende Note der ersten Arbeit, verdrängt sie aber nie.</summary>
public static bool ReplacesMissingGrade(this Exam exam) => exam.IsMakeUp || exam.IsSupportWork;
}
public static class ExamKindExtensions
{
public static bool CountsAsWritten(this ExamKind kind) => kind == ExamKind.Klausur;
public static string Label(this ExamKind kind) => kind switch
{
ExamKind.Test => "Test",
ExamKind.KontrollierteHausaufgabe => "Kontrollierte Hausaufgabe",
ExamKind.Sonstiges => "Sonstige Arbeit",
_ => "Klausur",
};
}