using LehrerApp.Core.Importing; using LehrerApp.Core.Models; namespace LehrerApp.Desktop.Services; /// /// Aus WebUntisLessonAbsenceComparisonViewModel herausgelöst (Nachtrag: die MCP-Tools in /// UntisComparisonTools brauchen exakt dieselbe Regel für dieselbe Fehlzeile, siehe TODO.md) - /// framework-frei (kein ObservableObject/Avalonia-Bezug), damit beide Aufrufer ohne Duplikat /// garantiert denselben Statusvorschlag berechnen. Eine Abweichung zwischen Dialog und MCP-Tool für /// dieselbe WebUntis-Zeile wäre verwirrender als die eine zusätzliche Indirektion hier. /// public static class UntisLessonAbsenceHelper { private const int FullLessonMinutes = 45; // Der Bericht liefert keinen Entschuldigungstext, nur Minutenwerte, ein Bearbeitet-Datum und die // (laut Schule) über Klammerung der ENr codierte Entscheidung des Klassenlehrers - ENr in // Klammern bedeutet unentschuldigt, ohne Klammern abgeschlossen/entschuldigt. Reihenfolge ist // wichtig: "nach Hause entlassen" zählt immer als vorzeitige Entlassung, unabhängig von der // Dauer; darunter zählt jede Fehlzeit unter einer vollen Stunde (45 Min.) immer als Verspätung // oder sonstiger Teilverlust, nie als komplette Abwesenheit - der Text "Verspätung" allein ist // laut Schule nicht zuverlässig genug, deshalb primär über die Minutenschwelle erkannt. public static AttendanceStatus MapStatus(UntisLessonAbsenceDto absence) { if (IsEarlyRelease(absence)) return AttendanceStatus.LeftDuringClass; if (absence.AbsentMinutes < FullLessonMinutes) return AttendanceStatus.Late; if (string.IsNullOrWhiteSpace(absence.HandledOn)) return AttendanceStatus.ExcusePending; if (absence.ExternKey is null) return AttendanceStatus.ExcusePending; return absence.ExternKeyInParentheses ? AttendanceStatus.Unexcused : AttendanceStatus.Excused; } private static bool IsEarlyRelease(UntisLessonAbsenceDto absence) => absence.Reason?.Contains("entlassen", StringComparison.OrdinalIgnoreCase) == true; /// Erste Wahl zum Zuordnen einer WebUntis-Fehlzeile: die externe Schülernummer (ENr), sofern der /// Schüler eine hat (z.B. nicht bei manuell statt per WebUntis-Import angelegten Schülern). public static int? StudentExternKey(Student student) { student.ExternalIds ??= []; return student.ExternalIds.TryGetValue(StudentImportFormats.MasterDataCsv.Value, out var value) && int.TryParse(value, out var key) ? key : null; } }