Files
LehrerApp/LehrerApp.Core/Services/GroupMembershipService.cs

65 lines
2.5 KiB
C#

using LehrerApp.Core.Models;
namespace LehrerApp.Core.Services;
public enum SchoolYearPeriodKind { FullYear, H1, H2 }
/// <summary>
/// Gemeinsame Regeln für zeitlich begrenzte Gruppenzugehörigkeiten.
/// Eintritt und Austritt gelten unabhängig vom gewählten Halbjahresmodus.
/// </summary>
public static class GroupMembershipService
{
public static bool IsActiveOn(GroupMembership membership, DateOnly date)
{
if (membership.JoinedAt is { } joinedAt && date < joinedAt) return false;
if (membership.LeftAt is { } leftAt && date > leftAt) return false;
return membership.Period switch
{
MembershipPeriod.H1Only => IsFirstSemester(date),
MembershipPeriod.H2Only => !IsFirstSemester(date),
_ => true,
};
}
public static bool Overlaps(GroupMembership membership, DateOnly from, DateOnly to)
{
if (to < from) return false;
var effectiveFrom = membership.JoinedAt is { } joinedAt && joinedAt > from ? joinedAt : from;
var effectiveTo = membership.LeftAt is { } leftAt && leftAt < to ? leftAt : to;
if (effectiveTo < effectiveFrom) return false;
if (membership.Period is MembershipPeriod.FullYear or MembershipPeriod.Custom) return true;
for (var month = new DateOnly(effectiveFrom.Year, effectiveFrom.Month, 1);
month <= effectiveTo;
month = month.AddMonths(1))
{
if (membership.Period == MembershipPeriod.H1Only && IsFirstSemester(month)) return true;
if (membership.Period == MembershipPeriod.H2Only && !IsFirstSemester(month)) return true;
}
return false;
}
public static (DateOnly From, DateOnly To) SchoolYearPeriod(
string schoolYear, SchoolYearPeriodKind period)
{
var slash = schoolYear.IndexOf('/');
var startText = slash >= 0 ? schoolYear[..slash] : schoolYear;
if (!int.TryParse(startText, out var startYear))
throw new ArgumentException("Ungültiges Schuljahr.", nameof(schoolYear));
return period switch
{
SchoolYearPeriodKind.H1 => (new DateOnly(startYear, 8, 1), new DateOnly(startYear + 1, 1, 31)),
SchoolYearPeriodKind.H2 => (new DateOnly(startYear + 1, 2, 1), new DateOnly(startYear + 1, 7, 31)),
_ => (new DateOnly(startYear, 8, 1), new DateOnly(startYear + 1, 7, 31)),
};
}
private static bool IsFirstSemester(DateOnly date) => date.Month >= 8 || date.Month <= 1;
}