Untitled

 avatar
unknown
plain_text
2 years ago
7.9 kB
0
Indexable
package pt.ulisboa.tecnico.socialsoftware.tutor.teacherdashboard.services;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import pt.ulisboa.tecnico.socialsoftware.tutor.exceptions.TutorException;
import pt.ulisboa.tecnico.socialsoftware.tutor.execution.domain.CourseExecution;
import pt.ulisboa.tecnico.socialsoftware.tutor.execution.repository.CourseExecutionRepository;
import pt.ulisboa.tecnico.socialsoftware.tutor.teacherdashboard.domain.TeacherDashboard;
import pt.ulisboa.tecnico.socialsoftware.tutor.teacherdashboard.domain.QuestionStats;
import pt.ulisboa.tecnico.socialsoftware.tutor.teacherdashboard.dto.TeacherDashboardDto;
import pt.ulisboa.tecnico.socialsoftware.tutor.teacherdashboard.dto.QuestionStatsDto;
import pt.ulisboa.tecnico.socialsoftware.tutor.teacherdashboard.repository.TeacherDashboardRepository;
import pt.ulisboa.tecnico.socialsoftware.tutor.teacherdashboard.repository.QuestionStatsRepository;
import pt.ulisboa.tecnico.socialsoftware.tutor.user.domain.Teacher;
import pt.ulisboa.tecnico.socialsoftware.tutor.user.repository.TeacherRepository;
import pt.ulisboa.tecnico.socialsoftware.tutor.question.domain.Course;
import pt.ulisboa.tecnico.socialsoftware.tutor.exceptions.ErrorMessage;
import java.util.stream.Collectors;

import java.util.*;
import java.util.stream.*;

import static pt.ulisboa.tecnico.socialsoftware.tutor.exceptions.ErrorMessage.*;

@Service
public class TeacherDashboardService {

    @Autowired
    private CourseExecutionRepository courseExecutionRepository;

    @Autowired
    private TeacherRepository teacherRepository;

    @Autowired
    private TeacherDashboardRepository teacherDashboardRepository;

    @Autowired
    private QuestionStatsRepository questionStatsRepository;

    @Transactional(isolation = Isolation.READ_COMMITTED)
    public TeacherDashboardDto getTeacherDashboard(int courseExecutionId, int teacherId) {
        CourseExecution courseExecution = courseExecutionRepository.findById(courseExecutionId)
                .orElseThrow(() -> new TutorException(COURSE_EXECUTION_NOT_FOUND));
        Teacher teacher = teacherRepository.findById(teacherId)
                .orElseThrow(() -> new TutorException(USER_NOT_FOUND, teacherId));

        if (!teacher.getCourseExecutions().contains(courseExecution))
            throw new TutorException(TEACHER_NO_COURSE_EXECUTION);

        Optional<TeacherDashboard> dashboardOptional = teacher.getDashboards().stream()
                .filter(dashboard -> dashboard.getCourseExecution().getId().equals(courseExecutionId))
                .findAny();

        return dashboardOptional.
                map(TeacherDashboardDto::new).
                orElseGet(() -> createAndReturnTeacherDashboardDto(courseExecution, teacher));
    }

    @Transactional(isolation = Isolation.READ_COMMITTED)
    public TeacherDashboardDto createTeacherDashboard(int courseExecutionId, int teacherId) {
        CourseExecution courseExecution = courseExecutionRepository.findById(courseExecutionId)
                .orElseThrow(() -> new TutorException(COURSE_EXECUTION_NOT_FOUND));
        Teacher teacher = teacherRepository.findById(teacherId)
                .orElseThrow(() -> new TutorException(USER_NOT_FOUND, teacherId));

        if (teacher.getDashboards().stream().anyMatch(dashboard -> dashboard.getCourseExecution().equals(courseExecution)))
            throw new TutorException(TEACHER_ALREADY_HAS_DASHBOARD);

        if (!teacher.getCourseExecutions().contains(courseExecution))
            throw new TutorException(TEACHER_NO_COURSE_EXECUTION);

        return createAndReturnTeacherDashboardDto(courseExecution, teacher);
    }

    private TeacherDashboardDto createAndReturnTeacherDashboardDto(CourseExecution courseExecution, Teacher teacher) {
        TeacherDashboard teacherDashboard = new TeacherDashboard(courseExecution, teacher);
        teacherDashboardRepository.save(teacherDashboard);

        Course course = courseExecution.getCourse();

        List<CourseExecution> recentCourseExecutions = this.getRecentCourseExecutions(course);

        List<QuestionStats> questionStatsList = new ArrayList<QuestionStats>();

        int recentCourseExecutionsSize = recentCourseExecutions.size();

        for(int i = 0; i < recentCourseExecutionsSize; i++){
            QuestionStats questionStats = new QuestionStats(teacherDashboard, recentCourseExecutions.get(i));
            questionStatsRepository.save(questionStats);
            questionStatsList.add(questionStats);
        }
        teacherDashboard.setQuestionStats(questionStatsList);
        teacherDashboard.update();

        return new TeacherDashboardDto(teacherDashboard);
    }

    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void removeTeacherDashboard(Integer dashboardId) {
        if (dashboardId == null)
            throw new TutorException(DASHBOARD_NOT_FOUND, -1);

        TeacherDashboard teacherDashboard = teacherDashboardRepository.findById(dashboardId).orElseThrow(() -> new TutorException(DASHBOARD_NOT_FOUND, dashboardId));

        List<QuestionStats> questionStats = teacherDashboard.getQuestionStats();
        int questionStatsListSize= questionStats.size();

        for (int i = 0; i < questionStatsListSize; i++){
            questionStatsRepository.delete(questionStats.get(i));
        }
        teacherDashboard.remove();
        teacherDashboardRepository.delete(teacherDashboard);
    }

    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void updateTeacherDashboard(Integer dashboardId) {
        if (dashboardId == null)
            throw new TutorException(DASHBOARD_NOT_FOUND, -1);
        TeacherDashboard teacherDashboard = teacherDashboardRepository.findById(dashboardId).orElseThrow(() -> new TutorException(DASHBOARD_NOT_FOUND));

        teacherDashboard.update();
    }

    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void updateAllTeacherDashboards(){
        List<Teacher> teachers = StreamSupport.stream(teacherRepository.findAll().spliterator(), false).collect(Collectors.toList());

        for(Teacher teacher : teachers){
            for(CourseExecution courseExecution : teacher.getCourseExecutions()){
                if (teacher.getCourseExecutionDashboard(courseExecution) == null){
                    createTeacherDashboard(courseExecution.getId(), teacher.getId());
                }
            }
        }

        List<TeacherDashboard> listOfAllTeacherDashboards = StreamSupport.stream(teacherDashboardRepository.findAll().spliterator(), false).collect(Collectors.toList());

        for(TeacherDashboard teacherDashboard : listOfAllTeacherDashboards){
            updateTeacherDashboard(teacherDashboard.getId());
        }
    }

    private List<CourseExecution> getRecentCourseExecutions(Course course){
        Set<CourseExecution> courseExecutions = course.getCourseExecutions();

        List<CourseExecution> recentCourseExecutions = courseExecutions.stream()
                .filter(unfilteredCourseExecution -> {
                    try{
                        unfilteredCourseExecution.getEndDate();
                    } catch(IllegalStateException e){
                        return false;
                    }
                    return true;

                })
                .sorted(Comparator.comparing(CourseExecution::getEndDate).reversed())
                .limit(3)
                .collect(Collectors.toList());

        return recentCourseExecutions;
    }
}