using LehrerApp.Core.Interfaces; using LehrerApp.Core.Models; namespace LehrerApp.Data.Repositories; public class StudentGroupPlanRepository(LiteDbContext db) : IStudentGroupPlanRepository { public StudentGroupPlan? GetById(Guid id) => db.StudentGroupPlans.FindById(id); public List GetByGroup(Guid groupId) => db.StudentGroupPlans.Find(p => p.GroupId == groupId) .OrderByDescending(p => p.UpdatedAt).ToList(); public List GetByStudent(Guid studentId) => db.StudentGroupPlans.FindAll() .Where(plan => plan.Groups.Any(group => group.StudentIds.Contains(studentId))) .OrderByDescending(plan => plan.UpdatedAt).ToList(); public void Save(StudentGroupPlan plan) { if (db.Groups.FindById(plan.GroupId) is null) throw new InvalidOperationException("Die zugehörige Lerngruppe existiert nicht."); ArchivedGroupWriteGuard.EnsureActive(db, plan.GroupId); plan.Name = plan.Name?.Trim() ?? ""; if (plan.Name.Length == 0) throw new ArgumentException("Bitte einen Namen für die Gruppeneinteilung eingeben."); plan.Groups ??= []; if (plan.Groups.Count == 0) throw new InvalidOperationException("Die Gruppeneinteilung enthält keine Gruppen."); var ids = plan.Groups.SelectMany(g => g.StudentIds ?? []).ToList(); if (ids.Count != ids.Distinct().Count()) throw new InvalidOperationException("Ein Schüler darf nur in einer Gruppe stehen."); if (db.StudentGroupPlans.Find(p => p.GroupId == plan.GroupId) .Any(p => p.Id != plan.Id && string.Equals(p.Name, plan.Name, StringComparison.OrdinalIgnoreCase))) throw new InvalidOperationException("Eine gespeicherte Einteilung mit diesem Namen gibt es bereits."); if (db.StudentGroupPlans.FindById(plan.Id) is { } existing) { if (existing.GroupId != plan.GroupId) throw new InvalidOperationException("Eine Gruppeneinteilung kann nicht in eine andere Lerngruppe verschoben werden."); plan.CreatedAt = existing.CreatedAt; } plan.UpdatedAt = DateTime.UtcNow; db.StudentGroupPlans.Upsert(plan); db.OnChange?.Invoke(nameof(StudentGroupPlan), plan.Id.ToString(), "Save", plan); } public void Delete(Guid id) { if (db.StudentGroupPlans.FindById(id) is not { } plan) return; ArchivedGroupWriteGuard.EnsureActive(db, plan.GroupId); db.StudentGroupPlans.Delete(id); db.OnChange?.Invoke(nameof(StudentGroupPlan), id.ToString(), "Delete", null); } }