Files
LehrerApp/LehrerApp.Desktop/ViewModels/Groups/TeachingModeOutstandingHomeworkViewModel.cs
T
2026-09-25 22:02:00 +02:00

78 lines
3.3 KiB
C#

using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using LehrerApp.Core.Interfaces;
using LehrerApp.Core.Models;
using LehrerApp.Core.Services;
namespace LehrerApp.Desktop.ViewModels.Groups;
public sealed record OutstandingHomeworkRow(string StudentName, DateOnly Date, HomeworkStatus Status)
{
public string DateLabel => Date.ToString("dd.MM.yyyy");
public string StatusLabel => HomeworkDisplay.Label(Status);
}
/// <summary>Jüngste noch fehlende Hausaufgaben der aktuellen Lerngruppe. Liest bei jedem Öffnen
/// und auf Wunsch erneut, damit die Anwesenheit der laufenden Stunde berücksichtigt wird.</summary>
public partial class TeachingModeOutstandingHomeworkViewModel(
Guid groupId, DateOnly lessonDate,
IStudentRepository students, IGroupMembershipRepository memberships,
IParticipationSessionRepository sessions, IParticipationRepository participation) : ObservableObject
{
private const int LookbackDays = 120;
private const int MaxRows = 20;
private Guid? _currentSessionId;
public ObservableCollection<OutstandingHomeworkRow> Rows { get; } = [];
public string Header => $"Offene Nachreichungen ({Rows.Count})";
public bool HasRows => Rows.Count > 0;
[ObservableProperty] private bool _isExpanded;
[ObservableProperty] private bool _includeAbsentStudents;
partial void OnIsExpandedChanged(bool value)
{
if (value) Refresh();
}
partial void OnIncludeAbsentStudentsChanged(bool value) => Refresh();
public void SetCurrentSessionId(Guid? sessionId) => _currentSessionId = sessionId;
[RelayCommand]
public void Refresh()
{
Rows.Clear();
var groupMemberships = memberships.GetByGroup(groupId);
var roster = students.GetByGroup(groupId)
.Where(s => groupMemberships.FirstOrDefault(m => m.StudentId == s.Id) is not { } membership ||
GroupMembershipService.IsActiveOn(membership, lessonDate))
.ToDictionary(s => s.Id);
var absentIds = _currentSessionId is { } sessionId
? participation.GetBySession(sessionId)
.Where(e => e.Attendance is not null and not AttendanceStatus.Present
and not AttendanceStatus.Late and not AttendanceStatus.SignificantlyLate)
.Select(e => e.StudentId).ToHashSet()
: [];
var rows = sessions.GetByGroup(groupId)
.Where(s => s.Date < lessonDate && s.Date >= lessonDate.AddDays(-LookbackDays))
.SelectMany(session => participation.GetBySession(session.Id)
.Select(entry => (session.Date, Entry: entry)))
.Where(x => roster.ContainsKey(x.Entry.StudentId) &&
(IncludeAbsentStudents || !absentIds.Contains(x.Entry.StudentId)))
.Select(x => (x.Date, x.Entry.StudentId, Status: HomeworkDisplay.Effective(x.Entry)))
.Where(x => x.Status is { } status && HomeworkDisplay.CountsAsMissing(status))
.OrderByDescending(x => x.Date)
.ThenBy(x => roster[x.StudentId].FullName)
.Take(MaxRows);
foreach (var row in rows)
Rows.Add(new OutstandingHomeworkRow(roster[row.StudentId].FullName, row.Date, row.Status!.Value));
OnPropertyChanged(nameof(Header));
OnPropertyChanged(nameof(HasRows));
}
}