Neue Funktion Schüler austragen statt aus Kurs löschen.
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user