Skip to content
Open
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
Expand Up @@ -71,7 +71,7 @@ private MemberInfoRes getMemberInfo(Member member) {
return MemberInfoRes.of(member, student, teacher);
}

public ResponseData<List<MemberInfoRes>> getAll(){
public ResponseData<List<MemberInfoRes>> getAll() {
return ResponseData.ok("모든 멤버 정보 조회 성공",
memberRepository.findByStatusOrderByStudent(ActiveStatus.ACTIVE)
.parallelStream()
Expand Down Expand Up @@ -107,12 +107,11 @@ private ResponseData<Boolean> checkDormitoryManageMemberByMember(Member member)
return ResponseData.ok("자치위원 확인 성공", dormitoryManageMemberRepository.existsByMember(member));
}

public ResponseData<MemberInfoRes> getMemberByCode(String code){
return ResponseData.ok("학생 조회 성공", this.getMemberInfo(memberService.checkCode(code)
.getMember()));
public ResponseData<MemberInfoRes> getMemberByCode(String code) {
return ResponseData.ok("학생 조회 성공", this.getMemberInfo(memberService.checkCode(code).getMember()));
}

public ResponseData<List<StudentRelationRes>> getStudentByPatent(){
public ResponseData<List<StudentRelationRes>> getStudentByPatent() {
Member member = memberAuthenticationHolder.current();
List<StudentRelationRes> studentRelationRes =
memberService.getStudentRelationByMember(member).stream()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package b1nd.dodam.restapi.nightstudy.application;

import b1nd.dodam.core.util.ZonedDateTimeUtil;
import b1nd.dodam.domain.rds.member.entity.DormitoryManageMember;
import b1nd.dodam.domain.rds.member.entity.Member;
import b1nd.dodam.domain.rds.member.entity.Student;
Expand Down Expand Up @@ -37,7 +36,6 @@
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
Expand All @@ -59,30 +57,28 @@ public class NightStudyUseCase {

public Response apply(ApplyNightStudyReq req) {
Student student = studentRepository.getByMember(memberAuthenticationHolder.current());
validateDuplicatedOrBanned(student, req);
validateBanned(student, req);
nightStudyService.save(req.toEntity(student));
return Response.created("심야자습 신청 성공");
}

private void validateDuplicatedOrBanned(Student student, ApplyNightStudyReq req) {
private void validateBanned(Student student, ApplyNightStudyReq req) {
nightStudyBanService.validateBan(student);
nightStudyService.validateDurationDuplication(student, req.startAt(), req.endAt());
nightStudyProjectMemberService.validateMultipleDurationDuplication(Collections.singletonList(student), req.startAt(), req.endAt(), NightStudyProjectType.NIGHT_STUDY_PROJECT_2);
}

public Response applyProject(ApplyNightStudyProjectReq req) {
Student leader = studentRepository.getByMember(memberAuthenticationHolder.current());
List<Student> students = studentRepository.getByIds(req.students());
checkLeaderAndStudentsDuplicatedOrBanned(leader, students, req);
checkLeaderAndStudentsBanned(leader, students, req);
NightStudyProject project = nightStudyProjectService.save(req.toEntity());
nightStudyProjectMemberService.saveAll(getProjectMembers(leader, students, project));
return Response.created("프로젝트 심야자습 신청 성공");
}

private void checkLeaderAndStudentsDuplicatedOrBanned(Student leader, List<Student> students, ApplyNightStudyProjectReq req) {
private void checkLeaderAndStudentsBanned(Student leader, List<Student> students, ApplyNightStudyProjectReq req) {
List<Student> participants = Stream.concat(Stream.of(leader), students.stream()).toList();
nightStudyBanService.validateMultipleBans(participants);
nightStudyProjectMemberService.validateMultipleDurationDuplication(participants, req.startAt(), req.endAt(), req.type());
if (req.type() == NightStudyProjectType.NIGHT_STUDY_PROJECT_2) nightStudyService.validateNoActiveNightStudies(participants);
}

Expand Down Expand Up @@ -208,17 +204,14 @@ public ResponseData<List<NightStudyBanRes>> getAllActiveBans() {

@Transactional(readOnly = true)
public ResponseData<List<NightStudyRes>> getAll() {
Student student = studentRepository.getByMember(memberAuthenticationHolder.current());
LocalDate now = ZonedDateTimeUtil.nowToLocalDate();
List<NightStudyRes> result = NightStudyRes.of(nightStudyService.getAll(now));
List<NightStudyRes> result = NightStudyRes.of(nightStudyService.getAll());
return ResponseData.ok("모든 심야자습 조회 성공", result);
}

@Transactional(readOnly = true)
public ResponseData<List<NightStudyRes>> getMy() {
Student student = studentRepository.getByMember(memberAuthenticationHolder.current());
LocalDate now = ZonedDateTimeUtil.nowToLocalDate();
List<NightStudyRes> result = NightStudyRes.of(nightStudyService.getMy(student, now));
List<NightStudyRes> result = NightStudyRes.of(nightStudyService.getMy(student));
return ResponseData.ok("내 심야자습 조회 성공", result);
}

Expand All @@ -230,20 +223,17 @@ public ResponseData<List<NightStudyRes>> getPending() {

@Transactional(readOnly = true)
public ResponseData<List<NightStudyRes>> getValid() {
LocalDate now = ZonedDateTimeUtil.nowToLocalDate();
List<NightStudyRes> result = NightStudyRes.of(nightStudyService.getValid(now));
List<NightStudyRes> result = NightStudyRes.of(nightStudyService.getValid());
return ResponseData.ok("승인된 심야자습 조회 성공", result);
}

@Transactional(readOnly = true)
public ResponseData<List<StudentWithNightStudyBanRes>> getMembers() {
LocalDate now = ZonedDateTimeUtil.nowToLocalDate();
List<Student> students = studentRepository.findAllByMember_Status(ActiveStatus.ACTIVE);
List<Integer> bannedStudentIds = nightStudyBanService.findAllStudentIdByDate(now);
List<Integer> bannedStudentIds = nightStudyBanService.findAllStudentIdByDate();
return ResponseData.ok("학생 및 정지 여부 조회 성공", StudentWithNightStudyBanRes.of(students, bannedStudentIds));
}


@Transactional(readOnly = true)
public ResponseData<NightStudyProjectWithMembersRes> getProjectDetails(Long id) {
NightStudyProject project = nightStudyProjectService.getById(id);
Expand All @@ -253,24 +243,21 @@ public ResponseData<NightStudyProjectWithMembersRes> getProjectDetails(Long id)

@Transactional(readOnly = true)
public ResponseData<List<NightStudyProjectRes>> getValidProjects() {
LocalDate today = ZonedDateTimeUtil.nowToLocalDate();
List<NightStudyProjectRes> result = nightStudyProjectService.getAllByDateRange(today).stream()
List<NightStudyProjectRes> result = nightStudyProjectService.getAllByDateRange().stream()
.map(NightStudyProjectRes::of)
.toList();
return ResponseData.ok("유효한 모든 프로젝트 조회 성공", result);
}

@Transactional(readOnly = true)
public ResponseData<List<NightStudyProjectWithMembersRes>> getPendingProjects() {
LocalDate today = ZonedDateTimeUtil.nowToLocalDate();
List<NightStudyProjectMember> members = nightStudyProjectMemberService.getPendingProjectMembers(today);
List<NightStudyProjectMember> members = nightStudyProjectMemberService.getPendingProjectMembers();
return ResponseData.ok("대기중인 프로젝트 심야자습 조회 성공", convertToProjectWithMembersRes(members));
}

@Transactional(readOnly = true)
public ResponseData<List<NightStudyProjectWithMembersRes>> getAllowedProjects() {
LocalDate today = ZonedDateTimeUtil.nowToLocalDate();
List<NightStudyProjectMember> members = nightStudyProjectMemberService.getAllowedProjectMembers(today);
List<NightStudyProjectMember> members = nightStudyProjectMemberService.getAllowedProjectMembers();
return ResponseData.ok("승인된 프로젝트 심야자습 조회 성공", convertToProjectWithMembersRes(members));
}

Expand All @@ -285,35 +272,39 @@ private List<NightStudyProjectWithMembersRes> convertToProjectWithMembersRes(Lis
@Transactional(readOnly = true)
public ResponseData<List<NightStudyProjectRes>> getMyProjects() {
Student student = studentRepository.getByMember(memberAuthenticationHolder.current());
LocalDate today = ZonedDateTimeUtil.nowToLocalDate();
List<NightStudyProjectRes> result = nightStudyProjectMemberService.findByStudent(student, today).stream()
List<NightStudyProjectRes> result = nightStudyProjectMemberService.findByStudent(student).stream()
.map(NightStudyProjectRes::of)
.toList();
return ResponseData.ok("내 프로젝트 심야자습 조회 성공", result);
}

@Transactional(readOnly = true)
public ResponseData<List<NightStudyProjectRoomRes>> getRoomsInUse() {
LocalDate today = ZonedDateTimeUtil.nowToLocalDate();
List<NightStudyProjectRoomRes> result = NightStudyProjectRoomRes.of(nightStudyProjectService.getAllRoomsWithProjects(today));
List<NightStudyProjectRoomRes> result = NightStudyProjectRoomRes.of(nightStudyProjectService.getAllRoomsWithProjects());
return ResponseData.ok("사용중인 프로젝트 실 조회 성공", result);
}

@Transactional(readOnly = true)
public ResponseData<List<StudentWithNightStudyBanRes>> getStudentsWithBan() {
LocalDate today = ZonedDateTimeUtil.nowToLocalDate();
Member member = authenticationHolder.current();
List<Student> students = studentRepository.findAllByMember_StatusAndMemberNot(ActiveStatus.ACTIVE, member);
List<Integer> bannedStudents = nightStudyBanService.findAllStudentIdByDate(today);
List<Integer> bannedStudents = nightStudyBanService.findAllStudentIdByDate();
List<StudentWithNightStudyBanRes> result = StudentWithNightStudyBanRes.of(students, bannedStudents);
return ResponseData.ok("학생 조회 성공", result);
}

@Transactional(readOnly = true)
public ResponseData<NightStudyAndProjectRes> getCombined() {
List<NightStudyProjectMember> members = nightStudyProjectMemberService.getAllStudentByDate();
List<NightStudyRes> nightStudyRes = NightStudyRes.of(nightStudyService.getCombinedStudy());
List<StudentWithNightStudyProjectRes> projectStudents = StudentWithNightStudyProjectRes.from(members);
NightStudyAndProjectRes result = NightStudyAndProjectRes.of(nightStudyRes, projectStudents);
return ResponseData.ok("심야자습 및 프로젝트 참가자 조회 성공", result);
}

@Transactional(readOnly = true)
public ResponseData<List<StudentWithNightStudyProjectRes>> getProjectStudents() {
List<NightStudyProjectMember> members = nightStudyProjectMemberService.getAllStudentByDate(ZonedDateTimeUtil.nowToLocalDate());
return ResponseData.ok("프로젝트 참가 학생 조회 성공", members.stream()
.map(member -> StudentWithNightStudyProjectRes.of(member.getStudent(), member.getProject()))
.toList());
List<NightStudyProjectMember> members = nightStudyProjectMemberService.getAllStudentByDate();
return ResponseData.ok("프로젝트 참가 학생 조회 성공", StudentWithNightStudyProjectRes.from(members));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package b1nd.dodam.restapi.nightstudy.application.data.res;

import java.util.List;

public record NightStudyAndProjectRes(
List<NightStudyRes> selfStudy,
List<StudentWithNightStudyProjectRes> projectStudy
) {
public static NightStudyAndProjectRes of(
List<NightStudyRes> selfStudy,
List<StudentWithNightStudyProjectRes> projectStudy
) {
return new NightStudyAndProjectRes(selfStudy, projectStudy);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

import b1nd.dodam.domain.rds.member.entity.Student;
import b1nd.dodam.domain.rds.nightstudy.entity.NightStudyProject;
import b1nd.dodam.domain.rds.nightstudy.entity.NightStudyProjectMember;
import b1nd.dodam.domain.rds.nightstudy.enumeration.NightStudyProjectRoom;
import b1nd.dodam.domain.rds.nightstudy.enumeration.NightStudyProjectType;

import java.util.List;

public record StudentWithNightStudyProjectRes(
int id,
String name,
Expand All @@ -27,4 +30,10 @@ public static StudentWithNightStudyProjectRes of(Student student, NightStudyProj
project.getRoom()
);
}
}

public static List<StudentWithNightStudyProjectRes> from(List<NightStudyProjectMember> members) {
return members.stream()
.map(member -> StudentWithNightStudyProjectRes.of(member.getStudent(), member.getProject()))
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ public ResponseData<List<StudentWithNightStudyBanRes>> getAvailableStudents() {
return useCase.getStudentsWithBan();
}

@GetMapping("/combined")
public ResponseData<NightStudyAndProjectRes> getCombined() {
return useCase.getCombined();
}

@GetMapping("/project/students")
public ResponseData<List<StudentWithNightStudyProjectRes>> getValidProjectStudents() {
return useCase.getProjectStudents();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ List<NightStudyProjectMember> findValidStudyByStudentAndDate(

@Query("""
select m from NightStudyProjectMember m
join m.project p
join fetch m.project p
where p.status = 'ALLOWED' and
:today between p.startAt and p.endAt
:today <= p.endAt
""")
List<NightStudyProjectMember> findAllowedProjectMembers(
@Param("today") LocalDate today
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,11 @@ boolean existsActiveNightStudy(@Param("students") List<Student> students,

@EntityGraph(attributePaths = {"student.member"})
List<NightStudy> findByEndAt(LocalDate endAt);

@Query("SELECT n FROM NightStudy n " +
"JOIN FETCH n.student s " +
"JOIN FETCH s.member " +
"WHERE n.status = 'ALLOWED' AND n.endAt >= :date AND n.startAt <= :date " +
"ORDER BY s.grade, s.room, s.number")
List<NightStudy> findCombinedNightStudy(@Param("date") LocalDate date);
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ public NightStudyBan findUserBan(Student student) {
.orElseThrow(NightStudyBanNotFoundException::new);
}

public List<Integer> findAllStudentIdByDate(LocalDate date) {
return nightStudyBanRepository.findByEndedGreaterThanEqual(date)
public List<Integer> findAllStudentIdByDate() {
return nightStudyBanRepository.findByEndedGreaterThanEqual(ZonedDateTimeUtil.nowToLocalDate())
.stream()
.map(NightStudyBan::getStudentId)
.toList();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package b1nd.dodam.domain.rds.nightstudy.service;

import b1nd.dodam.core.util.ZonedDateTimeUtil;
import b1nd.dodam.domain.rds.member.entity.Student;
import b1nd.dodam.domain.rds.nightstudy.entity.NightStudyProject;
import b1nd.dodam.domain.rds.nightstudy.entity.NightStudyProjectMember;
import b1nd.dodam.domain.rds.nightstudy.enumeration.NightStudyProjectType;
import b1nd.dodam.domain.rds.nightstudy.exception.NightStudyDuplicateException;
import b1nd.dodam.domain.rds.nightstudy.exception.NightStudyProjectMemberNotFoundException;
import b1nd.dodam.domain.rds.nightstudy.repository.NightStudyProjectMemberRepository;
import b1nd.dodam.domain.rds.support.enumeration.ApprovalStatus;
Expand All @@ -23,12 +22,12 @@ public void saveAll(List<NightStudyProjectMember> members) {
repository.saveAll(members);
}

public List<NightStudyProjectMember> getAllStudentByDate(LocalDate now) {
return repository.findAllowedProjectMembers(now);
public List<NightStudyProjectMember> getAllStudentByDate() {
return repository.findAllowedProjectMembers(ZonedDateTimeUtil.nowToLocalDate());
}

public List<NightStudyProject> findByStudent(Student student, LocalDate now) {
return repository.findByStudentAndProject_EndAtGreaterThanEqual(student, now).stream().map(NightStudyProjectMember::getProject).toList();
public List<NightStudyProject> findByStudent(Student student) {
return repository.findByStudentAndProject_EndAtGreaterThanEqual(student, ZonedDateTimeUtil.nowToLocalDate()).stream().map(NightStudyProjectMember::getProject).toList();
}

public NightStudyProjectMember findByStudentAndProject(Student student, NightStudyProject project) {
Expand All @@ -40,15 +39,11 @@ public List<NightStudyProjectMember> getByProject(NightStudyProject project) {
return repository.findAllByProject(project);
}

public void validateMultipleDurationDuplication(List<Student> students, LocalDate startAt, LocalDate endAt, NightStudyProjectType type) {
if (repository.existsValidByStudentAndDate(students, startAt, endAt, type)) throw new NightStudyDuplicateException();
public List<NightStudyProjectMember> getAllowedProjectMembers() {
return repository.findMemberWithProjectByStatus(ApprovalStatus.ALLOWED, ZonedDateTimeUtil.nowToLocalDate());
}

public List<NightStudyProjectMember> getAllowedProjectMembers(LocalDate date) {
return repository.findMemberWithProjectByStatus(ApprovalStatus.ALLOWED, date);
}

public List<NightStudyProjectMember> getPendingProjectMembers(LocalDate date) {
return repository.findMemberWithProjectByStatus(ApprovalStatus.PENDING, date);
public List<NightStudyProjectMember> getPendingProjectMembers() {
return repository.findMemberWithProjectByStatus(ApprovalStatus.PENDING, ZonedDateTimeUtil.nowToLocalDate());
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package b1nd.dodam.domain.rds.nightstudy.service;

import b1nd.dodam.core.util.ZonedDateTimeUtil;
import b1nd.dodam.domain.rds.nightstudy.entity.NightStudyProject;
import b1nd.dodam.domain.rds.nightstudy.exception.NightStudyNotFoundException;
import b1nd.dodam.domain.rds.nightstudy.repository.NightStudyProjectRepository;
Expand Down Expand Up @@ -29,11 +30,13 @@ public NightStudyProject getById(Long id) {
.orElseThrow(NightStudyNotFoundException::new);
}

public List<NightStudyProject> getAllByDateRange(LocalDate date) {
return repository.findByStartAtLessThanEqualAndEndAtGreaterThanEqual(date, date);
public List<NightStudyProject> getAllByDateRange() {
LocalDate now = ZonedDateTimeUtil.nowToLocalDate();
return repository.findByStartAtLessThanEqualAndEndAtGreaterThanEqual(now, now);
}

public List<NightStudyProject> getAllRoomsWithProjects(LocalDate date) {
return repository.findByStatusNotAndStartAtLessThanEqualAndEndAtGreaterThanEqualOrderByRoom(ApprovalStatus.REJECTED, date, date);
public List<NightStudyProject> getAllRoomsWithProjects() {
LocalDate now = ZonedDateTimeUtil.nowToLocalDate();
return repository.findByStatusNotAndStartAtLessThanEqualAndEndAtGreaterThanEqualOrderByRoom(ApprovalStatus.REJECTED, now, now);
}
}
Loading