Skip to content
Snippets Groups Projects
Commit 0df5fa1b authored by Ester Vilímková's avatar Ester Vilímková
Browse files

Merge branch 'M2-language-school-course-lecture' into 'M2'

M2 language school course lecture

See merge request !20
parents ffe59998 c9cb7d2c
No related branches found
No related tags found
3 merge requests!31M2,!27Draft: M2 user,!20M2 language school course lecture
Pipeline #
Showing
with 501 additions and 87 deletions
...@@ -28,10 +28,10 @@ public class CourseCreateDto { ...@@ -28,10 +28,10 @@ public class CourseCreateDto {
@NotNull(message = "Language type is required") @NotNull(message = "Language type is required")
@Valid @Valid
private LanguageTypeDto languageTypeDto; private LanguageTypeDto language;
@NotNull(message = "Proficiency level is required") @NotNull(message = "Proficiency level is required")
@Valid @Valid
private ProficiencyLevelDto proficiencyLevelDto; private ProficiencyLevelDto proficiency;
} }
...@@ -20,7 +20,7 @@ import java.util.List; ...@@ -20,7 +20,7 @@ import java.util.List;
*/ */
@Getter @Getter
@Setter @Setter
@EqualsAndHashCode @EqualsAndHashCode(callSuper = true)
public class CourseDto extends DomainObjectDto { public class CourseDto extends DomainObjectDto {
@NotBlank(message = "Course name is required") @NotBlank(message = "Course name is required")
...@@ -33,22 +33,22 @@ public class CourseDto extends DomainObjectDto { ...@@ -33,22 +33,22 @@ public class CourseDto extends DomainObjectDto {
@NotNull(message = "Language type is required") @NotNull(message = "Language type is required")
@Valid @Valid
private LanguageTypeDto languageTypeDto; private LanguageTypeDto language;
@NotNull(message = "Proficiency level is required") @NotNull(message = "Proficiency level is required")
@Valid @Valid
private ProficiencyLevelDto proficiencyLevelDto; private ProficiencyLevelDto proficiency;
@NotNull(message = "Student's list is required") @NotNull(message = "Student's list is required")
@Valid @Valid
private List<String> studentIds; private List<Long> studentIds;
public CourseDto(String name, Integer capacity, LanguageTypeDto languageTypeDto, ProficiencyLevelDto proficiencyLevelDto) { public CourseDto(Long id, String name, Integer capacity, LanguageTypeDto languageTypeDto, ProficiencyLevelDto proficiencyLevelDto) {
setId(0L); this.setId(id);
this.name = name; this.name = name;
this.capacity = capacity; this.capacity = capacity;
this.languageTypeDto = languageTypeDto; this.language = languageTypeDto;
this.proficiencyLevelDto = proficiencyLevelDto; this.proficiency = proficiencyLevelDto;
this.studentIds = new ArrayList<>(); this.studentIds = new ArrayList<>();
} }
} }
...@@ -3,7 +3,6 @@ package org.fuseri.model.dto.lecture; ...@@ -3,7 +3,6 @@ package org.fuseri.model.dto.lecture;
import jakarta.validation.constraints.*; import jakarta.validation.constraints.*;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.fuseri.model.dto.course.CourseDto;
import java.time.LocalDateTime; import java.time.LocalDateTime;
...@@ -27,10 +26,10 @@ public class LectureCreateDto { ...@@ -27,10 +26,10 @@ public class LectureCreateDto {
@Min(value = 1, message = "Lecture capacity must be at least 1") @Min(value = 1, message = "Lecture capacity must be at least 1")
private Integer capacity; private Integer capacity;
@NotBlank(message = "Lecture course cannot be blank") @NotNull(message = "Lecture course cannot be null")
private String courseId; private Long courseId;
public LectureCreateDto(LocalDateTime from, LocalDateTime to, String topic, Integer capacity, String courseId) { public LectureCreateDto(LocalDateTime from, LocalDateTime to, String topic, Integer capacity, Long courseId) {
this.from = from; this.from = from;
this.to = to; this.to = to;
this.topic = topic; this.topic = topic;
......
...@@ -29,16 +29,16 @@ public class LectureDto extends DomainObjectDto { ...@@ -29,16 +29,16 @@ public class LectureDto extends DomainObjectDto {
@Min(value = 1, message = "Lecture capacity must be at least 1") @Min(value = 1, message = "Lecture capacity must be at least 1")
private Integer capacity; private Integer capacity;
@NotNull(message = "Lecture capacity cannot be null") @NotNull(message = "Lecture lecturer cannot be null")
private String lecturerId; private Long lecturerId;
@NotBlank(message = "Lecture courseId cannot be blank") @NotNull(message = "Lecture courseId cannot be null")
private String courseId; private Long courseId;
@NotNull(message = "Student IDs list cannot be null") @NotNull(message = "Student IDs list cannot be null")
private List<String> studentIds; private List<Long> studentIds;
public LectureDto(LocalDateTime from, LocalDateTime to, String topic, Integer capacity, String lecturerId, String courseId) { public LectureDto(LocalDateTime from, LocalDateTime to, String topic, Integer capacity, Long lecturerId, Long courseId) {
this.from = from; this.from = from;
this.to = to; this.to = to;
this.topic = topic; this.topic = topic;
......
package org.fuseri.model.dto.user; package org.fuseri.model.dto.user;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import org.fuseri.model.dto.common.DomainObjectDto;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.fuseri.model.dto.common.DomainObjectDto;
@Getter @Getter
@Setter @Setter
......
...@@ -59,8 +59,17 @@ ...@@ -59,8 +59,17 @@
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.6.9</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
......
package org.fuseri.modulelanguageschool.common; package org.fuseri.modulelanguageschool.common;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.MappedSuperclass; import jakarta.persistence.MappedSuperclass;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.UUID;
@Getter @Getter
@Setter @Setter
@MappedSuperclass @MappedSuperclass
public abstract class DomainObject { public abstract class DomainObject {
@Id @Id
private String id = UUID.randomUUID().toString(); @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
} }
...@@ -10,7 +10,7 @@ public abstract class DomainService<T extends DomainObject> { ...@@ -10,7 +10,7 @@ public abstract class DomainService<T extends DomainObject> {
public static final int DEFAULT_PAGE_SIZE = 10; public static final int DEFAULT_PAGE_SIZE = 10;
public abstract JpaRepository<T, String> getRepository(); public abstract JpaRepository<T, Long> getRepository();
@Transactional @Transactional
public T create(T entity) { public T create(T entity) {
......
package org.fuseri.modulelanguageschool.common;
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException() {
}
public ResourceNotFoundException(String message) {
super(message);
}
public ResourceNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public ResourceNotFoundException(Throwable cause) {
super(cause);
}
public ResourceNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
package org.fuseri.modulelanguageschool.course; package org.fuseri.modulelanguageschool.course;
import jakarta.persistence.Entity; import jakarta.persistence.*;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import lombok.*; import lombok.*;
import org.fuseri.modulelanguageschool.common.DomainObject; import org.fuseri.modulelanguageschool.common.DomainObject;
import org.fuseri.modulelanguageschool.user.User;
import java.util.List;
import java.util.Set;
@Getter @Getter
@Setter @Setter
@Entity
@Table(name = "course")
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class Course extends DomainObject { public class Course extends DomainObject {
...@@ -19,5 +23,16 @@ public class Course extends DomainObject { ...@@ -19,5 +23,16 @@ public class Course extends DomainObject {
private Language language; private Language language;
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
private ProficiencyLevel proficiencyLevel; private ProficiencyLevel proficiency;
@ManyToMany
private Set<User> students;
public void enrolStudent(User student) {
students.add(student);
}
public void expelStudent(User student) {
students.remove(student);
}
} }
package org.fuseri.modulelanguageschool.course; package org.fuseri.modulelanguageschool.course;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import jakarta.validation.constraints.PositiveOrZero;
import org.fuseri.model.dto.course.CourseCreateDto; import org.fuseri.model.dto.course.CourseCreateDto;
import org.fuseri.model.dto.course.CourseDto; import org.fuseri.model.dto.course.CourseDto;
import org.fuseri.model.dto.course.LanguageTypeDto; import org.fuseri.model.dto.course.LanguageTypeDto;
import org.fuseri.model.dto.course.ProficiencyLevelDto; import org.fuseri.model.dto.course.ProficiencyLevelDto;
import org.fuseri.model.dto.user.UserDto; import org.fuseri.model.dto.user.UserDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* This class represents a RESTful controller for Courses resources. * This class represents a RESTful controller for Courses resources.
* It handles incoming HTTP requests related to courses, and delegates them to the appropriate service method. * It handles incoming HTTP requests related to courses, and delegates them to the appropriate service method.
*/ */
@Api(tags = "Course Controller")
@RestController @RestController
@RequestMapping("/courses") @RequestMapping("/courses")
public class CourseController { public class CourseController {
public static final String COURSE_NAME = "english b2 course"; private final CourseFacade courseFacade;
@Autowired
public CourseController(CourseFacade courseFacade) {
this.courseFacade = courseFacade;
}
/** /**
* Creates a new course. * Creates a new course.
...@@ -28,9 +38,10 @@ public class CourseController { ...@@ -28,9 +38,10 @@ public class CourseController {
* @param dto the CourseCreateDto containing the course data * @param dto the CourseCreateDto containing the course data
* @return the newly created CourseDto * @return the newly created CourseDto
*/ */
@PostMapping("/create") @ApiOperation(value = "Create a new course")
@PostMapping
public CourseDto create(@Valid @RequestBody CourseCreateDto dto) { public CourseDto create(@Valid @RequestBody CourseCreateDto dto) {
return new CourseDto(dto.getName(), dto.getCapacity(), dto.getLanguageTypeDto(), dto.getProficiencyLevelDto()); return courseFacade.create(dto);
} }
/** /**
...@@ -39,9 +50,10 @@ public class CourseController { ...@@ -39,9 +50,10 @@ public class CourseController {
* @param id the ID of the course to retrieve * @param id the ID of the course to retrieve
* @return the CourseDto for the specified ID * @return the CourseDto for the specified ID
*/ */
@ApiOperation(value = "Retrieve a course by ID")
@GetMapping("/find/{id}") @GetMapping("/find/{id}")
public CourseDto find(@PathVariable String id) { public CourseDto find(@PathVariable Long id) {
return new CourseDto(COURSE_NAME, 10, LanguageTypeDto.ENGLISH, ProficiencyLevelDto.B2); return courseFacade.findById(id);
} }
/** /**
...@@ -50,36 +62,36 @@ public class CourseController { ...@@ -50,36 +62,36 @@ public class CourseController {
* @param page the page number to retrieve * @param page the page number to retrieve
* @return the Result containing the requested page of CourseDtos * @return the Result containing the requested page of CourseDtos
*/ */
@ApiOperation(value = "Retrieve a paginated list of courses")
@GetMapping("/findAll") @GetMapping("/findAll")
public List<CourseDto> findAll(@RequestParam int page) { public Page<CourseDto> findAll(@RequestParam int page) {
return new ArrayList<>(); return courseFacade.findAll(PageRequest.of(page, 10, Sort.by(Sort.Direction.ASC, "name")));
} }
/** /**
* Retrieves a paginated list of courses of a given language * Retrieves a paginated list of courses of a given language
* *
* @param page the page number to retrieve
* @param lang the language to find courses of * @param lang the language to find courses of
* @return the Result containing the requested page of CourseDtos * @return the Result containing the requested page of CourseDtos
*/ */
@ApiOperation(value = "Retrieve a paginated list of courses of a given language")
@GetMapping("/findAllByLang") @GetMapping("/findAllByLang")
public List<CourseDto> findAll(@RequestParam int page, @RequestParam LanguageTypeDto lang) { public List<CourseDto> findAll(@RequestParam LanguageTypeDto lang) {
return new ArrayList<>(); return courseFacade.findAll(lang);
} }
/** /**
* Retrieves a paginated list of courses of a given language and proficiency * Retrieves a paginated list of courses of a given language and proficiency
* *
* @param page the page number to retrieve
* @param lang the language to find courses of * @param lang the language to find courses of
* @param prof the proficiency of the language * @param prof the proficiency of the language
* @return the Result containing the requested page of CourseDtos * @return the Result containing the requested page of CourseDtos
*/ */
@ApiOperation(value = "Retrieve a paginated list of courses of a given language and proficiency")
@GetMapping("/findAllByLangProf") @GetMapping("/findAllByLangProf")
public List<CourseDto> findAll(@RequestParam int page, public List<CourseDto> findAll(@RequestParam LanguageTypeDto lang,
@RequestParam LanguageTypeDto lang,
@RequestParam ProficiencyLevelDto prof) { @RequestParam ProficiencyLevelDto prof) {
return new ArrayList<>(); return courseFacade.findAll(lang, prof);
} }
/** /**
...@@ -89,19 +101,21 @@ public class CourseController { ...@@ -89,19 +101,21 @@ public class CourseController {
* @param dto the CourseCreateDto containing the updated course data * @param dto the CourseCreateDto containing the updated course data
* @return the updated CourseDto * @return the updated CourseDto
*/ */
@ApiOperation(value = "Update an existing course")
@PutMapping("/update/{id}") @PutMapping("/update/{id}")
public CourseDto update(@PathVariable String id, @Valid @RequestBody CourseCreateDto dto) { public CourseDto update(@PathVariable Long id, @Valid @RequestBody CourseCreateDto dto) {
return new CourseDto(dto.getName(), dto.getCapacity(), dto.getLanguageTypeDto(), dto.getProficiencyLevelDto()); return courseFacade.update(id, dto);
} }
/** /**
* Deletes a course by ID. * Deletes a course by ID.
* *
* @param id the ID of the course to delete * @param id the ID of the course to delete
* @return true if the course was successfully deleted, false otherwise
*/ */
@ApiOperation(value = "Delete a course by ID")
@DeleteMapping("/delete/{id}") @DeleteMapping("/delete/{id}")
public void delete(@PathVariable String id) { public void delete(@PathVariable Long id) {
courseFacade.delete(id);
} }
...@@ -112,11 +126,10 @@ public class CourseController { ...@@ -112,11 +126,10 @@ public class CourseController {
* @param student UserDto for the student * @param student UserDto for the student
* @return the CourseDto representing the updated course * @return the CourseDto representing the updated course
*/ */
@ApiOperation(value = "Add student to the existing course")
@PatchMapping("/enrol/{id}") @PatchMapping("/enrol/{id}")
public CourseDto enrol(@PathVariable String id, @RequestBody UserDto student) { public CourseDto enrol(@PathVariable Long id, @RequestBody UserDto student) {
var course = new CourseDto(COURSE_NAME, 10, LanguageTypeDto.ENGLISH, ProficiencyLevelDto.B2); return courseFacade.enrol(id, student);
course.setStudentIds(new ArrayList<>(List.of(student.getId())));
return course;
} }
/** /**
...@@ -126,9 +139,10 @@ public class CourseController { ...@@ -126,9 +139,10 @@ public class CourseController {
* @param student UserDto for the student * @param student UserDto for the student
* @return the CourseDto representing the updated course * @return the CourseDto representing the updated course
*/ */
@ApiOperation(value = "Remove student from the existing course")
@PatchMapping("/expel/{id}") @PatchMapping("/expel/{id}")
public CourseDto expel(@PathVariable String id, @RequestBody UserDto student) { public CourseDto expel(@PathVariable Long id, @RequestBody UserDto student) {
return new CourseDto(COURSE_NAME, 10, LanguageTypeDto.ENGLISH, ProficiencyLevelDto.B2); return courseFacade.expel(id, student);
} }
} }
package org.fuseri.modulelanguageschool.course;
import org.fuseri.model.dto.course.CourseCreateDto;
import org.fuseri.model.dto.course.CourseDto;
import org.fuseri.model.dto.course.LanguageTypeDto;
import org.fuseri.model.dto.course.ProficiencyLevelDto;
import org.fuseri.model.dto.user.UserDto;
import org.fuseri.modulelanguageschool.user.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional
public class CourseFacade {
private final CourseService courseService;
private final CourseMapper courseMapper;
private final UserMapper userMapper;
@Autowired
public CourseFacade(CourseService courseService, CourseMapper courseMapper, UserMapper userMapper) {
this.courseService = courseService;
this.courseMapper = courseMapper;
this.userMapper = userMapper;
}
@Transactional
public CourseDto create(CourseCreateDto dto) {
return courseMapper.mapToDto(courseService.save(courseMapper.mapToCourse(dto)));
}
@Cacheable(cacheNames = "courses", key = "#id")
@Transactional(readOnly = true)
public CourseDto findById(Long id) {
return courseMapper.mapToDto(courseService.findById(id));
}
@Transactional(readOnly = true)
public Page<CourseDto> findAll(Pageable pageable) {
return courseMapper.mapToPageDto(courseService.findAll(pageable));
}
@Transactional
public CourseDto update(Long id, CourseCreateDto dto) {
return courseMapper.mapToDto(courseService.update(id, courseMapper.mapToCourse(dto)));
}
@Transactional
public void delete(Long id) {
courseService.delete(id);
}
public List<CourseDto> findAll(LanguageTypeDto lang) {
return courseMapper.mapToList(courseService.findAll(Language.valueOf(lang.name())));
}
public List<CourseDto> findAll(LanguageTypeDto lang, ProficiencyLevelDto prof) {
return courseMapper.mapToList(courseService.findAll(Language.valueOf(lang.name()), ProficiencyLevel.valueOf(prof.name())));
}
public CourseDto enrol(Long id, UserDto student) {
return courseMapper.mapToDto(courseService.enrol(id, userMapper.fromDto(student)));
}
public CourseDto expel(Long id, UserDto student) {
return courseMapper.mapToDto(courseService.expel(id, userMapper.fromDto(student)));
}
}
package org.fuseri.modulelanguageschool.course;
import org.fuseri.model.dto.course.CourseCreateDto;
import org.fuseri.model.dto.course.CourseDto;
import org.mapstruct.Mapper;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import java.util.List;
@Mapper(componentModel = "spring")
public interface CourseMapper {
CourseDto mapToDto(Course course);
Course mapToCourse(CourseDto courseDto);
List<CourseDto> mapToList(List<Course> persons);
default Page<CourseDto> mapToPageDto(Page<Course> courses) {
return new PageImpl<>(mapToList(courses.getContent()), courses.getPageable(), courses.getTotalPages());
}
Course mapToCourse(CourseCreateDto dto);
}
package org.fuseri.modulelanguageschool.course;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface CourseRepository extends JpaRepository<Course, Long> {
@Query("SELECT c FROM Course c WHERE c.language = ?1")
List<Course> findAllByLang(Language language);
@Query("SELECT c FROM Course c WHERE c.language = ?1 AND c.proficiency = ?2")
List<Course> findAllByLangProf(Language language, ProficiencyLevel proficiencyLevel);
}
package org.fuseri.modulelanguageschool.course;
import org.fuseri.modulelanguageschool.common.ResourceNotFoundException;
import org.fuseri.modulelanguageschool.user.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Service
public class CourseService {
private final CourseRepository courseRepository;
@Autowired
public CourseService(CourseRepository courseRepository) {
this.courseRepository = courseRepository;
}
@Transactional
public Course save(Course course) {
return courseRepository.save(course);
}
@Transactional(readOnly = true)
public Course findById(Long id) {
return courseRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException("Course with id: " + id + " was not found."));
}
@Transactional(readOnly = true)
public Page<Course> findAll(Pageable pageable) {
return courseRepository.findAll(pageable);
}
@Transactional
public Course update(Long id, Course newCourse) {
Optional<Course> optionalCourse = courseRepository.findById(id);
if (optionalCourse.isPresent()) {
Course course = optionalCourse.get();
course.setName(newCourse.getName());
course.setCapacity(newCourse.getCapacity());
course.setLanguage(newCourse.getLanguage());
course.setProficiency(newCourse.getProficiency());
return courseRepository.save(course);
} else {
throw new ResourceNotFoundException("Course with id: " + id + " was not found.");
}
}
@Transactional
public void delete(Long id) {
courseRepository.deleteById(id);
}
public List<Course> findAll(Language language) {
return courseRepository.findAllByLang(language);
}
public List<Course> findAll(Language language, ProficiencyLevel proficiencyLevel) {
return courseRepository.findAllByLangProf(language, proficiencyLevel);
}
public Course enrol(Long id, User student) {
Optional<Course> optionalCourse = courseRepository.findById(id);
if (optionalCourse.isPresent()) {
Course course = optionalCourse.get();
course.enrolStudent(student);
return courseRepository.save(course);
} else {
throw new ResourceNotFoundException("Course with id: " + id + " was not found.");
}
}
public Course expel(Long id, User student) {
Optional<Course> optionalCourse = courseRepository.findById(id);
if (optionalCourse.isPresent()) {
Course course = optionalCourse.get();
course.expelStudent(student);
return courseRepository.save(course);
} else {
throw new ResourceNotFoundException("Course with id: " + id + " was not found.");
}
}
}
...@@ -3,6 +3,7 @@ package org.fuseri.modulelanguageschool.lecture; ...@@ -3,6 +3,7 @@ package org.fuseri.modulelanguageschool.lecture;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.ManyToMany; import jakarta.persistence.ManyToMany;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
...@@ -12,13 +13,15 @@ import org.fuseri.modulelanguageschool.course.Course; ...@@ -12,13 +13,15 @@ import org.fuseri.modulelanguageschool.course.Course;
import org.fuseri.modulelanguageschool.user.User; import org.fuseri.modulelanguageschool.user.User;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.Set;
/** /**
* This class represents a lecture entity in the domain model. * This class represents a lecture entity in the domain model.
*/ */
@Getter @Getter
@Setter @Setter
@Entity
@Table(name = "lecture")
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class Lecture extends DomainObject { public class Lecture extends DomainObject {
...@@ -27,9 +30,20 @@ public class Lecture extends DomainObject { ...@@ -27,9 +30,20 @@ public class Lecture extends DomainObject {
private LocalDateTime to; private LocalDateTime to;
private String topic; private String topic;
@ManyToOne
private Course course; private Course course;
@ManyToOne
private User lecturer; private User lecturer;
private List<User> user; @ManyToMany
private Set<User> students;
public void enrolStudent(User student) {
students.add(student);
}
public void expelStudent(User student) {
students.remove(student);
}
} }
package org.fuseri.modulelanguageschool.lecture; package org.fuseri.modulelanguageschool.lecture;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import org.fuseri.model.dto.course.CourseDto;
import org.fuseri.model.dto.lecture.LectureCreateDto; import org.fuseri.model.dto.lecture.LectureCreateDto;
import org.fuseri.model.dto.lecture.LectureDto; import org.fuseri.model.dto.lecture.LectureDto;
import org.fuseri.model.dto.user.UserDto; import org.fuseri.model.dto.user.UserDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.time.Month;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* This class represents a RESTful controller for Lecture resources. * This class represents a RESTful controller for Lecture resources.
* It handles incoming HTTP requests related to lectures, and delegates them to the appropriate service method. * It handles incoming HTTP requests related to lectures, and delegates them to the appropriate service method.
*/ */
@Api(tags = "Lecture Controller")
@RestController @RestController
@RequestMapping("/lectures") @RequestMapping("/lectures")
public class LectureController { public class LectureController {
private static final LocalDateTime START_DATETIME = LocalDateTime.of(2045, Month.JUNE, 30, 12, 0, 0); private final LectureFacade lectureFacade;
private static final LocalDateTime END_DATETIME = LocalDateTime.of(2045, Month.JUNE, 30, 14, 0, 0);
public static final String TOPIC = "Learning how to spell deprecated"; @Autowired
public LectureController(LectureFacade lectureFacade) {
this.lectureFacade = lectureFacade;
}
/** /**
* Creates a new lecture resource by delegating to the LectureService's create method. * Creates a new lecture resource by delegating to the LectureService's create method.
...@@ -30,20 +34,22 @@ public class LectureController { ...@@ -30,20 +34,22 @@ public class LectureController {
* @param lecture the LectureDto representing the lecture to be created * @param lecture the LectureDto representing the lecture to be created
* @return the LectureDto representing the newly created lecture * @return the LectureDto representing the newly created lecture
*/ */
@PostMapping("/create") @ApiOperation(value = "Create a new lecture")
@PostMapping
public LectureDto create(@Valid @RequestBody LectureCreateDto lecture) { public LectureDto create(@Valid @RequestBody LectureCreateDto lecture) {
return new LectureDto(START_DATETIME, END_DATETIME, TOPIC, 10, "0", "0"); return lectureFacade.create(lecture);
} }
/** /**
* Retrieves a lecture resource by its ID. * Retrieves a lecture resource by its ID.
* *
* @param id the ID of the lecture to find * @param courseId the ID of the lecture to find
* @return the LectureDto representing the found lecture * @return the LectureDto representing the found lecture
*/ */
@GetMapping("find/{id}") @ApiOperation(value = "Retrieve a lecture by its ID")
public LectureDto find(@PathVariable String id) { @GetMapping("find/{courseId}")
return new LectureDto(START_DATETIME, END_DATETIME, TOPIC, 10, "0", "0"); public LectureDto find(@PathVariable Long courseId) {
return lectureFacade.findById(courseId);
} }
/** /**
...@@ -52,9 +58,10 @@ public class LectureController { ...@@ -52,9 +58,10 @@ public class LectureController {
* @param courseId the course to retrieve lectures from * @param courseId the course to retrieve lectures from
* @return the list of LectureDtos * @return the list of LectureDtos
*/ */
@ApiOperation(value = "Retrieve a list of lectures for the corresponding course")
@GetMapping("/findByCourse") @GetMapping("/findByCourse")
public List<LectureDto> findByCourse(@Valid @RequestParam String courseId) { public List<LectureDto> findByCourse(@Valid @RequestParam Long courseId) {
return new ArrayList<>(); return lectureFacade.findAll(courseId);
} }
/** /**
...@@ -63,9 +70,10 @@ public class LectureController { ...@@ -63,9 +70,10 @@ public class LectureController {
* @param lecture the CourseCreateDto representing the updated lecture * @param lecture the CourseCreateDto representing the updated lecture
* @return the LectureDto representing the updated lecture * @return the LectureDto representing the updated lecture
*/ */
@ApiOperation(value = "Update an existing lecture")
@PutMapping("/update/{id}") @PutMapping("/update/{id}")
public LectureDto update(@PathVariable String id, @Valid @RequestBody LectureCreateDto lecture) { public LectureDto update(@PathVariable Long id, @Valid @RequestBody LectureCreateDto lecture) {
return new LectureDto(START_DATETIME, END_DATETIME, TOPIC, 10, "0", "0"); return lectureFacade.update(id, lecture);
} }
/** /**
...@@ -73,21 +81,24 @@ public class LectureController { ...@@ -73,21 +81,24 @@ public class LectureController {
* *
* @param id the ID of the lecture to delete * @param id the ID of the lecture to delete
*/ */
@ApiOperation(value = "Delete a lecture by its ID")
@DeleteMapping("/delete/{id}") @DeleteMapping("/delete/{id}")
public void delete(@PathVariable String id) { public void delete(@PathVariable Long id) {
lectureFacade.delete(id);
} }
/** /**
* Adds lecturer to the existing lecture resource * Adds lecturer to the existing lecture resource
* *
* @param id id of lecture to update * @param id id of lecture to update
* @param lecturer UserDto for the course lecturer * @param lecturerDto UserDto for the course lecturer
* @return the LectureDto representing the updated lecture * @return the LectureDto representing the updated lecture
*/ */
@ApiOperation(value = "Add lecturer to the existing lecture")
@PatchMapping("/setLecturer/{id}") @PatchMapping("/setLecturer/{id}")
public LectureDto setLecturer(@PathVariable String id, @RequestBody UserDto lecturer) { public LectureDto setLecturer(@PathVariable Long id, @RequestBody UserDto lecturerDto) {
return new LectureDto(START_DATETIME, END_DATETIME, TOPIC, 10, "0", "0"); return lectureFacade.setLecturer(id, lecturerDto);
} }
/** /**
...@@ -97,11 +108,10 @@ public class LectureController { ...@@ -97,11 +108,10 @@ public class LectureController {
* @param student UserDto for the course student * @param student UserDto for the course student
* @return the LectureDto representing the updated lecture * @return the LectureDto representing the updated lecture
*/ */
@ApiOperation(value = "Add student to the existing lecture")
@PatchMapping("/enrol/{id}") @PatchMapping("/enrol/{id}")
public LectureDto enrol(@PathVariable String id, @RequestBody UserDto student) { public LectureDto enrol(@PathVariable Long id, @RequestBody UserDto student) {
var lecture = new LectureDto(START_DATETIME, END_DATETIME, TOPIC, 10, "0", "0"); return lectureFacade.enrol(id, student);
lecture.setStudentIds(new ArrayList<>(List.of(student.getId())));
return lecture;
} }
/** /**
...@@ -111,8 +121,9 @@ public class LectureController { ...@@ -111,8 +121,9 @@ public class LectureController {
* @param student UserDto for the course student * @param student UserDto for the course student
* @return the LectureDto representing the updated lecture * @return the LectureDto representing the updated lecture
*/ */
@ApiOperation(value = "Remove student from the existing lecture")
@PatchMapping("/expel/{id}") @PatchMapping("/expel/{id}")
public LectureDto expel(@PathVariable String id, @RequestBody UserDto student) { public LectureDto expel(@PathVariable Long id, @RequestBody UserDto student) {
return new LectureDto(START_DATETIME, END_DATETIME, TOPIC, 10, "0", "0"); return lectureFacade.expel(id, student);
} }
} }
\ No newline at end of file
package org.fuseri.modulelanguageschool.lecture;
import org.fuseri.model.dto.course.LanguageTypeDto;
import org.fuseri.model.dto.course.ProficiencyLevelDto;
import org.fuseri.model.dto.lecture.LectureCreateDto;
import org.fuseri.model.dto.lecture.LectureDto;
import org.fuseri.model.dto.user.UserDto;
import org.fuseri.modulelanguageschool.course.Language;
import org.fuseri.modulelanguageschool.course.ProficiencyLevel;
import org.fuseri.modulelanguageschool.user.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional
public class LectureFacade {
private final LectureService lectureService;
private final LectureMapper lectureMapper;
private final UserMapper userMapper;
@Autowired
public LectureFacade(LectureService lectureService, LectureMapper lectureMapper, UserMapper userMapper) {
this.lectureService = lectureService;
this.lectureMapper = lectureMapper;
this.userMapper = userMapper;
}
@Transactional
public LectureDto create(LectureCreateDto dto) {
return lectureMapper.mapToDto(lectureService.save(lectureMapper.mapToLecture(dto)));
}
@Cacheable(cacheNames = "courses", key = "#id")
@Transactional(readOnly = true)
public LectureDto findById(Long id) {
return lectureMapper.mapToDto(lectureService.findById(id));
}
@Transactional(readOnly = true)
public List<LectureDto> findAll(Long id) {
return lectureMapper.mapToList(lectureService.findAllByCourse(id));
}
@Transactional
public LectureDto update(Long id, LectureCreateDto dto) {
return lectureMapper.mapToDto(lectureService.update(id, lectureMapper.mapToLecture(dto)));
}
@Transactional
public void delete(Long id) {
lectureService.delete(id);
}
public List<LectureDto> findAll(LanguageTypeDto lang) {
return lectureMapper.mapToList(lectureService.findAll(Language.valueOf(lang.name())));
}
public List<LectureDto> findAll(LanguageTypeDto lang, ProficiencyLevelDto prof) {
return lectureMapper.mapToList(lectureService.findAll(Language.valueOf(lang.name()), ProficiencyLevel.valueOf(prof.name())));
}
public LectureDto enrol(Long id, UserDto student) {
return lectureMapper.mapToDto(lectureService.enrol(id, userMapper.fromDto(student)));
}
public LectureDto expel(Long id, UserDto student) {
return lectureMapper.mapToDto(lectureService.expel(id, userMapper.fromDto(student)));
}
public LectureDto setLecturer(Long id, UserDto lecturerDto) {
return lectureMapper.mapToDto(lectureService.setLecturer(id, userMapper.fromDto(lecturerDto)));
}
}
package org.fuseri.modulelanguageschool.lecture;
import org.fuseri.model.dto.lecture.LectureCreateDto;
import org.fuseri.model.dto.lecture.LectureDto;
import org.mapstruct.Mapper;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import java.util.List;
@Mapper(componentModel = "spring")
public interface LectureMapper {
LectureDto mapToDto(Lecture lecture);
Lecture mapToLecture(LectureDto lectureDto);
List<LectureDto> mapToList(List<Lecture> lectures);
default Page<LectureDto> mapToPageDto(Page<Lecture> lectures) {
return new PageImpl<>(mapToList(lectures.getContent()), lectures.getPageable(), lectures.getTotalPages());
}
Lecture mapToLecture(LectureCreateDto dto);
}
package org.fuseri.modulelanguageschool.lecture;
import org.fuseri.modulelanguageschool.course.Language;
import org.fuseri.modulelanguageschool.course.ProficiencyLevel;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface LectureRepository extends JpaRepository<Lecture, Long> {
@Query("SELECT l FROM Lecture l WHERE l.course.id = ?1")
List<Lecture> findAllByCourse(Long id);
@Query("SELECT l FROM Lecture l WHERE l.course.language = ?1")
List<Lecture> findAllByLang(Language language);
@Query("SELECT l FROM Lecture l WHERE l.course.language = ?1 AND l.course.proficiency = ?2")
List<Lecture> findAllByLangProf(Language language, ProficiencyLevel proficiencyLevel);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment