Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import school.hei.haapi.endpoint.rest.mapper.ExamMapper;
import school.hei.haapi.endpoint.rest.model.CrupdateExam;
import school.hei.haapi.endpoint.rest.model.ExamInfo;
import school.hei.haapi.endpoint.rest.model.StudentCourseGradeStats;
import school.hei.haapi.endpoint.rest.model.StudentExamGrade;
import school.hei.haapi.model.BoundedPageSize;
import school.hei.haapi.model.PageFromOne;
Expand Down Expand Up @@ -118,4 +119,11 @@ public List<StudentExamGrade> getStudentExamsGrade(
.map(exam -> examMapper.toRestStudentExamGrade(studentId, exam))
.toList();
}

@GetMapping("/courses/{course_id}/student/{student_id}/grade/stats")
public StudentCourseGradeStats getStudentCourseGradeStats(
@PathVariable(value = "course_id") String courseId,
@PathVariable(value = "student_id") String studentId) {
return examService.getStudentCourseGradeStats(courseId, studentId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ req, res, null, forbiddenWithRemoteInfo(req))))
antMatcher(GET, "/courses/*/exams/*/details"),
antMatcher(GET, "/courses/*/exams/*/participants/*"),
antMatcher(GET, "/courses/*/student/*/exams/grades"),
antMatcher(GET, "/courses/*/student/*/grade/stats"),
antMatcher(GET, STUDENT_COURSE),
antMatcher(GET, "/comments"),
antMatcher(GET, "/students/*/comments"),
Expand Down Expand Up @@ -862,6 +863,11 @@ req, res, null, forbiddenWithRemoteInfo(req))))
.hasAnyRole(STUDENT.getRole())
.requestMatchers(GET, "/courses/*/student/*/exams/grades")
.hasAnyRole(TEACHER.getRole(), MANAGER.getRole(), ADMIN.getRole())
.requestMatchers(
new SelfMatcher(GET, "/courses/*/student/*/grade/stats", "student"))
.hasAnyRole(STUDENT.getRole())
.requestMatchers(GET, "/courses/*/student/*/grade/stats")
.hasAnyRole(TEACHER.getRole(), MANAGER.getRole(), ADMIN.getRole())
.requestMatchers(new SelfMatcher(GET, STUDENT_COURSE, "students"))
.hasAnyRole(STUDENT.getRole(), ADMIN.getRole())
.requestMatchers(GET, STUDENT_COURSE)
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/school/hei/haapi/model/Grade.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import jakarta.persistence.Table;
import java.io.Serializable;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
Expand Down Expand Up @@ -49,4 +51,13 @@ public Grade(Exam exam, User student) {
this.student = student;
this.exam = exam;
}

public static double scoreSumWithCoefficient(List<Grade> grades) {
return grades.stream()
.mapToDouble(
grade ->
Optional.ofNullable(grade.getScore()).orElse(0.)
* Optional.ofNullable(grade.getExam().getCoefficient()).orElse(0))
.sum();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package school.hei.haapi.repository;

import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
Expand All @@ -18,4 +19,10 @@ Optional<Grade> getGradeByExamIdAndStudentRef(
@Param("exam_id") String examId, @Param("student_ref") String studentRef);

Optional<Grade> findByExamIdAndStudentId(String examId, String studentId);

@Query(
"select g from Grade g where g.exam.awardedCourse.course.id = :course_id"
+ " and g.student = :user_id ")
List<Grade> findGradesByCourseIdAndStudentId(
@Param("course_id") String courseId, @Param("user_id") String studentId);
}
10 changes: 10 additions & 0 deletions src/main/java/school/hei/haapi/service/ExamService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static java.util.stream.Collectors.toUnmodifiableList;
import static org.springframework.data.domain.Sort.Direction.DESC;
import static school.hei.haapi.model.Grade.scoreSumWithCoefficient;

