using LehrerApp.Core.Models; namespace LehrerApp.Core.Services; public record AttendanceBalance( int TotalChecked, int Present, int Excused, int Unexcused, int SchoolEvent, int ExcusePending, double AbsenceRatePercent) { public bool ExceedsThreshold => AbsenceRatePercent > AttendanceBalanceService.WarningThresholdPercent; } /// /// Fehlzeitenbilanz (5.2.2/5.2.3) — reine Auswertung der bereits im Mitarbeit-Feature /// erfassten -Werte, keine zweite Erfassung. /// public class AttendanceBalanceService { public const double WarningThresholdPercent = 20.0; public AttendanceBalance Calculate(IEnumerable<(DateOnly Date, AttendanceStatus? Status)> entries, DateOnly from, DateOnly to) { var relevant = entries .Where(e => e.Status.HasValue && e.Date >= from && e.Date <= to) .Select(e => e.Status!.Value) .ToList(); var present = relevant.Count(s => s == AttendanceStatus.Present); var excused = relevant.Count(s => s == AttendanceStatus.Excused); var unexcused = relevant.Count(s => s is AttendanceStatus.Unexcused or AttendanceStatus.Truant); var schoolEvent = relevant.Count(s => s == AttendanceStatus.OtherSchoolEvent); var pending = relevant.Count(s => s == AttendanceStatus.ExcusePending); var total = relevant.Count; // Schulisch veranlasste Abwesenheit (Exkursion o.ä.) zählt nicht als Fehlzeit des Schülers. var absenceCount = excused + unexcused + pending; var rate = total == 0 ? 0.0 : Math.Round(100.0 * absenceCount / total, 1); return new AttendanceBalance(total, present, excused, unexcused, schoolEvent, pending, rate); } }