diff --git a/src/main/java/classfit/example/classfit/calendarCategory/repository/CalendarCategoryRepository.java b/src/main/java/classfit/example/classfit/calendarCategory/repository/CalendarCategoryRepository.java index 89a2d3ef..986d126c 100644 --- a/src/main/java/classfit/example/classfit/calendarCategory/repository/CalendarCategoryRepository.java +++ b/src/main/java/classfit/example/classfit/calendarCategory/repository/CalendarCategoryRepository.java @@ -3,10 +3,10 @@ import classfit.example.classfit.calendarCategory.domain.CalendarCategory; import classfit.example.classfit.memberCalendar.domain.CalendarType; import classfit.example.classfit.memberCalendar.domain.MemberCalendar; -import java.util.Collection; import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; @Repository @@ -14,4 +14,9 @@ public interface CalendarCategoryRepository extends JpaRepository findByMemberCalendar(MemberCalendar memberCalendar); CalendarCategory findById(Optional aLong); + + @Query("SELECT c FROM CalendarCategory c " + + "WHERE c.memberCalendar.type = :type " + + "AND c.memberCalendar.member.academy.id = :academyId") + List findByMemberCalendarTypeAndAcademyId(CalendarType type, Long academyId); } diff --git a/src/main/java/classfit/example/classfit/calendarCategory/service/CalendarCategoryService.java b/src/main/java/classfit/example/classfit/calendarCategory/service/CalendarCategoryService.java index 8bfab974..0d6b625f 100644 --- a/src/main/java/classfit/example/classfit/calendarCategory/service/CalendarCategoryService.java +++ b/src/main/java/classfit/example/classfit/calendarCategory/service/CalendarCategoryService.java @@ -71,26 +71,37 @@ private boolean isDuplicateName(String name, Long categoryId) { @Transactional(readOnly = true) public CalendarCategoryListResponse getCategories(@AuthMember Member member) { MemberCalendar personalCalendar = getMemberCalendarByMemberAndType(member, CalendarType.PERSONAL); - MemberCalendar sharedCalendar = getMemberCalendarByMemberAndType(member, CalendarType.SHARED); - List personalCategories = classifyAndSortCategories(personalCalendar); - List sharedCategories = classifyAndSortCategories(sharedCalendar); + + List sharedCategories = classifyAndSortSharedCategories(member); return CalendarCategoryListResponse.of(personalCategories, sharedCategories); } private List classifyAndSortCategories(MemberCalendar memberCalendar) { - List typeCategories = calendarCategoryRepository.findByMemberCalendar(memberCalendar) + return calendarCategoryRepository.findByMemberCalendar(memberCalendar) .stream() .map(category -> CalendarCategoryResponse.of( category.getId(), category.getName(), category.getColor() )) + .sorted(Comparator.comparing(CalendarCategoryResponse::name)) .collect(Collectors.toList()); + } - typeCategories.sort(Comparator.comparing(CalendarCategoryResponse::name)); - return typeCategories; + private List classifyAndSortSharedCategories(Member member) { + Long academyId = member.getAcademy().getId(); + + return calendarCategoryRepository.findByMemberCalendarTypeAndAcademyId(CalendarType.SHARED, academyId) + .stream() + .map(category -> CalendarCategoryResponse.of( + category.getId(), + category.getName(), + category.getColor() + )) + .sorted(Comparator.comparing(CalendarCategoryResponse::name)) + .collect(Collectors.toList()); } @Transactional diff --git a/src/main/java/classfit/example/classfit/classStudent/repository/ClassStudentRepository.java b/src/main/java/classfit/example/classfit/classStudent/repository/ClassStudentRepository.java index daf33f72..3629e7e1 100644 --- a/src/main/java/classfit/example/classfit/classStudent/repository/ClassStudentRepository.java +++ b/src/main/java/classfit/example/classfit/classStudent/repository/ClassStudentRepository.java @@ -40,7 +40,16 @@ Page findAllByMainClassAndSubClass( List findByStudent(Student student); - List findBySubClass(SubClass subClass); + @Query("SELECT cs FROM ClassStudent cs " + + "JOIN cs.subClass sc " + + "JOIN sc.mainClass mc " + + "JOIN mc.academy a " + + "WHERE a.id = :academyId " + + "AND sc = :subClass") + List findByAcademyIdAndSubClass(@Param("academyId") Long academyId, + @Param("subClass") SubClass subClass); + + @Query("SELECT new classfit.example.classfit.scoreReport.dto.response.FindClassStudent(cs.student.id, cs.student.name) " + "FROM ClassStudent cs " + diff --git a/src/main/java/classfit/example/classfit/event/repository/EventRepository.java b/src/main/java/classfit/example/classfit/event/repository/EventRepository.java index 95279922..e33be306 100644 --- a/src/main/java/classfit/example/classfit/event/repository/EventRepository.java +++ b/src/main/java/classfit/example/classfit/event/repository/EventRepository.java @@ -17,11 +17,23 @@ public interface EventRepository extends JpaRepository { "WHERE e.memberCalendar.type = :calendarType " + "AND e.memberCalendar.member = :member " + "AND e.startDate BETWEEN :startOfMonth AND :endOfMonth") - List findByCalendarTypeAndStartDateBetween( + List findByPersonalCalendarTypeAndStartDateBetween( @Param("calendarType") CalendarType calendarType, @Param("startOfMonth") LocalDateTime startOfMonth, @Param("endOfMonth") LocalDateTime endOfMonth, @Param("member")Member member ); + + @Query("SELECT e FROM Event e " + + "WHERE e.memberCalendar.type = :calendarType " + + "AND e.memberCalendar.member.academy.id = :academyId " + + "AND e.startDate BETWEEN :startOfMonth AND :endOfMonth") + List findBySharedCalendarAndStartDateBetween( + @Param("calendarType") CalendarType calendarType, + @Param("startOfMonth") LocalDateTime startOfMonth, + @Param("endOfMonth") LocalDateTime endOfMonth, + @Param("academyId") Long academyId + ); + Optional findById(long eventId); } diff --git a/src/main/java/classfit/example/classfit/event/service/EventGetService.java b/src/main/java/classfit/example/classfit/event/service/EventGetService.java index a7fe8982..02fb01a3 100644 --- a/src/main/java/classfit/example/classfit/event/service/EventGetService.java +++ b/src/main/java/classfit/example/classfit/event/service/EventGetService.java @@ -2,6 +2,7 @@ import static classfit.example.classfit.common.exception.ClassfitException.EVENT_NOT_FOUND; +import classfit.example.classfit.academy.domain.Academy; import classfit.example.classfit.common.exception.ClassfitException; import classfit.example.classfit.event.domain.Event; import classfit.example.classfit.event.dto.response.EventModalResponse; @@ -39,7 +40,14 @@ public List getMonthlyEventsByCalendarType(CalendarType ca LocalDateTime startOfMonth = LocalDateTime.of(year, month, 1, 0, 0, 0, 0); LocalDateTime endOfMonth = startOfMonth.plusMonths(1).minusSeconds(1); - List events = eventRepository.findByCalendarTypeAndStartDateBetween(calendarType, startOfMonth, endOfMonth, member); + List events; + if (calendarType == CalendarType.SHARED) { + Long academyId = member.getAcademy().getId(); + events = eventRepository.findBySharedCalendarAndStartDateBetween(calendarType, startOfMonth, endOfMonth, academyId); + } else { + events = eventRepository.findByPersonalCalendarTypeAndStartDateBetween(calendarType, startOfMonth, endOfMonth, member); + } + return mapToEventCreateResponse(events); } diff --git a/src/main/java/classfit/example/classfit/scoreReport/domain/ScoreReport.java b/src/main/java/classfit/example/classfit/scoreReport/domain/ScoreReport.java index f8b9883d..48550e81 100644 --- a/src/main/java/classfit/example/classfit/scoreReport/domain/ScoreReport.java +++ b/src/main/java/classfit/example/classfit/scoreReport/domain/ScoreReport.java @@ -62,6 +62,7 @@ public class ScoreReport extends BaseEntity { private Boolean includeAverage; + @Builder public ScoreReport(SubClass subClass, MainClass mainClass, String reportName, Student student, String overallOpinion, LocalDate startDate, diff --git a/src/main/java/classfit/example/classfit/student/service/StudentService.java b/src/main/java/classfit/example/classfit/student/service/StudentService.java index 46fd2be9..ecf3cca0 100644 --- a/src/main/java/classfit/example/classfit/student/service/StudentService.java +++ b/src/main/java/classfit/example/classfit/student/service/StudentService.java @@ -51,26 +51,29 @@ public StudentResponse registerStudent(StudentRequest request) { classStudent.addSubClass(subClass); classStudentRepository.save(classStudent); - createAttendanceForThreeWeeks(student); + createAttendanceForSevenWeeks(student); }); return StudentResponse.from(student); } - private void createAttendanceForThreeWeeks(Student student) { + private void createAttendanceForSevenWeeks(Student student) { LocalDate currentDate = LocalDate.now(); - LocalDate weekStart = currentDate.with(DayOfWeek.MONDAY); + LocalDate weekStart = currentDate.with(DayOfWeek.MONDAY).minusWeeks(4); + List classStudents = classStudentRepository.findByStudent(student); classStudents.forEach(classStudent -> { - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 7; i++) { LocalDate weekDate = weekStart.plusWeeks(i); + AttendanceStatus status = (i < 4) ? AttendanceStatus.ABSENT : AttendanceStatus.PRESENT; // 4주 전은 ABSENT, 나머지는 PRESENT + for (int j = 0; j < 7; j++) { LocalDate attendanceDate = weekDate.plusDays(j); Attendance attendance = Attendance.builder() .date(attendanceDate) .week(j) - .status(AttendanceStatus.PRESENT) + .status(status) .student(student) .classStudent(classStudent) .build(); diff --git a/src/main/java/classfit/example/classfit/studentExam/domain/Exam.java b/src/main/java/classfit/example/classfit/studentExam/domain/Exam.java index 73eb6323..7fdcc9cc 100644 --- a/src/main/java/classfit/example/classfit/studentExam/domain/Exam.java +++ b/src/main/java/classfit/example/classfit/studentExam/domain/Exam.java @@ -35,6 +35,9 @@ public class Exam extends BaseEntity { @Column(name = "exam_id") private Long id; + @Column(name = "created_by") + private Long createdBy; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "sub_class_id", nullable = false) private SubClass subClass; @@ -112,6 +115,6 @@ public void updateHighestScore(Integer highestScore) { public void updateAverage(Integer newAverage) { this.average = newAverage.doubleValue(); } - + public void updateCreatedBy(Long createdBy) {this.createdBy = createdBy;} } diff --git a/src/main/java/classfit/example/classfit/studentExam/domain/ExamRepository.java b/src/main/java/classfit/example/classfit/studentExam/domain/ExamRepository.java index c2a27d7f..1a2383a3 100644 --- a/src/main/java/classfit/example/classfit/studentExam/domain/ExamRepository.java +++ b/src/main/java/classfit/example/classfit/studentExam/domain/ExamRepository.java @@ -13,16 +13,32 @@ public interface ExamRepository extends JpaRepository { "JOIN e.mainClass mc " + "JOIN mc.academy a " + "JOIN a.members m " + - "WHERE a.name = :academyName " + + "WHERE a.id = :academyId " + "AND m.name = :memberName") - List findByAcademyAndMemberName(@Param("academyName") String academyName, + List findByAcademyIdAndMemberName(@Param("academyId") Long academyId, @Param("memberName") String memberName); - List findByExamName(String examName); + @Query("SELECT e FROM Exam e " + + "JOIN e.mainClass mc " + + "JOIN mc.academy a " + + "WHERE a.id = :academyId " + + "AND e.examName = :examName") + List findByAcademyIdAndExamName(@Param("academyId") Long academyId, + @Param("examName") String examName); + @Query("SELECT e FROM Exam e WHERE e.mainClass.academy.id = :academyId ORDER BY e.id ASC") List findAllByAcademyId(@Param("academyId") Long academyId); - List findByMainClassIdAndSubClassId(Long mainClassId, Long subClassId); + @Query("SELECT e FROM Exam e " + + "JOIN e.mainClass mc " + + "JOIN mc.academy a " + + "WHERE a.id = :academyId " + + "AND mc.id = :mainClassId " + + "AND e.subClass.id = :subClassId") + List findByAcademyIdAndMainClassIdAndSubClassId(@Param("academyId") Long academyId, + @Param("mainClassId") Long mainClassId, + @Param("subClassId") Long subClassId); + } diff --git a/src/main/java/classfit/example/classfit/studentExam/dto/response/FindExamResponse.java b/src/main/java/classfit/example/classfit/studentExam/dto/response/FindExamResponse.java index 3f219c46..b5000e21 100644 --- a/src/main/java/classfit/example/classfit/studentExam/dto/response/FindExamResponse.java +++ b/src/main/java/classfit/example/classfit/studentExam/dto/response/FindExamResponse.java @@ -5,36 +5,37 @@ import classfit.example.classfit.studentExam.domain.Standard; import classfit.example.classfit.member.domain.Member; import java.time.LocalDate; -import java.time.LocalDateTime; import org.springframework.format.annotation.DateTimeFormat; public record FindExamResponse( Long examId, ExamPeriod examPeriod, Long memberId, - String memberName, Standard standard, String mainClassName, String subClassName, String examName, - @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate createdAt -) { + @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate examDate, + String createdByName + ) { + + + public static FindExamResponse from(Exam exam, Member findMember) { + Member createdByMember = findMember.getAcademy().getMembers().stream() + .filter(member -> member.getId().equals(exam.getCreatedBy())) + .findFirst() + .orElse(null); - public static FindExamResponse from(Exam exam, Member member) { return new FindExamResponse( exam.getId(), exam.getExamPeriod(), - member.getId(), - member.getName(), + findMember.getId(), exam.getStandard(), exam.getMainClass().getMainClassName(), exam.getSubClass().getSubClassName(), exam.getExamName(), - convertToLocalDate(exam.getCreatedAt()) + exam.getExamDate(), + createdByMember != null ? createdByMember.getName() : "선생님" ); } - - private static LocalDate convertToLocalDate(LocalDateTime dateTime) { - return dateTime.toLocalDate(); - } } diff --git a/src/main/java/classfit/example/classfit/studentExam/service/ExamService.java b/src/main/java/classfit/example/classfit/studentExam/service/ExamService.java index 14f13805..47cd3fd9 100644 --- a/src/main/java/classfit/example/classfit/studentExam/service/ExamService.java +++ b/src/main/java/classfit/example/classfit/studentExam/service/ExamService.java @@ -73,6 +73,7 @@ public CreateExamResponse createExam(@AuthMember Member findMember, CreateExamRe validateAcademy(findMember, findMainClass.getAcademy().getId()); Exam newExam = request.toEntity(findSubClass, findMainClass); + newExam.updateCreatedBy(findMember.getId()); if (request.standard() == Standard.PF) { newExam.updateHighestScore(-1); @@ -82,6 +83,7 @@ public CreateExamResponse createExam(@AuthMember Member findMember, CreateExamRe Exam savedExam = examRepository.save(newExam); + int defaultScore; if (request.standard() == Standard.PF) { defaultScore = -3; // PF : -3(P) / -4(F) @@ -91,7 +93,7 @@ public CreateExamResponse createExam(@AuthMember Member findMember, CreateExamRe defaultScore = 0; // 기본값은 0 } - List classStudents = classStudentRepository.findBySubClass(findSubClass); + List classStudents = classStudentRepository.findByAcademyIdAndSubClass(findMember.getAcademy().getId(),findSubClass); List studentExamScores = classStudents.stream().map(classStudent -> { Student student = classStudent.getStudent(); return new StudentExamScore(student, savedExam, defaultScore, null, null); // 초기 점수는 0 @@ -107,7 +109,7 @@ public List findExamClassStudent(@AuthMember Member findMember .orElseThrow(() -> new ClassfitException("시험지를 찾을 수 없어요.", HttpStatus.NOT_FOUND)); validateAcademy(findMember, findMember.getAcademy().getId()); - List studentExamScores = studentExamScoreRepository.findByExam(findExam); + List studentExamScores = studentExamScoreRepository.findByAcademyIdAndExam(findMember.getAcademy().getId(),findExam); return studentExamScores.stream().map(studentExamScore -> { Student student = studentExamScore.getStudent(); @@ -132,15 +134,15 @@ public List findExamList(@AuthMember Member findMember, if (request.memberName() == null && request.examName() == null && request.mainClassId() == null && request.subClassId() == null) { - exams = examRepository.findAll(); + exams = examRepository.findAllByAcademyId(findMember.getAcademy().getId()); } else if (request.mainClassId() != null && request.subClassId() != null) { - exams = examRepository.findByMainClassIdAndSubClassId(request.mainClassId(), + exams = examRepository.findByAcademyIdAndMainClassIdAndSubClassId(findMember.getAcademy().getId(),request.mainClassId(), request.subClassId()); } else if (request.memberName() != null && request.examName() == null) { - exams = examRepository.findByAcademyAndMemberName(findMember.getAcademy().getName(), + exams = examRepository.findByAcademyIdAndMemberName(findMember.getAcademy().getId(), request.memberName()); } else if (request.memberName() == null && request.examName() != null) { - exams = examRepository.findByExamName(request.examName()); + exams = examRepository.findByAcademyIdAndExamName(findMember.getAcademy().getId(),request.examName()); } else { throw new ClassfitException("검색을 할 수 없습니다.", HttpStatus.BAD_REQUEST); } @@ -163,7 +165,7 @@ public ShowExamDetailResponse showExamDetail(@AuthMember Member findMember, Long SubClass subClass = findExam.getSubClass(); List studentScores = findExam.getStudentExamScores(); - List classStudents = classStudentRepository.findBySubClass(subClass); + List classStudents = classStudentRepository.findByAcademyIdAndSubClass(findMember.getAcademy().getId(),subClass); Integer perfectScore = studentScores.stream().mapToInt(StudentExamScore::getScore).max() .orElse(findExam.getHighestScore()); Integer lowestScore = studentScores.stream().mapToInt(StudentExamScore::getScore).min() @@ -183,7 +185,7 @@ public ShowExamDetailResponse showExamDetail(@AuthMember Member findMember, Long .filter(scoreObj -> scoreObj.getStudent().getId().equals(student.getId())) .map(StudentExamScore::getScore).findFirst().orElse(0); - String evaluationDetail = studentExamScoreRepository.findByExamAndStudentId(findExam, + String evaluationDetail = studentExamScoreRepository.findByExamAndStudentIdAndAcademyId(findMember.getAcademy().getId(),findExam, student.getId()) .map(StudentExamScore::getEvaluationDetail) .orElse(null); @@ -223,7 +225,7 @@ public UpdateExamResponse updateExam(@AuthMember Member findMember, Long examId, Integer newHighestScore = request.highestScore(); - List studentExamScores = studentExamScoreRepository.findAllByExam( + List studentExamScores = studentExamScoreRepository.findAllByAcademyIdAndExam(findMember.getAcademy().getId(), findExam); if (newHighestScore != null && newHighestScore > 0) { @@ -263,7 +265,7 @@ public UpdateStudentScoreResponse updateStudentScore(@AuthMember Member findMemb validateAcademy(findMember, findExam.getMainClass().getAcademy().getId()); for (UpdateStudentScoreRequest request : requests) { - StudentExamScore studentExamScore = studentExamScoreRepository.findByExamAndStudentId( + StudentExamScore studentExamScore = studentExamScoreRepository.findByExamAndStudentIdAndAcademyId(findMember.getAcademy().getId(), findExam, request.studentId()).orElseGet(() -> { Student student = studentRepository.findById(request.studentId()).orElseThrow( () -> new ClassfitException("해당 학생을 찾을 수 없어요.", HttpStatus.NOT_FOUND)); @@ -293,16 +295,16 @@ public UpdateStudentScoreResponse updateStudentScore(@AuthMember Member findMemb studentExamScoreRepository.flush(); Standard standard = findExam.getStandard(); - List classStudents = classStudentRepository.findBySubClass( + List classStudents = classStudentRepository.findByAcademyIdAndSubClass(findMember.getAcademy().getId(), findExam.getSubClass()); List examStudents = classStudents.stream().map(classStudent -> { Student student = classStudent.getStudent(); - Integer score = studentExamScoreRepository.findByExamAndStudentId(findExam, + Integer score = studentExamScoreRepository.findByExamAndStudentIdAndAcademyId(findMember.getAcademy().getId(),findExam, student.getId()) .map(StudentExamScore::getScore) .orElse(0); - String evaluationDetail = studentExamScoreRepository.findByExamAndStudentId(findExam, + String evaluationDetail = studentExamScoreRepository.findByExamAndStudentIdAndAcademyId(findMember.getAcademy().getId(),findExam, student.getId()) .map(StudentExamScore::getEvaluationDetail) .orElse(null);