CI / build-and-test (push) Canceled after 0s
Nachschreibarbeiten nutzen die Wiederholungs-Verknüpfung, ersetzen aber nur fehlende Noten; mehrere Folgearbeiten je erster Arbeit sind möglich. Exam.Kind trennt Klausuren (schriftlich) von Tests u. Ä. (Sonstige). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
93 lines
4.1 KiB
C#
93 lines
4.1 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; }
|
|
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 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",
|
|
};
|
|
}
|