Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 시간표 조회 API 이수 구분 반환 추가 #1150

Merged
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
@@ -0,0 +1,20 @@
package in.koreatech.koin.domain.graduation.exception;

import in.koreatech.koin.global.exception.DataNotFoundException;

public class CatalogNotFoundException extends DataNotFoundException {

private static final String DEFAULT_MESSAGE = "존재하지 않는 대학 요람입니다.";

protected CatalogNotFoundException(String message) {
super(message);
}

protected CatalogNotFoundException(String message, String detail) {
super(message, detail);
}

public static CatalogNotFoundException withDetail(String detail) {
return new CatalogNotFoundException(DEFAULT_MESSAGE, detail);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package in.koreatech.koin.domain.graduation.exception;

import in.koreatech.koin.global.exception.DataNotFoundException;

public class CourseTypeNotFoundException extends DataNotFoundException {

private static final String DEFAULT_MESSAGE = "존재하지 않는 이수 구분입니다.";

protected CourseTypeNotFoundException(String message) {
super(message);
}

protected CourseTypeNotFoundException(String message, String detail) {
super(message, detail);
}

public static CourseTypeNotFoundException withDetail(String detail) {
return new CourseTypeNotFoundException(DEFAULT_MESSAGE, detail);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package in.koreatech.koin.domain.graduation.exception;

import in.koreatech.koin.global.exception.DataNotFoundException;

public class DepartmentNotFoundException extends DataNotFoundException {

private static final String DEFAULT_MESSAGE = "존재하지 않는 학과입니다.";

protected DepartmentNotFoundException(String message) {
super(message);
}

protected DepartmentNotFoundException(String message, String detail) {
super(message, detail);
}

public static DepartmentNotFoundException withDetail(String detail) {
return new DepartmentNotFoundException(DEFAULT_MESSAGE, detail);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package in.koreatech.koin.domain.graduation.repository;

import java.util.Optional;

import org.springframework.data.repository.Repository;

import in.koreatech.koin.domain.graduation.exception.CatalogNotFoundException;
import in.koreatech.koin.domain.graduation.model.Catalog;
import in.koreatech.koin.domain.graduation.model.Department;

public interface CatalogRepository extends Repository<Catalog, Integer> {
Optional<Catalog> findByYearAndDepartmentAndCode(String year, Department department, String code);

default Catalog getByYearAndDepartmentAndCode(String year, Department department, String code) {
return findByYearAndDepartmentAndCode(year, department, code)
.orElseThrow(() -> CatalogNotFoundException.withDetail(
"year: " + year + ", department: " + department + ", code: " + code));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package in.koreatech.koin.domain.graduation.repository;

import java.util.Optional;

import org.springframework.data.repository.Repository;

import in.koreatech.koin.domain.graduation.exception.CourseTypeNotFoundException;
import in.koreatech.koin.domain.graduation.model.CourseType;

public interface CourseTypeRepository extends Repository<CourseType, Integer> {

CourseType save(CourseType courseType);

Optional<CourseType> findById(Integer id);

default CourseType getCourseTypeById(Integer id) {
return findById(id)
.orElseThrow(() -> CourseTypeNotFoundException.withDetail("course_type_id: " + id));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package in.koreatech.koin.domain.graduation.repository;

import java.util.Optional;

import org.springframework.data.repository.Repository;

import in.koreatech.koin.domain.graduation.exception.DepartmentNotFoundException;
import in.koreatech.koin.domain.graduation.model.Department;

public interface DepartmentRepository extends Repository<Department, Integer> {
Optional<Department> findByName(String name);

default Department getByName(String name) {
return findByName(name)
.orElseThrow(() -> DepartmentNotFoundException.withDetail("name: " + name));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.fasterxml.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;

import in.koreatech.koin.domain.graduation.model.CourseType;
import in.koreatech.koin.domain.timetable.model.Lecture;
import in.koreatech.koin.domain.timetableV2.exception.TimetableLectureClassTimeNullException;
import in.koreatech.koin.domain.timetableV2.model.TimetableFrame;
Expand Down Expand Up @@ -91,11 +92,13 @@ public TimetableLecture toTimetableLecture(TimetableFrame timetableFrame) {
memo,
false,
null,
timetableFrame
timetableFrame,
null
);
}

public TimetableLecture toTimetableLecture(TimetableFrame timetableFrame, Lecture lecture) {
public TimetableLecture toTimetableLecture(TimetableFrame timetableFrame, Lecture lecture,
CourseType courseType) {
return new TimetableLecture(
classTitle,
getClassTimeToString(),
Expand All @@ -105,7 +108,8 @@ public TimetableLecture toTimetableLecture(TimetableFrame timetableFrame, Lectur
memo,
false,
lecture,
timetableFrame
timetableFrame,
courseType
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ public record InnerTimetableLectureResponse(
String professor,

@Schema(description = "학부", example = "디자인ㆍ건축공학부", requiredMode = NOT_REQUIRED)
String department
String department,

@Schema(description = "이수 구분", example = "전공필수", requiredMode = NOT_REQUIRED)
String courseType
) {
@JsonNaming(value = SnakeCaseStrategy.class)
public record ClassInfo(
Expand Down Expand Up @@ -156,6 +159,7 @@ public static List<InnerTimetableLectureResponse> from(List<TimetableLecture> ti
null,
null,
timetableLecture.getProfessor(),
null,
null
);
} else {
Expand All @@ -172,7 +176,8 @@ public static List<InnerTimetableLectureResponse> from(List<TimetableLecture> ti
lecture.getLectureClass(),
lecture.getTarget(),
getProfessor(timetableLecture, lecture),
lecture.getDepartment()
lecture.getDepartment(),
timetableLecture.getCourseType().getName()
);
}
timetableLectureList.add(response);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
package in.koreatech.koin.domain.timetableV2.factory;

import static in.koreatech.koin.domain.timetableV2.dto.request.TimetableLectureCreateRequest.*;
import static in.koreatech.koin.domain.timetableV2.dto.request.TimetableLectureCreateRequest.InnerTimeTableLectureRequest;

import org.springframework.stereotype.Component;

import in.koreatech.koin.domain.graduation.model.Catalog;
import in.koreatech.koin.domain.graduation.model.CourseType;
import in.koreatech.koin.domain.graduation.model.Department;
import in.koreatech.koin.domain.graduation.repository.CatalogRepository;
import in.koreatech.koin.domain.graduation.repository.DepartmentRepository;
import in.koreatech.koin.domain.student.model.Student;
import in.koreatech.koin.domain.student.repository.StudentRepository;
import in.koreatech.koin.domain.student.util.StudentUtil;
import in.koreatech.koin.domain.timetable.model.Lecture;
import in.koreatech.koin.domain.timetableV2.dto.request.TimetableLectureCreateRequest;
import in.koreatech.koin.domain.timetableV2.model.TimetableFrame;
Expand All @@ -18,16 +26,36 @@ public class TimetableLectureCreator {

private final LectureRepositoryV2 lectureRepositoryV2;
private final TimetableLectureRepositoryV2 timetableLectureRepositoryV2;
private final CatalogRepository catalogRepository;
private final DepartmentRepository departmentRepository;
private final StudentRepository studentRepository;

public void createTimetableLectures(TimetableLectureCreateRequest request, TimetableFrame frame) {
public void createTimetableLectures(TimetableLectureCreateRequest request, Integer userId, TimetableFrame frame) {
for (InnerTimeTableLectureRequest lectureRequest : request.timetableLecture()) {
Lecture lecture = determineLecture(lectureRequest.lectureId());
TimetableLecture timetableLecture = lectureRequest.toTimetableLecture(frame, lecture);
CourseType courseType = determineCourseType(lecture, userId);
TimetableLecture timetableLecture = lectureRequest.toTimetableLecture(frame, lecture, courseType);
frame.addTimeTableLecture(timetableLecture);
timetableLectureRepositoryV2.save(timetableLecture);
}
}

private CourseType determineCourseType(Lecture lecture, Integer userId) {
if (lecture != null) {
return getCourseType(userId, lecture);
}
return null;
}

private CourseType getCourseType(Integer userId, Lecture lecture) {
Student student = studentRepository.getById(userId);
String year = StudentUtil.parseStudentNumberYear(student.getStudentNumber()).toString();
Department department = departmentRepository.getByName(student.getDepartment());
String code = lecture.getCode();
Catalog catalog = catalogRepository.getByYearAndDepartmentAndCode(year, department, code);
return catalog.getCourseType();
}

private Lecture determineLecture(Integer lectureId) {
if (lectureId != null) {
return lectureRepositoryV2.getLectureById(lectureId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import org.hibernate.annotations.Where;

import in.koreatech.koin.domain.graduation.model.CourseType;
import in.koreatech.koin.domain.timetable.dto.TimetableUpdateRequest;
import in.koreatech.koin.domain.timetable.model.Lecture;
import in.koreatech.koin.global.domain.BaseEntity;
Expand Down Expand Up @@ -71,9 +72,14 @@ public class TimetableLecture extends BaseEntity {
@JoinColumn(name = "frame_id")
private TimetableFrame timetableFrame;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "course_type_id")
private CourseType courseType;

@Builder
public TimetableLecture(String classTitle, String classTime, String classPlace, String professor,
String grades, String memo, boolean isDeleted, Lecture lecture, TimetableFrame timetableFrame) {
String grades, String memo, boolean isDeleted, Lecture lecture, TimetableFrame timetableFrame,
CourseType courseType) {
this.classTitle = classTitle;
this.classTime = classTime;
this.classPlace = classPlace;
Expand All @@ -83,6 +89,7 @@ public TimetableLecture(String classTitle, String classTime, String classPlace,
this.isDeleted = isDeleted;
this.lecture = lecture;
this.timetableFrame = timetableFrame;
this.courseType = courseType;
}

public void update(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class TimetableLectureService {
public TimetableLectureResponse createTimetableLectures(Integer userId, TimetableLectureCreateRequest request) {
TimetableFrame frame = timetableFrameRepositoryV2.getById(request.timetableFrameId());
validateUserAuthorization(frame.getUser().getId(), userId);
timetableLectureCreator.createTimetableLectures(request, frame);
timetableLectureCreator.createTimetableLectures(request, userId, frame);
return getTimetableLectureResponse(userId, frame);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ void setup() {
Lecture 건축구조의_이해_및_실습 = lectureFixture.건축구조의_이해_및_실습(semester.getSemester());
Lecture HRD_개론 = lectureFixture.HRD_개론(semester.getSemester());

timetableV2Fixture.시간표6(user, semester, 건축구조의_이해_및_실습, HRD_개론);
timetableV2Fixture.시간표6(user, semester, 건축구조의_이해_및_실습, HRD_개론, null, null);

mockMvc.perform(
get("/timetables")
Expand Down Expand Up @@ -324,8 +324,8 @@ void setup() {
Semester semester2 = semesterFixture.semester("20201");
Lecture HRD_개론 = lectureFixture.HRD_개론(semester1.getSemester());
Lecture 건축구조의_이해_및_실습 = lectureFixture.건축구조의_이해_및_실습(semester2.getSemester());
timetableV2Fixture.시간표6(user, semester1, HRD_개론, null);
timetableV2Fixture.시간표6(user, semester2, 건축구조의_이해_및_실습, null);
timetableV2Fixture.시간표6(user, semester1, HRD_개론, null, null, null);
timetableV2Fixture.시간표6(user, semester2, 건축구조의_이해_및_실습, null, null, null);

mockMvc.perform(
get("/semesters/check")
Expand Down Expand Up @@ -553,7 +553,7 @@ void setup() {
Lecture 건축구조의_이해_및_실습 = lectureFixture.건축구조의_이해_및_실습(semester.getSemester());
Lecture HRD_개론 = lectureFixture.HRD_개론(semester.getSemester());

timetableV2Fixture.시간표6(user, semester, 건축구조의_이해_및_실습, HRD_개론);
timetableV2Fixture.시간표6(user, semester, 건축구조의_이해_및_실습, HRD_개론, null, null);

mockMvc.perform(
delete("/timetable")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
import org.springframework.transaction.annotation.Transactional;

import in.koreatech.koin.AcceptanceTest;
import in.koreatech.koin.domain.graduation.model.CourseType;
import in.koreatech.koin.domain.timetable.model.Lecture;
import in.koreatech.koin.domain.timetable.model.Semester;
import in.koreatech.koin.domain.timetableV2.model.TimetableFrame;
import in.koreatech.koin.domain.timetableV2.repository.TimetableFrameRepositoryV2;
import in.koreatech.koin.domain.timetableV2.repository.TimetableLectureRepositoryV2;
import in.koreatech.koin.domain.user.model.User;
import in.koreatech.koin.fixture.CourseTypeFixture;
import in.koreatech.koin.fixture.LectureFixture;
import in.koreatech.koin.fixture.SemesterFixture;
import in.koreatech.koin.fixture.TimeTableV2Fixture;
Expand Down Expand Up @@ -48,6 +50,9 @@ public class TimetableFrameApiTest extends AcceptanceTest {
@Autowired
private TimetableLectureRepositoryV2 timetableLectureRepositoryV2;

@Autowired
private CourseTypeFixture courseTypeFixture;

private User user;
private String token;
private Semester semester;
Expand Down Expand Up @@ -165,8 +170,8 @@ void setup() {
@Test
void 강의를_담고_있는_특정_시간표_frame을_삭제한다() throws Exception {
Lecture lecture = lectureFixture.HRD_개론(semester.getSemester());

TimetableFrame frame1 = timetableV2Fixture.시간표5(user, semester, lecture);
CourseType courseType = courseTypeFixture.HRD_필수();
TimetableFrame frame1 = timetableV2Fixture.시간표5(user, semester, lecture, courseType);

mockMvc.perform(
delete("/v2/timetables/frame")
Expand Down
Loading
Loading