Add class-teacher slots on SchoolClass with owner-only assign/clear.
EOF Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
namespace HSchool.People;
|
||||
|
||||
public enum ClassTeacherError
|
||||
{
|
||||
None,
|
||||
UnknownSchool,
|
||||
UnknownClass,
|
||||
UnknownPerson,
|
||||
NotTeacher,
|
||||
}
|
||||
|
||||
public sealed record ClassTeacherOutcome(ClassTeacherError Error, Roster Roster);
|
||||
|
||||
/// <summary>
|
||||
/// Assigns or clears the class-teacher slot on a <see cref="SchoolClass"/>. Not a
|
||||
/// <see cref="PositionDef"/> — any hired teacher may cover several classes.
|
||||
/// </summary>
|
||||
public static class ClassTeachers
|
||||
{
|
||||
public static ClassTeacherOutcome UnknownSchool() =>
|
||||
new(ClassTeacherError.UnknownSchool, new Roster([], [], []));
|
||||
|
||||
public static ClassTeacherOutcome Assign(Roster roster, string classId, string personId)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(roster);
|
||||
ArgumentNullException.ThrowIfNull(classId);
|
||||
ArgumentNullException.ThrowIfNull(personId);
|
||||
|
||||
var index = IndexOf(roster.Classes, classId);
|
||||
if (index < 0)
|
||||
{
|
||||
return new ClassTeacherOutcome(ClassTeacherError.UnknownClass, roster);
|
||||
}
|
||||
|
||||
var person = roster.People.FirstOrDefault(candidate => candidate.Id.Equals(personId, StringComparison.Ordinal));
|
||||
if (person is null)
|
||||
{
|
||||
return new ClassTeacherOutcome(ClassTeacherError.UnknownPerson, roster);
|
||||
}
|
||||
|
||||
if (!person.IsStaff || !string.Equals(person.Position, Staffing.TeacherPosition, StringComparison.Ordinal))
|
||||
{
|
||||
return new ClassTeacherOutcome(ClassTeacherError.NotTeacher, roster);
|
||||
}
|
||||
|
||||
return Replace(roster, index, personId);
|
||||
}
|
||||
|
||||
public static ClassTeacherOutcome Clear(Roster roster, string classId)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(roster);
|
||||
ArgumentNullException.ThrowIfNull(classId);
|
||||
|
||||
var index = IndexOf(roster.Classes, classId);
|
||||
if (index < 0)
|
||||
{
|
||||
return new ClassTeacherOutcome(ClassTeacherError.UnknownClass, roster);
|
||||
}
|
||||
|
||||
return Replace(roster, index, null);
|
||||
}
|
||||
|
||||
private static ClassTeacherOutcome Replace(Roster roster, int index, string? teacherId)
|
||||
{
|
||||
var classes = roster.Classes.ToArray();
|
||||
classes[index] = classes[index] with { ClassTeacherId = teacherId };
|
||||
return new ClassTeacherOutcome(ClassTeacherError.None, roster with { Classes = classes });
|
||||
}
|
||||
|
||||
private static int IndexOf(IReadOnlyList<SchoolClass> classes, string classId)
|
||||
{
|
||||
for (var i = 0; i < classes.Count; i++)
|
||||
{
|
||||
if (classes[i].Id.Equals(classId, StringComparison.Ordinal))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -142,4 +142,6 @@ public sealed record SchoolClass(
|
||||
string Letter,
|
||||
string RoomId,
|
||||
int Capacity,
|
||||
IReadOnlyList<string> PupilIds);
|
||||
IReadOnlyList<string> PupilIds,
|
||||
/// <summary>Hired teacher who is the class teacher, or null when the slot is empty.</summary>
|
||||
string? ClassTeacherId = null);
|
||||
|
||||
Reference in New Issue
Block a user