Skip to content

Commit

Permalink
Add creation and deletion stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
JohannesStoehr committed Nov 7, 2024
1 parent 7024d9a commit 1eb6786
Show file tree
Hide file tree
Showing 16 changed files with 357 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package de.tum.cit.aet.artemis.atlas.domain.profile;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
Expand All @@ -17,10 +19,19 @@ public class CourseLearnerProfile extends DomainObject {
@JoinColumn(name = "learner_profile_id")
private LearnerProfile learnerProfile;

@OneToOne
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "course_id")
private Course course;

@Column(name = "aim_for_grade_or_bonus")
private int aimForGradeOrBonus;

@Column(name = "time_investment")
private int timeInvestment;

@Column(name = "repetition_intensity")
private int repetitionIntensity;

public void setLearnerProfile(LearnerProfile learnerProfile) {
this.learnerProfile = learnerProfile;
}
Expand All @@ -36,4 +47,28 @@ public void setCourse(Course course) {
public Course getCourse() {
return this.course;
}

public int getAimForGradeOrBonus() {
return aimForGradeOrBonus;
}

public void setAimForGradeOrBonus(int aimForGradeOrBonus) {
this.aimForGradeOrBonus = aimForGradeOrBonus;
}

public int getTimeInvestment() {
return timeInvestment;
}

public void setTimeInvestment(int timeInvestment) {
this.timeInvestment = timeInvestment;
}

public int getRepetitionIntensity() {
return repetitionIntensity;
}

public void setRepetitionIntensity(int repetitionIntensity) {
this.repetitionIntensity = repetitionIntensity;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import java.util.HashSet;
import java.util.Set;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
Expand All @@ -15,13 +17,13 @@

@Entity
@Table(name = "learner_profile")
class LearnerProfile extends DomainObject {
public class LearnerProfile extends DomainObject {

@OneToOne
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;

@OneToMany
@OneToMany(mappedBy = "learnerProfile", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private Set<CourseLearnerProfile> courseLearnerProfiles = new HashSet<>();

public void setUser(User user) {
Expand All @@ -48,7 +50,7 @@ public boolean addAllCourseLearnerProfiles(Collection<? extends CourseLearnerPro
return this.courseLearnerProfiles.addAll(courseLearnerProfiles);
}

public boolean removeCourseLearnerProfle(CourseLearnerProfile courseLearnerProfile) {
public boolean removeCourseLearnerProfile(CourseLearnerProfile courseLearnerProfile) {
return this.courseLearnerProfiles.remove(courseLearnerProfile);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package de.tum.cit.aet.artemis.atlas.repository;

import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;

import org.springframework.context.annotation.Profile;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import de.tum.cit.aet.artemis.atlas.domain.profile.CourseLearnerProfile;
import de.tum.cit.aet.artemis.core.domain.Course;
import de.tum.cit.aet.artemis.core.domain.User;
import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository;

@Profile(PROFILE_CORE)
@Repository
public interface CourseLearnerProfileRepository extends ArtemisJpaRepository<CourseLearnerProfile, Long> {

@Transactional // ok because of delete
@Modifying
@Query("""
DELETE FROM CourseLearnerProfile clp
WHERE clp.course = :course AND clp.learnerProfile.user = :user
""")
void deleteByCourseAndUser(Course course, User user);

@Transactional // ok because of delete
@Modifying
void deleteAllByCourse(Course couese);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package de.tum.cit.aet.artemis.atlas.repository;

import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;

import java.util.Optional;

import org.springframework.context.annotation.Profile;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import de.tum.cit.aet.artemis.atlas.domain.profile.LearnerProfile;
import de.tum.cit.aet.artemis.core.domain.User;
import de.tum.cit.aet.artemis.core.repository.base.ArtemisJpaRepository;

@Profile(PROFILE_CORE)
@Repository
public interface LearnerProfileRepository extends ArtemisJpaRepository<LearnerProfile, Long> {

Optional<LearnerProfile> findByUser(User user);

default LearnerProfile findByUserElseThrow(User user) {
return getValueElseThrow(findByUser(user));
}

@Transactional // ok because of delete
@Modifying
void deleteByUser(User user);
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import de.tum.cit.aet.artemis.atlas.repository.CourseCompetencyRepository;
import de.tum.cit.aet.artemis.atlas.repository.LearningPathRepository;
import de.tum.cit.aet.artemis.atlas.service.competency.CompetencyProgressService;
import de.tum.cit.aet.artemis.atlas.service.profile.CourseLearnerProfileService;
import de.tum.cit.aet.artemis.core.domain.Course;
import de.tum.cit.aet.artemis.core.domain.User;
import de.tum.cit.aet.artemis.core.dto.SearchResultPageDTO;
Expand Down Expand Up @@ -90,10 +91,13 @@ public class LearningPathService {

private final CourseCompetencyRepository courseCompetencyRepository;

private final CourseLearnerProfileService courseLearnerProfileService;

public LearningPathService(UserRepository userRepository, LearningPathRepository learningPathRepository, CompetencyProgressRepository competencyProgressRepository,
LearningPathNavigationService learningPathNavigationService, CourseRepository courseRepository, CompetencyRepository competencyRepository,
CompetencyRelationRepository competencyRelationRepository, LectureUnitCompletionRepository lectureUnitCompletionRepository,
StudentParticipationRepository studentParticipationRepository, CourseCompetencyRepository courseCompetencyRepository) {
StudentParticipationRepository studentParticipationRepository, CourseCompetencyRepository courseCompetencyRepository,
CourseLearnerProfileService courseLearnerProfileService) {
this.userRepository = userRepository;
this.learningPathRepository = learningPathRepository;
this.competencyProgressRepository = competencyProgressRepository;
Expand All @@ -104,6 +108,7 @@ public LearningPathService(UserRepository userRepository, LearningPathRepository
this.lectureUnitCompletionRepository = lectureUnitCompletionRepository;
this.studentParticipationRepository = studentParticipationRepository;
this.courseCompetencyRepository = courseCompetencyRepository;
this.courseLearnerProfileService = courseLearnerProfileService;
}

/**
Expand All @@ -113,7 +118,9 @@ public LearningPathService(UserRepository userRepository, LearningPathRepository
*/
public void enableLearningPathsForCourse(@NotNull Course course) {
course.setLearningPathsEnabled(true);
generateLearningPaths(course);
var students = userRepository.getStudentsWithLearnerProfile(course);
courseLearnerProfileService.createCourseLearnerProfiles(course, students);
generateLearningPaths(course, students);
courseRepository.save(course);
log.debug("Enabled learning paths for course (id={})", course.getId());
}
Expand All @@ -124,7 +131,16 @@ public void enableLearningPathsForCourse(@NotNull Course course) {
* @param course course the learning paths are created for
*/
public void generateLearningPaths(@NotNull Course course) {
var students = userRepository.getStudents(course);
var students = userRepository.getStudentsWithLearnerProfile(course);
generateLearningPaths(course, students);
}

/**
* Generate learning paths for all students enrolled in the course
*
* @param course course the learning paths are created for
*/
public void generateLearningPaths(@NotNull Course course, Set<User> students) {
students.forEach(student -> generateLearningPathForUser(course, student));
log.debug("Successfully created learning paths for all {} students in course (id={})", students.size(), course.getId());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package de.tum.cit.aet.artemis.atlas.service.profile;

import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;

import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

import de.tum.cit.aet.artemis.atlas.domain.profile.CourseLearnerProfile;
import de.tum.cit.aet.artemis.atlas.repository.CourseLearnerProfileRepository;
import de.tum.cit.aet.artemis.atlas.repository.LearnerProfileRepository;
import de.tum.cit.aet.artemis.core.domain.Course;
import de.tum.cit.aet.artemis.core.domain.User;

@Profile(PROFILE_CORE)
@Service
public class CourseLearnerProfileService {

private final CourseLearnerProfileRepository courseLearnerProfileRepository;

private final LearnerProfileRepository learnerProfileRepository;

public CourseLearnerProfileService(CourseLearnerProfileRepository courseLearnerProfileRepository, LearnerProfileService learnerProfileService,
LearnerProfileRepository learnerProfileRepository) {
this.courseLearnerProfileRepository = courseLearnerProfileRepository;
this.learnerProfileRepository = learnerProfileRepository;
}

public void createCourseLearnerProfile(Course course, User user) {
var courseProfile = new CourseLearnerProfile();
courseProfile.setCourse(course);

var learnerProfile = learnerProfileRepository.findByUserElseThrow(user);
courseProfile.setLearnerProfile(learnerProfile);

courseLearnerProfileRepository.save(courseProfile);
}

public void createCourseLearnerProfiles(Course course, Set<User> users) {
Set<CourseLearnerProfile> courseProfiles = users.stream().map(user -> {
var courseProfile = new CourseLearnerProfile();
courseProfile.setCourse(course);
courseProfile.setLearnerProfile(user.getLearnerProfile());

return courseProfile;
}).collect(Collectors.toSet());

courseLearnerProfileRepository.saveAll(courseProfiles);
}

public void deleteCourseLearnerProfile(Course course, User user) {
courseLearnerProfileRepository.deleteByCourseAndUser(course, user);
}

public void deleteAllForCourse(Course course) {
courseLearnerProfileRepository.deleteAllByCourse(course);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package de.tum.cit.aet.artemis.atlas.service.profile;

import static de.tum.cit.aet.artemis.core.config.Constants.PROFILE_CORE;

import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

import de.tum.cit.aet.artemis.atlas.domain.profile.LearnerProfile;
import de.tum.cit.aet.artemis.atlas.repository.LearnerProfileRepository;
import de.tum.cit.aet.artemis.core.domain.User;

@Profile(PROFILE_CORE)
@Service
public class LearnerProfileService {

private final LearnerProfileRepository learnerProfileRepository;

public LearnerProfileService(LearnerProfileRepository learnerProfileRepository) {
this.learnerProfileRepository = learnerProfileRepository;
}

public LearnerProfile createProfile(User user) {
var profile = new LearnerProfile();
profile.setUser(user);
return learnerProfileRepository.save(profile);
}

public void deleteProfile(User user) {
learnerProfileRepository.deleteByUser(user);
}
}
14 changes: 14 additions & 0 deletions src/main/java/de/tum/cit/aet/artemis/core/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import jakarta.persistence.JoinTable;
import jakarta.persistence.ManyToMany;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import jakarta.validation.constraints.Email;
Expand All @@ -40,6 +41,7 @@

import de.tum.cit.aet.artemis.atlas.domain.competency.CompetencyProgress;
import de.tum.cit.aet.artemis.atlas.domain.competency.LearningPath;
import de.tum.cit.aet.artemis.atlas.domain.profile.LearnerProfile;
import de.tum.cit.aet.artemis.communication.domain.push_notification.PushNotificationDeviceConfiguration;
import de.tum.cit.aet.artemis.core.config.Constants;
import de.tum.cit.aet.artemis.core.exception.AccessForbiddenException;
Expand Down Expand Up @@ -224,6 +226,10 @@ public class User extends AbstractAuditingEntity implements Participant {
@Column(name = "iris_accepted")
private ZonedDateTime irisAccepted = null;

@OneToOne(mappedBy = "user", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE, orphanRemoval = true)
@JsonIgnoreProperties("user")
private LearnerProfile learnerProfile;

public User() {
}

Expand Down Expand Up @@ -566,4 +572,12 @@ public String getSshPublicKey() {
public @Size(max = 100) String getSshPublicKeyHash() {
return sshPublicKeyHash;
}

public LearnerProfile getLearnerProfile() {
return learnerProfile;
}

public void setLearnerProfile(LearnerProfile learnerProfile) {
this.learnerProfile = learnerProfile;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ OR LOWER(user.login) = LOWER(:searchInput)
@EntityGraph(type = LOAD, attributePaths = { "groups", "authorities" })
Set<User> findAllWithGroupsAndAuthoritiesByIsDeletedIsFalseAndGroupsContains(String groupName);

@EntityGraph(type = LOAD, attributePaths = { "groups", "authorities", "learnerProfile" })
Set<User> findAllWithGroupsAndAuthoritiesAndLearnerProfileByIsDeletedIsFalseAndGroupsContains(String groupName);

@Query("""
SELECT DISTINCT user
FROM User user
Expand Down Expand Up @@ -1005,6 +1008,16 @@ default Set<User> getStudents(Course course) {
return findAllWithGroupsAndAuthoritiesByIsDeletedIsFalseAndGroupsContains(course.getStudentGroupName());
}

/**
* Get students by given course with their learner Profile
*
* @param course object
* @return students for given course
*/
default Set<User> getStudentsWithLearnerProfile(Course course) {
return findAllWithGroupsAndAuthoritiesAndLearnerProfileByIsDeletedIsFalseAndGroupsContains(course.getStudentGroupName());
}

/**
* Get tutors by given course
*
Expand Down
Loading

0 comments on commit 1eb6786

Please sign in to comment.