import java.time.Instant;
import java.util.ArrayList;
Expand All @@ -11,6 +12,7 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import school.hei.haapi.endpoint.rest.model.StudentCourseGradeStats;
import school.hei.haapi.model.BoundedPageSize;
import school.hei.haapi.model.Exam;
import school.hei.haapi.model.Grade;
Expand Down Expand Up @@ -93,4 +95,12 @@ public List<Exam> getAllExams(
public List<Exam> getExamsByCourseId(String courseId) {
return examRepository.findExamsByCourseId(courseId);
}

public StudentCourseGradeStats getStudentCourseGradeStats(String courseId, String studentId) {
List<Exam> exams = getExamsByCourseId(courseId);
double sumScore =
scoreSumWithCoefficient(gradeService.getGradeByCourseIdAndStudentId(courseId, studentId));
double sumCoefficient = exams.stream().mapToDouble(Exam::getCoefficient).sum();
return new StudentCourseGradeStats().average(sumScore / sumCoefficient);
}
}
13 changes: 13 additions & 0 deletions src/main/java/school/hei/haapi/service/GradeService.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,17 @@ private double getExamAverageGrade(String examId) {
public ExamGradeStats getExamGradeStats(String examId) {
return new ExamGradeStats().average(getExamAverageGrade(examId));
}

public double scoreSumWithCoefficient(List<Grade> grades) {
return grades.stream()
.mapToDouble(
grade ->
Optional.ofNullable(grade.getScore()).orElse(0.)
* Optional.ofNullable(grade.getExam().getCoefficient()).orElse(0))
.sum();
}

public List<Grade> getGradeByCourseIdAndStudentId(String courseId, String studentId) {
return gradeRepository.findGradesByCourseIdAndStudentId(courseId, studentId);
}
}
48 changes: 48 additions & 0 deletions src/test/java/school/hei/haapi/service/ExamServiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package school.hei.haapi.service;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
import static school.hei.haapi.integration.conf.TestUtils.COURSE1_ID;
import static school.hei.haapi.integration.conf.TestUtils.STUDENT1_ID;
import static school.hei.haapi.integration.conf.TestUtils.exam1;
import static school.hei.haapi.integration.conf.TestUtils.exam2;
import static school.hei.haapi.integration.conf.TestUtils.grade1;
import static school.hei.haapi.integration.conf.TestUtils.grade2;

import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import school.hei.haapi.endpoint.rest.mapper.ExamMapper;
import school.hei.haapi.endpoint.rest.mapper.GradeMapper;
import school.hei.haapi.endpoint.rest.model.StudentCourseGradeStats;
import school.hei.haapi.integration.conf.FacadeITMockedThirdParties;
import school.hei.haapi.repository.ExamRepository;
import school.hei.haapi.repository.GradeRepository;

class ExamServiceTest extends FacadeITMockedThirdParties {
@Autowired private ExamService subject;
@MockBean private ExamRepository examRepository;
@Autowired private ExamMapper examMapper;
@MockBean private GradeRepository gradeRepository;
@Autowired private GradeMapper gradeMapper;

@Test
void student_get_grade_for_each_exams_in_cours() {
var exam1 = examMapper.toDomain(exam1(), null);
var exam2 = examMapper.toDomain(exam2(), null);
var grade1 = gradeMapper.toDomain(grade1());
var grade2 = gradeMapper.toDomain(grade2());
grade1.setExam(exam1);
grade2.setExam(exam2);
when(examRepository.findExamsByCourseId(anyString())).thenReturn(List.of(exam1, exam2));
when(gradeRepository.findGradesByCourseIdAndStudentId(anyString(), anyString()))
.thenReturn(List.of(grade1, grade2));

StudentCourseGradeStats studentCourseGradeStats =
subject.getStudentCourseGradeStats(COURSE1_ID, STUDENT1_ID);

assertEquals(6.2, studentCourseGradeStats.getAverage());
}
}
Loading