< Summary - Syki

Information
Class: Syki.Back.Features.Teacher.GetTeacherClassStudents.ClassActivityDto
Assembly: Back
File(s): /home/runner/work/syki/syki/Back/Features/Teacher/GetTeacherClassStudents/GetTeacherClassStudentsService.cs
Tag: 4_16869239191
Line coverage
100%
Covered lines: 1
Uncovered lines: 0
Coverable lines: 1
Total lines: 70
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Id()100%11100%

File(s)

/home/runner/work/syki/syki/Back/Features/Teacher/GetTeacherClassStudents/GetTeacherClassStudentsService.cs

#LineLine coverage
 1namespace Syki.Back.Features.Teacher.GetTeacherClassStudents;
 2
 3public class GetTeacherClassStudentsService(SykiDbContext ctx) : ITeacherService
 4{
 5    public async Task<OneOf<List<TeacherClassStudentOut>, SykiError>> Get(Guid teacherId, Guid classId)
 6    {
 7        var @class = await ctx.Classes.AsNoTracking()
 8            .Include(x => x.Students)
 9            .FirstOrDefaultAsync(x => x.Id == classId && x.TeacherId == teacherId);
 10        if (@class == null) return new ClassNotFound();
 11
 12        var students = @class.Students.OrderBy(x => x.Name)
 13            .Select(x => new TeacherClassStudentOut { Id = x.Id, Name = x.Name })
 14            .ToList();
 15        var classAttendances = await ctx.Attendances.AsNoTracking().Where(x => x.ClassId == classId).ToListAsync();
 16
 17        var classActivities = await ctx.ClassActivities
 18            .AsNoTrackingWithIdentityResolution()
 19            .Where(x => x.ClassId == classId)
 20            .Include(x => x.Works)
 21            .ToListAsync();
 22        var activities = classActivities
 23            .Select(x => new ClassActivityDto(x.Id, x.Weight, x.Note))
 24            .ToList();
 25
 26        foreach (var student in students)
 27        {
 28            var attendances = classAttendances.Count(x => x.StudentId == student.Id);
 29            var presences = classAttendances.Count(x => x.StudentId == student.Id && x.Present);
 30            student.Frequency = attendances > 0 ? Math.Round(100M*(1M * presences / (1M * attendances)), 2) : 0;
 31
 32            var works = classActivities.SelectMany(x => x.Works.Where(w => w.SykiStudentId == student.Id))
 33                .Select(x => new ClassActivityWorkDto(x.ClassActivityId, x.Note))
 34                .ToList();
 35
 36            var n1 = GetAverage(activities.Where(x => x.Note == ClassNoteType.N1).ToList(), works);
 37            var n2 = GetAverage(activities.Where(x => x.Note == ClassNoteType.N2).ToList(), works);
 38            var n3 = GetAverage(activities.Where(x => x.Note == ClassNoteType.N3).ToList(), works);
 39
 40            student.Notes.Add(new() { Type = ClassNoteType.N1, Note = n1 });
 41            student.Notes.Add(new() { Type = ClassNoteType.N2, Note = n2 });
 42            student.Notes.Add(new() { Type = ClassNoteType.N3, Note = n3 });
 43            student.AverageNote = GetAverageNote(n1, n2, n3);
 44        }
 45
 46        return students;
 47    }
 48
 49    private static decimal GetAverage(List<ClassActivityDto> activities, List<ClassActivityWorkDto> works)
 50    {
 51        var average = 0.00M;
 52        foreach (var activity in activities)
 53        {
 54            var work = works.First(x => x.ActivityId == activity.Id);
 55            average += activity.Weight * work.Note;
 56        }
 57        average /= 100.00M;
 58        return average;
 59    }
 60
 61    private static decimal GetAverageNote(params decimal[] notes)
 62    {
 63        if (notes.Length <= 2) return 0;
 64        var average = notes.OrderDescending().Take(2).Average();
 65        return Math.Round(average, 2);
 66    }
 67}
 68
 4269internal record ClassActivityDto(Guid Id, int Weight, ClassNoteType Note);
 70internal record ClassActivityWorkDto(Guid ActivityId, decimal Note);

Methods/Properties

get_Id()