use of de.tum.in.www1.artemis.domain.exam.Exam in project ArTEMiS by ls1intum.
the class ExamResource method archiveExam.
/**
* PUT /courses/{courseId}/exams/{examId}/archive : archive an existing exam asynchronously.
*
* This method starts the process of archiving all exam exercises and submissions.
* It immediately returns and runs this task asynchronously. When the task is done, the exam is marked as archived, which means the zip file can be downloaded.
*
* @param courseId the id of the course
* @param examId the id of the exam to archive
* @return empty
*/
@PutMapping("/courses/{courseId}/exams/{examId}/archive")
@PreAuthorize("hasRole('INSTRUCTOR')")
public ResponseEntity<Void> archiveExam(@PathVariable Long courseId, @PathVariable Long examId) {
log.info("REST request to archive exam : {}", examId);
final Exam exam = examRepository.findOneWithEagerExercisesGroupsAndStudentExams(examId);
if (exam == null) {
throw new EntityNotFoundException("exam", examId);
}
examAccessService.checkCourseAndExamAccessForInstructorElseThrow(courseId, examId);
// Archiving an exam is only possible after the exam is over
if (now().isBefore(exam.getEndDate())) {
throw new BadRequestAlertException("You cannot archive an exam that is not over.", ENTITY_NAME, "examNotOver", true);
}
examService.archiveExam(exam);
return ResponseEntity.ok().build();
}
use of de.tum.in.www1.artemis.domain.exam.Exam in project ArTEMiS by ls1intum.
the class ExamResource method getExamForAssessmentDashboard.
/**
* GET /courses/:courseId/exams/:examId/exam-for-assessment-dashboard
*
* @param courseId the id of the course to retrieve
* @param examId the id of the exam that contains the exercises
* @return data about a course including all exercises, plus some data for the tutor as tutor status for assessment
*/
@GetMapping("/courses/{courseId}/exams/{examId}/exam-for-assessment-dashboard")
@PreAuthorize("hasRole('TA')")
public ResponseEntity<Exam> getExamForAssessmentDashboard(@PathVariable long courseId, @PathVariable long examId) {
log.debug("REST request /courses/{courseId}/exams/{examId}/exam-for-assessment-dashboard");
Exam exam = examService.findByIdWithExerciseGroupsAndExercisesElseThrow(examId);
Course course = exam.getCourse();
checkExamCourseIdElseThrow(courseId, exam);
User user = userRepository.getUserWithGroupsAndAuthorities();
authCheckService.checkHasAtLeastRoleInCourseElseThrow(Role.TEACHING_ASSISTANT, course, user);
if (ZonedDateTime.now().isBefore(exam.getEndDate()) && authCheckService.isTeachingAssistantInCourse(course, user)) {
// tutors cannot access the exercises before the exam ends
throw new AccessForbiddenException("exam", examId);
}
Set<Exercise> exercises = new HashSet<>();
// extract all exercises for all the exam
for (ExerciseGroup exerciseGroup : exam.getExerciseGroups()) {
exerciseGroup.setExercises(courseRepository.getInterestingExercisesForAssessmentDashboards(exerciseGroup.getExercises()));
exercises.addAll(exerciseGroup.getExercises());
}
List<TutorParticipation> tutorParticipations = tutorParticipationRepository.findAllByAssessedExercise_ExerciseGroup_Exam_IdAndTutor_Id(examId, user.getId());
assessmentDashboardService.generateStatisticsForExercisesForAssessmentDashboard(exercises, tutorParticipations, true);
return ResponseEntity.ok(exam);
}
use of de.tum.in.www1.artemis.domain.exam.Exam in project ArTEMiS by ls1intum.
the class ExamResource method getExamStatistics.
/**
* GET /courses/{courseId}/exams/{examId} : Find an exam by id.
*
* @param courseId the course to which the exam belongs
* @param examId the exam to find
* @return the ResponseEntity with status 200 (OK) and with the found exam as body
*/
@GetMapping("/courses/{courseId}/exams/{examId}/statistics")
@PreAuthorize("hasRole('TA')")
public ResponseEntity<ExamChecklistDTO> getExamStatistics(@PathVariable Long courseId, @PathVariable Long examId) {
log.debug("REST request to get exam statistics: {}", examId);
examAccessService.checkCourseAndExamAccessForTeachingAssistantElseThrow(courseId, examId);
var course = courseRepository.findByIdElseThrow(courseId);
var isInstructorInCourse = authCheckService.isAtLeastInstructorInCourse(course, null);
Exam exam = examRepository.findByIdWithRegisteredUsersExerciseGroupsAndExercisesElseThrow(examId);
ExamChecklistDTO examChecklistDTO = examService.getStatsForChecklist(exam, isInstructorInCourse);
return ResponseEntity.ok(examChecklistDTO);
}
use of de.tum.in.www1.artemis.domain.exam.Exam in project ArTEMiS by ls1intum.
the class ExamResource method generateMissingStudentExams.
/**
* POST /courses/:courseId/exams/:examId/generate-missing-student-exams:
* Generates exams for students, who don't have an individual exam yet.
* They are created randomly based on the exam configuration and the exercise groups.
*
* @param courseId the id of the course
* @param examId the id of the exam
* @return the list of student exams with their corresponding users
*/
@PostMapping(value = "/courses/{courseId}/exams/{examId}/generate-missing-student-exams")
@PreAuthorize("hasRole('INSTRUCTOR')")
public ResponseEntity<List<StudentExam>> generateMissingStudentExams(@PathVariable Long courseId, @PathVariable Long examId) {
log.info("REST request to generate missing student exams for exam {}", examId);
final Exam exam = examRepository.findByIdWithRegisteredUsersExerciseGroupsAndExercisesElseThrow(examId);
examAccessService.checkCourseAndExamAccessForInstructorElseThrow(courseId, examId);
// Validate settings of the exam
examService.validateForStudentExamGeneration(exam);
List<StudentExam> studentExams = studentExamRepository.generateMissingStudentExams(exam);
// we need to break a cycle for the serialization
for (StudentExam studentExam : studentExams) {
studentExam.getExam().setRegisteredUsers(null);
studentExam.getExam().setExerciseGroups(null);
studentExam.getExam().setStudentExams(null);
}
log.info("Generated {} missing student exams for exam {}", studentExams.size(), examId);
return ResponseEntity.ok().body(studentExams);
}
use of de.tum.in.www1.artemis.domain.exam.Exam in project ArTEMiS by ls1intum.
the class ExerciseGroupResource method createExerciseGroup.
/**
* POST /courses/{courseId}/exams/{examId}/exerciseGroups : Create a new exercise group.
*
* @param courseId the course to which the exercise group belongs to
* @param examId the exam to which the exercise group belongs to
* @param exerciseGroup the exercise group to create
* @return the ResponseEntity with status 201 (Created) and with the new exerciseGroup as body,
* or with status 400 (Bad Request) if the exerciseGroup has already an ID
* @throws URISyntaxException if the Location URI syntax is incorrect
*/
@PostMapping("/courses/{courseId}/exams/{examId}/exerciseGroups")
@PreAuthorize("hasRole('EDITOR')")
public ResponseEntity<ExerciseGroup> createExerciseGroup(@PathVariable Long courseId, @PathVariable Long examId, @RequestBody ExerciseGroup exerciseGroup) throws URISyntaxException {
log.debug("REST request to create an exercise group : {}", exerciseGroup);
if (exerciseGroup.getId() != null) {
throw new BadRequestAlertException("A new exerciseGroup cannot already have an ID", ENTITY_NAME, "idexists");
}
if (exerciseGroup.getExam() == null) {
throw new ConflictException("The exercise group has to belong no an exam.", ENTITY_NAME, "missingExam");
}
if (!exerciseGroup.getExam().getId().equals(examId)) {
throw new ConflictException("The exam connected to this group does not have the given exam id.", ENTITY_NAME, "wrongExamId");
}
examAccessService.checkCourseAndExamAccessForEditorElseThrow(courseId, examId);
// Save the exerciseGroup as part of the exam to ensure that the order column is set correctly
Exam examFromDB = examRepository.findByIdWithExerciseGroupsElseThrow(examId);
examFromDB.addExerciseGroup(exerciseGroup);
Exam savedExam = examRepository.save(examFromDB);
ExerciseGroup savedExerciseGroup = savedExam.getExerciseGroups().get(savedExam.getExerciseGroups().size() - 1);
return ResponseEntity.created(new URI("/api/courses/" + courseId + "/exams/" + examId + "/exerciseGroups/" + savedExerciseGroup.getId())).headers(HeaderUtil.createEntityCreationAlert(applicationName, true, ENTITY_NAME, savedExerciseGroup.getTitle())).body(savedExerciseGroup);
}
Aggregations