| | 1 | | namespace Syki.Back.Features.Academic.FinalizeClasses; |
| | 2 | |
|
| 271 | 3 | | public class FinalizeClassesService(SykiDbContext ctx) : IAcademicService |
| | 4 | | { |
| | 5 | | public async Task<OneOf<SykiSuccess, SykiError>> Finalize(Guid institutionId, FinalizeClassesIn data) |
| | 6 | | { |
| 5 | 7 | | var classes = await ctx.Classes |
| 5 | 8 | | .Include(x => x.Lessons) |
| 5 | 9 | | .ThenInclude(x => x.Attendances) |
| 5 | 10 | | .Include(x => x.Students) |
| 5 | 11 | | .Include(t => t.ExamGrades) |
| 5 | 12 | | .Where(c => c.InstitutionId == institutionId && data.Classes.Contains(c.Id)) |
| 5 | 13 | | .ToListAsync(); |
| | 14 | |
|
| 6 | 15 | | if (classes.Count == 0) return new InvalidClassesList(); |
| | 16 | |
|
| 8 | 17 | | var statusOk = classes.All(x => x.Status == ClassStatus.Started); |
| 6 | 18 | | if (!statusOk) return new ClassMustHaveStartedStatus(); |
| | 19 | |
|
| 4 | 20 | | var results = classes.ConvertAll(c => c.Finish()); |
| 7 | 21 | | foreach (var result in results) |
| | 22 | | { |
| 3 | 23 | | if (result.IsError()) return result.GetError(); |
| | 24 | | } |
| | 25 | |
|
| 2 | 26 | | var ids = classes.ConvertAll(x => x.Id); |
| 1 | 27 | | var classesStudents = await ctx.ClassesStudents.Where(x => ids.Contains(x.ClassId)).ToListAsync(); |
| | 28 | |
|
| 1 | 29 | | var configs = await ctx.Configs.FirstAsync(x => x.InstitutionId == institutionId); |
| | 30 | |
|
| 4 | 31 | | foreach (var @class in classes) |
| | 32 | | { |
| 22 | 33 | | var lessons = @class.Lessons.Count(x => x.Attendances.Count > 0); |
| 4 | 34 | | foreach (var student in @class.Students) |
| | 35 | | { |
| 4 | 36 | | var studentExamGrades = @class.ExamGrades.Where(g => g.StudentId == student.Id).ToList(); |
| 1 | 37 | | var averageNote = studentExamGrades.GetAverageNote(); |
| 43 | 38 | | var presences = @class.Lessons.Count(x => x.Attendances.Exists(a => a.StudentId == student.Id && a.Prese |
| 1 | 39 | | var frequency = lessons == 0 ? 0.00M : 100M * (1M * presences / (1M * lessons)); |
| 2 | 40 | | var link = classesStudents.First(x => x.ClassId == @class.Id && x.SykiStudentId == student.Id); |
| | 41 | |
|
| 1 | 42 | | link.StudentDisciplineStatus = StudentDisciplineStatus.Aprovado; |
| 1 | 43 | | if (averageNote < configs.NoteLimit) |
| | 44 | | { |
| 1 | 45 | | link.StudentDisciplineStatus = StudentDisciplineStatus.ReprovadoPorNota; |
| | 46 | | } |
| 0 | 47 | | else if (frequency < configs.FrequencyLimit) |
| | 48 | | { |
| 0 | 49 | | link.StudentDisciplineStatus = StudentDisciplineStatus.ReprovadoPorFalta; |
| | 50 | | } |
| | 51 | | } |
| | 52 | | } |
| | 53 | |
|
| 1 | 54 | | await ctx.SaveChangesAsync(); |
| | 55 | |
|
| 1 | 56 | | return new SykiSuccess(); |
| 5 | 57 | | } |
| | 58 | | } |