Klassenbucheinträge abgleich und poll
This commit is contained in:
@@ -43,11 +43,16 @@ public partial class WebUntisLessonAbsenceComparisonViewModel : ObservableObject
|
||||
private readonly IParticipationSessionRepository _sessions;
|
||||
private readonly IParticipationRepository _participation;
|
||||
|
||||
private IReadOnlyList<Student> _loadedStudents = [];
|
||||
private IReadOnlyDictionary<DateOnly, ParticipationSession> _loadedSessions =
|
||||
new Dictionary<DateOnly, ParticipationSession>();
|
||||
|
||||
public ObservableCollection<WebUntisLessonAbsenceRow> Rows { get; } = [];
|
||||
[ObservableProperty] private DateTimeOffset _startDate = DateTimeOffset.Now.AddMonths(-2);
|
||||
[ObservableProperty] private DateTimeOffset _endDate = DateTimeOffset.Now;
|
||||
[ObservableProperty] private string _status = "Zeitraum wählen und Fehlzeiten laden.";
|
||||
[ObservableProperty] private bool _busy;
|
||||
[ObservableProperty] private bool _markUnknownAsPresent;
|
||||
|
||||
public WebUntisLessonAbsenceComparisonViewModel(LearningGroup group, WebUntisIntegrationService untis,
|
||||
IStudentRepository students, IParticipationSessionRepository sessions,
|
||||
@@ -78,6 +83,8 @@ public partial class WebUntisLessonAbsenceComparisonViewModel : ObservableObject
|
||||
var localSessions = _sessions.GetByGroup(_group.Id)
|
||||
.Where(x => x.Date >= start && x.Date <= end).GroupBy(x => x.Date)
|
||||
.ToDictionary(x => x.Key, x => x.First());
|
||||
_loadedStudents = courseStudents;
|
||||
_loadedSessions = localSessions;
|
||||
// Erste Wahl: WebUntis-Kennung (ENr). Nicht jeder Schüler hat eine (z.B. manuell statt
|
||||
// per WebUntis-Import angelegt) - Fallback über den Namen, aber nur wenn er innerhalb
|
||||
// der Kursmitglieder eindeutig ist, sonst lieber unzugeordnet lassen als raten.
|
||||
@@ -152,10 +159,39 @@ public partial class WebUntisLessonAbsenceComparisonViewModel : ObservableObject
|
||||
entry.UpdatedAt = DateTime.UtcNow;
|
||||
_participation.Save(entry);
|
||||
}
|
||||
Status = $"{selected.Count} Anwesenheitsstatus übernommen.";
|
||||
|
||||
var presentCount = MarkUnknownAsPresent ? FillUnknownAsPresent() : 0;
|
||||
Status = $"{selected.Count} Anwesenheitsstatus übernommen." +
|
||||
(MarkUnknownAsPresent ? $" {presentCount} unbekannte Status auf anwesend gesetzt." : "");
|
||||
foreach (var row in selected) row.Selected = false;
|
||||
}
|
||||
|
||||
// "Identifiziert" heißt hier: WebUntis hat für diesen Schüler an diesem Tag überhaupt eine Zeile
|
||||
// gemeldet - unabhängig davon, ob die Zeile markiert/übernommen wurde. Nur wer für den geladenen
|
||||
// Zeitraum weder von WebUntis gemeldet noch lokal schon kontrolliert wurde, gilt als "unbekannt"
|
||||
// und wird auf anwesend gesetzt; bereits erfasste Einträge (auch ohne Anwesenheitsstatus, z.B. nur
|
||||
// mit Notiz) werden nicht überschrieben, wenn ihr Anwesenheitsstatus schon gesetzt ist.
|
||||
private int FillUnknownAsPresent()
|
||||
{
|
||||
var identified = Rows.Where(x => x.AssignedStudent is not null)
|
||||
.Select(x => (x.Date, StudentId: x.AssignedStudent!.Id))
|
||||
.ToHashSet();
|
||||
var filled = 0;
|
||||
foreach (var session in _loadedSessions.Values)
|
||||
foreach (var student in _loadedStudents)
|
||||
{
|
||||
if (identified.Contains((session.Date, student.Id))) continue;
|
||||
var entry = _participation.GetBySessionAndStudent(session.Id, student.Id);
|
||||
if (entry?.Attendance is not null) continue;
|
||||
entry ??= new ParticipationEntry { SessionId = session.Id, StudentId = student.Id };
|
||||
entry.Attendance = AttendanceStatus.Present;
|
||||
entry.UpdatedAt = DateTime.UtcNow;
|
||||
_participation.Save(entry);
|
||||
filled++;
|
||||
}
|
||||
return filled;
|
||||
}
|
||||
|
||||
private static int? StudentKey(Student student)
|
||||
{
|
||||
student.ExternalIds ??= [];
|
||||
|
||||
Reference in New Issue
Block a user