diff --git a/src/main/java/com/tukorea/planding/domain/group/controller/GroupFavoriteController.java b/src/main/java/com/tukorea/planding/domain/group/controller/GroupFavoriteController.java index ff7d535..510fb73 100644 --- a/src/main/java/com/tukorea/planding/domain/group/controller/GroupFavoriteController.java +++ b/src/main/java/com/tukorea/planding/domain/group/controller/GroupFavoriteController.java @@ -6,10 +6,12 @@ import com.tukorea.planding.domain.group.service.GroupFavoriteService; import com.tukorea.planding.domain.user.dto.UserInfo; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; +@Tag(name = "Group Favorite", description = "그룹 즐겨찾기 관련") @RestController @RequiredArgsConstructor @RequestMapping("/api/v1/favorite") diff --git a/src/main/java/com/tukorea/planding/domain/group/controller/GroupInviteController.java b/src/main/java/com/tukorea/planding/domain/group/controller/GroupInviteController.java index b4191b4..b520f0b 100644 --- a/src/main/java/com/tukorea/planding/domain/group/controller/GroupInviteController.java +++ b/src/main/java/com/tukorea/planding/domain/group/controller/GroupInviteController.java @@ -7,23 +7,27 @@ import com.tukorea.planding.domain.group.dto.response.GroupInviteMessageResponse; import com.tukorea.planding.domain.user.dto.UserInfo; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; import java.util.List; +@Tag(name = "Group Invite", description = "그룹 초대 관련") @RestController @RequiredArgsConstructor @RequestMapping("/api/v1/invitation") public class GroupInviteController { private final GroupInviteService groupInviteService; + @Operation(summary = "유저에게 초대를 보낸다") @PostMapping() public CommonResponse invite(@AuthenticationPrincipal UserInfo userInfo, @RequestBody GroupInviteRequest groupInviteRequest) { return CommonUtils.success(groupInviteService.inviteGroupRoom(userInfo, groupInviteRequest)); } + @Operation(summary = "초대를 수락한다") @GetMapping("/accept/{groupId}/{code}") public CommonResponse accept(@AuthenticationPrincipal UserInfo userInfo, @PathVariable(name = "groupId") Long groupId, @PathVariable(name = "code") String code) { groupInviteService.acceptInvitation(userInfo, code, groupId); @@ -37,6 +41,7 @@ public CommonResponse> getInvitations(@Authenti return CommonUtils.success(groupInviteResponse); } + @Operation(summary = "초대를 거절한다.") @DeleteMapping("/decline/{code}") public CommonResponse declineInvitation(@AuthenticationPrincipal UserInfo userInfo, @PathVariable(name = "code") String code) { groupInviteService.declineInvitation(userInfo, code); diff --git a/src/main/java/com/tukorea/planding/domain/group/dto/response/GroupScheduleResponse.java b/src/main/java/com/tukorea/planding/domain/group/dto/response/GroupScheduleResponse.java deleted file mode 100644 index 24b09e0..0000000 --- a/src/main/java/com/tukorea/planding/domain/group/dto/response/GroupScheduleResponse.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.tukorea.planding.domain.group.dto.response; - -public class GroupScheduleResponse { -} diff --git a/src/main/java/com/tukorea/planding/domain/group/entity/GroupRoom.java b/src/main/java/com/tukorea/planding/domain/group/entity/GroupRoom.java index e3b6ae9..e35eab5 100644 --- a/src/main/java/com/tukorea/planding/domain/group/entity/GroupRoom.java +++ b/src/main/java/com/tukorea/planding/domain/group/entity/GroupRoom.java @@ -36,8 +36,8 @@ public class GroupRoom extends BaseEntity { @OneToMany(mappedBy = "groupRoom", cascade = CascadeType.ALL, orphanRemoval = true) private final Set userGroups = new HashSet<>(); - @OneToMany(mappedBy = "groupRoom", cascade = CascadeType.ALL, orphanRemoval = true) - private final List schedules = new ArrayList<>(); +// @OneToMany(mappedBy = "groupRoom", cascade = CascadeType.ALL, orphanRemoval = true) +// private final List schedules = new ArrayList<>(); @OneToMany(mappedBy = "groupRoom", cascade = CascadeType.ALL, orphanRemoval = true) private final List groupFavorites = new ArrayList<>(); @@ -75,10 +75,10 @@ public void validateUserNotAlreadyMember(User user) throws BusinessException { } } - // 스케줄을 그룹룸에 추가하는 메서드 - public void addSchedule(Schedule schedule) { - this.schedules.add(schedule); - } +// // 스케줄을 그룹룸에 추가하는 메서드 +// public void addSchedule(Schedule schedule) { +// this.schedules.add(schedule); +// } public void updateNameOrDes(String name, String description) { if (name != null && !name.equals(this.name)) { diff --git a/src/main/java/com/tukorea/planding/domain/group/repository/normal/GroupRoomRepositoryCustom.java b/src/main/java/com/tukorea/planding/domain/group/repository/normal/GroupRoomRepositoryCustom.java index 15e4472..a4b839f 100644 --- a/src/main/java/com/tukorea/planding/domain/group/repository/normal/GroupRoomRepositoryCustom.java +++ b/src/main/java/com/tukorea/planding/domain/group/repository/normal/GroupRoomRepositoryCustom.java @@ -1,12 +1,13 @@ package com.tukorea.planding.domain.group.repository.normal; import com.tukorea.planding.domain.group.entity.GroupRoom; +import com.tukorea.planding.domain.schedule.entity.Schedule; import com.tukorea.planding.domain.user.entity.User; import java.util.List; public interface GroupRoomRepositoryCustom { List findGroupRoomsByUserId(Long userId); - List getGroupUsers(Long groupId); + List getGroupUsers(Long groupId); } diff --git a/src/main/java/com/tukorea/planding/domain/group/repository/usergroup/UserGroupRepositoryCustom.java b/src/main/java/com/tukorea/planding/domain/group/repository/usergroup/UserGroupRepositoryCustom.java index 6f1e1e6..8de5495 100644 --- a/src/main/java/com/tukorea/planding/domain/group/repository/usergroup/UserGroupRepositoryCustom.java +++ b/src/main/java/com/tukorea/planding/domain/group/repository/usergroup/UserGroupRepositoryCustom.java @@ -7,8 +7,12 @@ public interface UserGroupRepositoryCustom { boolean existsByGroupRoomIdAndUserId(Long groupRoomId, Long userId); + List findUserByIsConnectionFalse(Long groupRoomId); - UserGroup findUserByGroupId(Long userId, Long groupRoomId); + + UserGroup findUserByGroupId(Long userId, Long groupRoomId); + boolean existsByUserCodeAndGroupId(String userCode, Long groupId); + List findAllUsersByGroupId(Long groupRoomId); } diff --git a/src/main/java/com/tukorea/planding/domain/group/repository/usergroup/UserGroupRepositoryCustomImpl.java b/src/main/java/com/tukorea/planding/domain/group/repository/usergroup/UserGroupRepositoryCustomImpl.java index a27f3a2..29326d5 100644 --- a/src/main/java/com/tukorea/planding/domain/group/repository/usergroup/UserGroupRepositoryCustomImpl.java +++ b/src/main/java/com/tukorea/planding/domain/group/repository/usergroup/UserGroupRepositoryCustomImpl.java @@ -50,4 +50,11 @@ public boolean existsByUserCodeAndGroupId(String userCode, Long groupId) { return count > 0; } + + @Override + public List findAllUsersByGroupId(Long groupRoomId) { + return queryFactory.selectFrom(userGroup) + .where(userGroup.groupRoom.id.eq(groupRoomId)) + .fetch(); + } } diff --git a/src/main/java/com/tukorea/planding/domain/group/service/GroupInviteService.java b/src/main/java/com/tukorea/planding/domain/group/service/GroupInviteService.java index 9021725..258296b 100644 --- a/src/main/java/com/tukorea/planding/domain/group/service/GroupInviteService.java +++ b/src/main/java/com/tukorea/planding/domain/group/service/GroupInviteService.java @@ -6,6 +6,7 @@ import com.tukorea.planding.domain.group.entity.GroupRoom; import com.tukorea.planding.domain.group.entity.UserGroup; import com.tukorea.planding.domain.group.service.query.GroupQueryService; +import com.tukorea.planding.domain.group.service.query.UserGroupQueryService; import com.tukorea.planding.domain.notify.service.NotificationService; import com.tukorea.planding.domain.user.dto.UserInfo; import com.tukorea.planding.domain.user.entity.User; @@ -24,7 +25,7 @@ public class GroupInviteService { private final UserQueryService userQueryService; private final GroupQueryService groupQueryService; - private final UserGroupService userGroupService; + private final UserGroupQueryService userGroupQueryService; private final NotificationService notificationService; private final RedisGroupInviteService redisGroupInviteService; @@ -64,7 +65,7 @@ public void acceptInvitation(UserInfo userInfo, String code, Long groupId) { GroupRoom group = groupQueryService.getGroupById(groupId); final UserGroup userGroup = UserGroup.createUserGroup(user, group); - userGroupService.save(userGroup); + userGroupQueryService.save(userGroup); redisGroupInviteService.deleteInvitation(userInfo.getUserCode(), code); } diff --git a/src/main/java/com/tukorea/planding/domain/group/service/GroupRoomService.java b/src/main/java/com/tukorea/planding/domain/group/service/GroupRoomService.java index 33904a3..f259d1d 100644 --- a/src/main/java/com/tukorea/planding/domain/group/service/GroupRoomService.java +++ b/src/main/java/com/tukorea/planding/domain/group/service/GroupRoomService.java @@ -8,6 +8,7 @@ import com.tukorea.planding.domain.group.entity.UserGroup; import com.tukorea.planding.domain.group.repository.normal.GroupRoomRepository; import com.tukorea.planding.domain.group.service.query.GroupQueryService; +import com.tukorea.planding.domain.group.service.query.UserGroupQueryService; import com.tukorea.planding.domain.user.dto.UserInfo; import com.tukorea.planding.domain.user.entity.User; import com.tukorea.planding.domain.user.service.UserQueryService; @@ -27,7 +28,7 @@ public class GroupRoomService { private final UserQueryService userQueryService; - private final UserGroupService userGroupService; + private final UserGroupQueryService userGroupQueryService; private final GroupQueryService groupQueryService; @Transactional @@ -40,7 +41,7 @@ public GroupResponse createGroupRoom(UserInfo userInfo, GroupCreateRequest creat final UserGroup userGroup = UserGroup.createUserGroup(user, savedGroupRoom); // 중간테이블에 유저, 그룹 정보 저장 - userGroupService.save(userGroup); + userGroupQueryService.save(userGroup); return toGroupResponse(newGroupRoom); } diff --git a/src/main/java/com/tukorea/planding/domain/group/service/UserGroupService.java b/src/main/java/com/tukorea/planding/domain/group/service/UserGroupService.java index 0568e76..5c1a2a8 100644 --- a/src/main/java/com/tukorea/planding/domain/group/service/UserGroupService.java +++ b/src/main/java/com/tukorea/planding/domain/group/service/UserGroupService.java @@ -37,15 +37,4 @@ public void updateConnectionStatus(String userCode, String groupCode, boolean is test.setConnected(isConnected); } - public void save(UserGroup userGroup) { - userGroupRepository.save(userGroup); - } - - public void checkUserAccessToGroupRoom(Long groupRoomId, Long userId) { - boolean exists = userGroupRepository.existsByGroupRoomIdAndUserId(groupRoomId, userId); - if (!exists) { - throw new BusinessException(ErrorCode.ACCESS_DENIED); - } - } - } diff --git a/src/main/java/com/tukorea/planding/domain/group/service/query/GroupQueryService.java b/src/main/java/com/tukorea/planding/domain/group/service/query/GroupQueryService.java index 2d76c69..4663142 100644 --- a/src/main/java/com/tukorea/planding/domain/group/service/query/GroupQueryService.java +++ b/src/main/java/com/tukorea/planding/domain/group/service/query/GroupQueryService.java @@ -21,7 +21,6 @@ public class GroupQueryService { private final GroupRoomRepository groupRoomRepository; private final UserGroupRepository userGroupRepository; - public GroupRoom createGroup(GroupRoom groupRoom) { return groupRoomRepository.save(groupRoom); } @@ -35,6 +34,12 @@ public GroupRoom getGroupById(Long groupId) { .orElseThrow(() -> new BusinessException(ErrorCode.GROUP_ROOM_NOT_FOUND)); } + public GroupRoom getGroupByCode(String groupCode) { + return groupRoomRepository.findByGroupCode(groupCode) + .orElseThrow(() -> new BusinessException(ErrorCode.GROUP_ROOM_NOT_FOUND)); + } + + public void delete(GroupRoom groupRoom) { groupRoomRepository.delete(groupRoom); } diff --git a/src/main/java/com/tukorea/planding/domain/group/service/query/UserGroupQueryService.java b/src/main/java/com/tukorea/planding/domain/group/service/query/UserGroupQueryService.java new file mode 100644 index 0000000..9c253a0 --- /dev/null +++ b/src/main/java/com/tukorea/planding/domain/group/service/query/UserGroupQueryService.java @@ -0,0 +1,26 @@ +package com.tukorea.planding.domain.group.service.query; + +import com.tukorea.planding.domain.group.entity.UserGroup; +import com.tukorea.planding.domain.group.repository.usergroup.UserGroupRepository; +import com.tukorea.planding.global.error.BusinessException; +import com.tukorea.planding.global.error.ErrorCode; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class UserGroupQueryService { + + private final UserGroupRepository userGroupRepository; + + public void save(UserGroup userGroup) { + userGroupRepository.save(userGroup); + } + + public void checkUserAccessToGroupRoom(Long groupRoomId, Long userId) { + boolean exists = userGroupRepository.existsByGroupRoomIdAndUserId(groupRoomId, userId); + if (!exists) { + throw new BusinessException(ErrorCode.ACCESS_DENIED); + } + } +} diff --git a/src/main/java/com/tukorea/planding/domain/notify/controller/NotifyController.java b/src/main/java/com/tukorea/planding/domain/notify/controller/NotifyController.java index 6c2245c..1119a68 100644 --- a/src/main/java/com/tukorea/planding/domain/notify/controller/NotifyController.java +++ b/src/main/java/com/tukorea/planding/domain/notify/controller/NotifyController.java @@ -5,6 +5,7 @@ import com.tukorea.planding.domain.notify.service.NotificationService; import com.tukorea.planding.domain.user.dto.UserInfo; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; import org.springframework.security.core.annotation.AuthenticationPrincipal; @@ -13,7 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; - +@Tag(name = "Notify", description = "알림 메시지 관련") @RestController @RequiredArgsConstructor @RequestMapping("/api/v1/notification") diff --git a/src/main/java/com/tukorea/planding/domain/schedule/controller/CommonScheduleController.java b/src/main/java/com/tukorea/planding/domain/schedule/controller/CommonScheduleController.java new file mode 100644 index 0000000..cfaf355 --- /dev/null +++ b/src/main/java/com/tukorea/planding/domain/schedule/controller/CommonScheduleController.java @@ -0,0 +1,49 @@ +package com.tukorea.planding.domain.schedule.controller; + +import com.tukorea.planding.common.CommonResponse; +import com.tukorea.planding.common.CommonUtils; +import com.tukorea.planding.domain.schedule.dto.request.ScheduleRequest; +import com.tukorea.planding.domain.schedule.dto.response.PersonalScheduleResponse; +import com.tukorea.planding.domain.schedule.dto.response.ScheduleResponse; +import com.tukorea.planding.domain.schedule.service.CommonScheduleService; +import com.tukorea.planding.domain.user.dto.UserInfo; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDate; +import java.util.List; + +@Tag(name = "CommonSchedule", description = "공통 스케줄") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1/common/schedule") +public class CommonScheduleController { + + private final CommonScheduleService commonScheduleService; + + @Operation(summary = "오늘 스케줄 조회") + @GetMapping("/today") + public CommonResponse> showTodaySchedule(@AuthenticationPrincipal UserInfo userInfo) { + List responses = commonScheduleService.showTodaySchedule(userInfo); + return CommonUtils.success(responses); + } + + @Operation(summary = "공통: 스케쥴 생성을 할 때 내가 포함된 모든 그룹, 개인 시간때에 스케쥴을 확인") + @PostMapping("/overlap") + public CommonResponse> findOverlapSchedule(@AuthenticationPrincipal UserInfo userInfo, @RequestBody ScheduleRequest scheduleRequest) { + List scheduleResponses = commonScheduleService.findOverlapSchedule(userInfo.getId(), scheduleRequest); + return CommonUtils.success(scheduleResponses); + } + + @Operation(summary = "주간으로 가져오기") + @GetMapping("/week/{startDate}/{endDate}") + public CommonResponse> getWeekSchedule(@PathVariable(name = "startDate") LocalDate startDate, + @PathVariable(name = "endDate") LocalDate endDate + , @AuthenticationPrincipal UserInfo userInfo) { + List scheduleResponse = commonScheduleService.getWeekSchedule(startDate, endDate, userInfo); + return CommonUtils.success(scheduleResponse); + } +} diff --git a/src/main/java/com/tukorea/planding/domain/schedule/controller/GroupScheduleAttendanceController.java b/src/main/java/com/tukorea/planding/domain/schedule/controller/GroupScheduleAttendanceController.java index c72803a..0f991f1 100644 --- a/src/main/java/com/tukorea/planding/domain/schedule/controller/GroupScheduleAttendanceController.java +++ b/src/main/java/com/tukorea/planding/domain/schedule/controller/GroupScheduleAttendanceController.java @@ -1,17 +1,17 @@ package com.tukorea.planding.domain.schedule.controller; -import com.tukorea.planding.domain.schedule.dto.GroupScheduleAttendanceRequest; +import com.tukorea.planding.domain.schedule.dto.request.GroupScheduleAttendanceRequest; import com.tukorea.planding.domain.schedule.service.GroupScheduleAttendanceService; import com.tukorea.planding.domain.user.dto.UserInfo; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +@Tag(name = "GroupAttendance", description = "그룹 스케줄 참여설정") @RestController @RequiredArgsConstructor @RequestMapping("/api/v1/attendance") @@ -19,9 +19,9 @@ public class GroupScheduleAttendanceController { private final GroupScheduleAttendanceService groupScheduleAttendanceService; - @GetMapping() + @PostMapping() @Operation(summary = "스케줄 참여 여부 선택") - public ResponseEntity participationGroupSchedule(@AuthenticationPrincipal UserInfo userInfo, GroupScheduleAttendanceRequest status) { + public ResponseEntity participationGroupSchedule(@AuthenticationPrincipal UserInfo userInfo, @RequestBody GroupScheduleAttendanceRequest status) { groupScheduleAttendanceService.participationGroupSchedule(userInfo, status); return new ResponseEntity<>("스케줄 참여여부 변경 완료되었습니다.", HttpStatus.OK); } diff --git a/src/main/java/com/tukorea/planding/domain/schedule/controller/PersonalScheduleController.java b/src/main/java/com/tukorea/planding/domain/schedule/controller/PersonalScheduleController.java new file mode 100644 index 0000000..2235d0f --- /dev/null +++ b/src/main/java/com/tukorea/planding/domain/schedule/controller/PersonalScheduleController.java @@ -0,0 +1,57 @@ +package com.tukorea.planding.domain.schedule.controller; + +import com.tukorea.planding.common.CommonResponse; +import com.tukorea.planding.common.CommonUtils; +import com.tukorea.planding.domain.schedule.dto.response.PersonalScheduleResponse; +import com.tukorea.planding.domain.schedule.service.PersonalScheduleService; +import com.tukorea.planding.domain.user.dto.UserInfo; +import com.tukorea.planding.domain.schedule.dto.request.ScheduleRequest; +import com.tukorea.planding.domain.schedule.dto.response.ScheduleResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDate; +import java.util.List; + +@Tag(name = "PersonalSchedule", description = "개인 스케줄") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/v1/schedule") +public class PersonalScheduleController { + + private final PersonalScheduleService personalScheduleService; + + @Operation(summary = "개인 스케줄: 생성") + @PostMapping() + public CommonResponse createSchedule(@AuthenticationPrincipal UserInfo userInfo, @RequestBody ScheduleRequest scheduleRequest) { + PersonalScheduleResponse response = personalScheduleService.createSchedule(userInfo, scheduleRequest); + return CommonUtils.success(response); + } + + @Operation(summary = "개인 스케줄: 삭제") + @DeleteMapping("/{id}") + public ResponseEntity deleteSchedule(@AuthenticationPrincipal UserInfo userInfo, @PathVariable Long id) { + personalScheduleService.deleteSchedule(userInfo, id); + return new ResponseEntity<>(HttpStatus.OK); + } + + @Operation(summary = "개인 스케줄: 조회") + @GetMapping("/{schedule_id}") + public CommonResponse getScheduleById(@PathVariable(name = "schedule_id") Long id, @AuthenticationPrincipal UserInfo userInfo) { + PersonalScheduleResponse scheduleResponse = personalScheduleService.getSchedule(id, userInfo); + return CommonUtils.success(scheduleResponse); + } + + //TODO 아직 요구사항 미정 + @Operation(summary = "개인 스케줄: 제목,내용,시작시간,끝낼시간 항목 수정") + @PatchMapping("/{schedule_id}") + public CommonResponse updateSchedule(@PathVariable(name = "schedule_id") Long id, @RequestBody ScheduleRequest scheduleRequest, @AuthenticationPrincipal UserInfo userInfo) { + PersonalScheduleResponse scheduleResponse = personalScheduleService.updateSchedule(id, scheduleRequest, userInfo); + return CommonUtils.success(scheduleResponse); + } +} diff --git a/src/main/java/com/tukorea/planding/domain/schedule/controller/ScheduleController.java b/src/main/java/com/tukorea/planding/domain/schedule/controller/ScheduleController.java deleted file mode 100644 index bb76f9d..0000000 --- a/src/main/java/com/tukorea/planding/domain/schedule/controller/ScheduleController.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.tukorea.planding.domain.schedule.controller; - -import com.tukorea.planding.common.CommonResponse; -import com.tukorea.planding.common.CommonUtils; -import com.tukorea.planding.domain.schedule.service.ScheduleService; -import com.tukorea.planding.domain.user.dto.UserInfo; -import com.tukorea.planding.domain.schedule.dto.ScheduleRequest; -import com.tukorea.planding.domain.schedule.dto.ScheduleResponse; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.*; - -import java.time.LocalDate; -import java.util.List; - -@Tag(name = "Schedule", description = "스케줄 CRUD") -@RestController -@RequiredArgsConstructor -@RequestMapping("/api/v1/schedule") -public class ScheduleController { - - private final ScheduleService scheduleService; - - @Operation(summary = "오늘 스케줄 조회") - @GetMapping("/today") - public CommonResponse> showTodaySchedule(@AuthenticationPrincipal UserInfo userInfo) { - List responses = scheduleService.showTodaySchedule(userInfo); - return CommonUtils.success(responses); - } - - @Operation(summary = "공통: 스케쥴 생성을 할 때 내가 포함된 모든 그룹, 개인 시간때에 스케쥴을 확인") - @PostMapping("/overlap") - public CommonResponse> findOverlapSchedule(@AuthenticationPrincipal UserInfo userInfo, @RequestBody ScheduleRequest scheduleRequest) { - List scheduleResponses = scheduleService.findOverlapSchedule(userInfo.getId(), scheduleRequest); - return CommonUtils.success(scheduleResponses); - } - - @Operation(summary = "개인 스케줄: 생성") - @PostMapping() - public CommonResponse createSchedule(@AuthenticationPrincipal UserInfo userInfo, @RequestBody ScheduleRequest scheduleRequest) { - ScheduleResponse response = scheduleService.createSchedule(userInfo, scheduleRequest); - return CommonUtils.success(response); - } - - @Operation(summary = "개인 스케줄: 삭제") - @DeleteMapping("/{id}") - public ResponseEntity deleteSchedule(@AuthenticationPrincipal UserInfo userInfo, @PathVariable Long id) { - scheduleService.deleteSchedule(userInfo, id); - return new ResponseEntity<>(HttpStatus.OK); - } - - @Operation(summary = "개인 스케줄: 조회") - @GetMapping("/{schedule_id}") - public CommonResponse getScheduleById(@PathVariable(name = "schedule_id") Long id, @AuthenticationPrincipal UserInfo userInfo) { - ScheduleResponse scheduleResponse = scheduleService.getSchedule(id, userInfo); - return CommonUtils.success(scheduleResponse); - } - - @Operation(summary = "개인 스케줄: 주간으로 가져오기") - @GetMapping("/week/{startDate}/{endDate}") - public CommonResponse> getWeekSchedule(@PathVariable(name = "startDate") LocalDate startDate, - @PathVariable(name = "endDate") LocalDate endDate - , @AuthenticationPrincipal UserInfo userInfo) { - List scheduleResponse = scheduleService.getWeekSchedule(startDate, endDate, userInfo); - return CommonUtils.success(scheduleResponse); - } - - //TODO 아직 요구사항 미정 - @Operation(summary = "개인 스케줄: 제목,내용,시작시간,끝낼시간 항목 수정") - @PatchMapping("/{schedule_id}") - public CommonResponse updateSchedule(@PathVariable(name = "schedule_id") Long id, @RequestBody ScheduleRequest scheduleRequest, @AuthenticationPrincipal UserInfo userInfo) { - ScheduleResponse scheduleResponse = scheduleService.updateSchedule(id, scheduleRequest, userInfo); - return CommonUtils.success(scheduleResponse); - } - - /* - 그룹룸 스케줄관련 코드 - */ - @Operation(summary = "그룹 스케줄: 작성 목록 조회") - @GetMapping("/groupRoom/{groupRoomId}") - public CommonResponse> getSchedulesByGroupRoom(@PathVariable Long groupRoomId, @AuthenticationPrincipal UserInfo userInfo) { - List scheduleResponses = scheduleService.getSchedulesByGroupRoom(groupRoomId, userInfo); - return CommonUtils.success(scheduleResponses); - } - - @Operation(summary = "그룹 스케줄: 조회") - @GetMapping("/groupRoom/{groupRoomId}/{scheduleId}") - public CommonResponse getGroupSchedule(@PathVariable Long groupRoomId, @PathVariable Long scheduleId, @AuthenticationPrincipal UserInfo userInfo) { - ScheduleResponse scheduleResponses = scheduleService.getGroupSchedule(groupRoomId, scheduleId, userInfo); - return CommonUtils.success(scheduleResponses); - } - - @Operation(summary = "그룹 스케줄: 스케줄 수정") - @PatchMapping("/groupRoom/{groupRoomId}/{scheduleId}") - public CommonResponse updateScheduleByGroupRoom(@PathVariable Long groupRoomId, @PathVariable Long scheduleId, @RequestBody ScheduleRequest scheduleRequest, @AuthenticationPrincipal UserInfo userInfo) { - ScheduleResponse scheduleResponse = scheduleService.updateScheduleByGroupRoom(groupRoomId, scheduleId, scheduleRequest, userInfo); - return CommonUtils.success(scheduleResponse); - } - - @Operation(summary = "그룹 스케줄: 스케줄 삭제") - @DeleteMapping("/groupRoom/{groupRoomId}/{scheduleId}") - public ResponseEntity deleteScheduleByGroupRoom(@PathVariable Long groupRoomId, @PathVariable Long scheduleId, @AuthenticationPrincipal UserInfo userInfo) { - scheduleService.deleteScheduleByGroupRoom(groupRoomId, scheduleId, userInfo); - return new ResponseEntity<>(HttpStatus.OK); - } -} diff --git a/src/main/java/com/tukorea/planding/domain/schedule/dto/GroupScheduleAttendanceRequest.java b/src/main/java/com/tukorea/planding/domain/schedule/dto/request/GroupScheduleAttendanceRequest.java similarity index 78% rename from src/main/java/com/tukorea/planding/domain/schedule/dto/GroupScheduleAttendanceRequest.java rename to src/main/java/com/tukorea/planding/domain/schedule/dto/request/GroupScheduleAttendanceRequest.java index ca16303..98c57f7 100644 --- a/src/main/java/com/tukorea/planding/domain/schedule/dto/GroupScheduleAttendanceRequest.java +++ b/src/main/java/com/tukorea/planding/domain/schedule/dto/request/GroupScheduleAttendanceRequest.java @@ -1,4 +1,4 @@ -package com.tukorea.planding.domain.schedule.dto; +package com.tukorea.planding.domain.schedule.dto.request; import com.tukorea.planding.domain.schedule.entity.ScheduleStatus; import lombok.Builder; diff --git a/src/main/java/com/tukorea/planding/domain/schedule/dto/request/GroupScheduleRequest.java b/src/main/java/com/tukorea/planding/domain/schedule/dto/request/GroupScheduleRequest.java new file mode 100644 index 0000000..bc364ec --- /dev/null +++ b/src/main/java/com/tukorea/planding/domain/schedule/dto/request/GroupScheduleRequest.java @@ -0,0 +1,17 @@ +package com.tukorea.planding.domain.schedule.dto.request; + +import lombok.Builder; + +import java.time.LocalDate; +import java.time.LocalTime; + +@Builder +public record GroupScheduleRequest( + String userCode, + String title, + String content, + LocalDate scheduleDate, + LocalTime startTime, + LocalTime endTime +) { +} diff --git a/src/main/java/com/tukorea/planding/domain/schedule/dto/ScheduleRequest.java b/src/main/java/com/tukorea/planding/domain/schedule/dto/request/ScheduleRequest.java similarity index 83% rename from src/main/java/com/tukorea/planding/domain/schedule/dto/ScheduleRequest.java rename to src/main/java/com/tukorea/planding/domain/schedule/dto/request/ScheduleRequest.java index b811664..2b9b7ec 100644 --- a/src/main/java/com/tukorea/planding/domain/schedule/dto/ScheduleRequest.java +++ b/src/main/java/com/tukorea/planding/domain/schedule/dto/request/ScheduleRequest.java @@ -1,4 +1,4 @@ -package com.tukorea.planding.domain.schedule.dto; +package com.tukorea.planding.domain.schedule.dto.request; import lombok.Builder; diff --git a/src/main/java/com/tukorea/planding/domain/schedule/dto/response/GroupScheduleResponse.java b/src/main/java/com/tukorea/planding/domain/schedule/dto/response/GroupScheduleResponse.java new file mode 100644 index 0000000..6feac49 --- /dev/null +++ b/src/main/java/com/tukorea/planding/domain/schedule/dto/response/GroupScheduleResponse.java @@ -0,0 +1,38 @@ +package com.tukorea.planding.domain.schedule.dto.response; + +import com.tukorea.planding.domain.schedule.entity.Schedule; +import com.tukorea.planding.domain.schedule.entity.ScheduleType; +import lombok.Builder; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.List; + +@Builder +public record GroupScheduleResponse( + Long id, + String title, + String content, + LocalDate scheduleDate, + LocalTime startTime, + LocalTime endTime, + boolean isComplete, + ScheduleType type, + String groupName, + List userScheduleAttendances +) { + public static GroupScheduleResponse from(Schedule schedule, String groupName, List attendances) { + return GroupScheduleResponse.builder() + .id(schedule.getId()) + .title(schedule.getTitle()) + .content(schedule.getContent()) + .scheduleDate(schedule.getScheduleDate()) + .startTime(schedule.getStartTime()) + .endTime(schedule.getEndTime()) + .isComplete(schedule.isComplete()) + .type(ScheduleType.GROUP) + .groupName(groupName) + .userScheduleAttendances(attendances) + .build(); + } +} diff --git a/src/main/java/com/tukorea/planding/domain/schedule/dto/response/PersonalScheduleResponse.java b/src/main/java/com/tukorea/planding/domain/schedule/dto/response/PersonalScheduleResponse.java new file mode 100644 index 0000000..2ad6a0e --- /dev/null +++ b/src/main/java/com/tukorea/planding/domain/schedule/dto/response/PersonalScheduleResponse.java @@ -0,0 +1,40 @@ +package com.tukorea.planding.domain.schedule.dto.response; + +import com.tukorea.planding.domain.schedule.entity.Schedule; +import com.tukorea.planding.domain.schedule.entity.ScheduleType; +import lombok.Builder; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.Comparator; + +@Builder +public record PersonalScheduleResponse( + Long id, + String title, + String content, + LocalDate scheduleDate, + LocalTime startTime, + LocalTime endTime, + boolean complete, + ScheduleType type +) { + + public static PersonalScheduleResponse from(Schedule schedule) { + return PersonalScheduleResponse.builder() + .id(schedule.getId()) + .title(schedule.getTitle()) + .content(schedule.getContent()) + .scheduleDate(schedule.getScheduleDate()) + .startTime(schedule.getStartTime()) + .endTime(schedule.getEndTime()) + .complete(schedule.isComplete()) + .type(ScheduleType.PERSONAL) + .build(); + } + + + public static Comparator getComparatorByStartTime() { + return Comparator.comparing(schedule -> schedule.startTime()); + } +} diff --git a/src/main/java/com/tukorea/planding/domain/schedule/dto/ScheduleResponse.java b/src/main/java/com/tukorea/planding/domain/schedule/dto/response/ScheduleResponse.java similarity index 72% rename from src/main/java/com/tukorea/planding/domain/schedule/dto/ScheduleResponse.java rename to src/main/java/com/tukorea/planding/domain/schedule/dto/response/ScheduleResponse.java index 09a1d38..3be20b5 100644 --- a/src/main/java/com/tukorea/planding/domain/schedule/dto/ScheduleResponse.java +++ b/src/main/java/com/tukorea/planding/domain/schedule/dto/response/ScheduleResponse.java @@ -1,6 +1,7 @@ -package com.tukorea.planding.domain.schedule.dto; +package com.tukorea.planding.domain.schedule.dto.response; import com.tukorea.planding.domain.schedule.entity.Schedule; +import com.tukorea.planding.domain.schedule.entity.ScheduleType; import lombok.Builder; import java.time.LocalDate; @@ -15,7 +16,9 @@ public record ScheduleResponse( LocalDate scheduleDate, LocalTime startTime, LocalTime endTime, - boolean complete + boolean complete, + String groupName, + ScheduleType type ) { public static ScheduleResponse from(Schedule schedule) { @@ -27,9 +30,12 @@ public static ScheduleResponse from(Schedule schedule) { .startTime(schedule.getStartTime()) .endTime(schedule.getEndTime()) .complete(schedule.isComplete()) + .type(schedule.getType()) + .groupName(schedule.getType() == ScheduleType.GROUP ? schedule.getGroupSchedule().getGroupRoom().getName() : null) .build(); } + public static Comparator getComparatorByStartTime() { return Comparator.comparing(schedule -> schedule.startTime()); } diff --git a/src/main/java/com/tukorea/planding/domain/schedule/dto/response/UserScheduleAttendance.java b/src/main/java/com/tukorea/planding/domain/schedule/dto/response/UserScheduleAttendance.java new file mode 100644 index 0000000..fc831af --- /dev/null +++ b/src/main/java/com/tukorea/planding/domain/schedule/dto/response/UserScheduleAttendance.java @@ -0,0 +1,11 @@ +package com.tukorea.planding.domain.schedule.dto.response; + +import com.tukorea.planding.domain.schedule.entity.ScheduleStatus; + +public record UserScheduleAttendance( + String userCode, + String userName, + ScheduleStatus status +) { + +} diff --git a/src/main/java/com/tukorea/planding/domain/schedule/entity/GroupSchedule.java b/src/main/java/com/tukorea/planding/domain/schedule/entity/GroupSchedule.java new file mode 100644 index 0000000..8385625 --- /dev/null +++ b/src/main/java/com/tukorea/planding/domain/schedule/entity/GroupSchedule.java @@ -0,0 +1,32 @@ +package com.tukorea.planding.domain.schedule.entity; + +import com.tukorea.planding.domain.group.entity.GroupRoom; +import jakarta.persistence.*; +import lombok.*; + +import java.util.HashSet; +import java.util.Set; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "GROUP_SCHEDULE") +public class GroupSchedule { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "group_schedule_id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "group_room_id") + private GroupRoom groupRoom; + + @OneToMany(mappedBy = "groupSchedule", cascade = CascadeType.ALL, orphanRemoval = true) + private Set schedules = new HashSet<>(); + + @Builder + public GroupSchedule(GroupRoom groupRoom) { + this.groupRoom = groupRoom; + } +} diff --git a/src/main/java/com/tukorea/planding/domain/schedule/entity/PersonalSchedule.java b/src/main/java/com/tukorea/planding/domain/schedule/entity/PersonalSchedule.java new file mode 100644 index 0000000..64706ac --- /dev/null +++ b/src/main/java/com/tukorea/planding/domain/schedule/entity/PersonalSchedule.java @@ -0,0 +1,40 @@ +package com.tukorea.planding.domain.schedule.entity; + +import com.tukorea.planding.domain.user.entity.User; +import com.tukorea.planding.global.error.BusinessException; +import com.tukorea.planding.global.error.ErrorCode; +import jakarta.persistence.*; +import lombok.*; + +import java.util.HashSet; +import java.util.Set; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "PERSONAL_SCHEDULE") +public class PersonalSchedule { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "personal_schedule_id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; + + @OneToMany(mappedBy = "personalSchedule", cascade = CascadeType.ALL, orphanRemoval = true) + private Set schedules = new HashSet<>(); + + @Builder + public PersonalSchedule(User user) { + this.user = user; + } + + public void checkOwnership(Long userId) throws BusinessException { + if (!this.user.getId().equals(userId)) { + throw new BusinessException(ErrorCode.UNAUTHORIZED_SCHEDULE); + } + } +} diff --git a/src/main/java/com/tukorea/planding/domain/schedule/entity/Schedule.java b/src/main/java/com/tukorea/planding/domain/schedule/entity/Schedule.java index 0289df4..5257af6 100644 --- a/src/main/java/com/tukorea/planding/domain/schedule/entity/Schedule.java +++ b/src/main/java/com/tukorea/planding/domain/schedule/entity/Schedule.java @@ -41,30 +41,29 @@ public class Schedule extends BaseEntity { @Column(name = "complete", nullable = false) private boolean isComplete; + @Enumerated(EnumType.STRING) + @Column(name = "type", nullable = false) + private ScheduleType type; + @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "group_room_id") - private GroupRoom groupRoom; + @JoinColumn(name = "personal_schedule_id") + private PersonalSchedule personalSchedule; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "user_id") - private User user; + @JoinColumn(name = "group_schedule_id") + private GroupSchedule groupSchedule; @Builder - public Schedule(String title, String content, LocalDate scheduleDate, LocalTime startTime, LocalTime endTime, boolean isComplete, GroupRoom groupRoom, User user) { + public Schedule(String title, String content, LocalDate scheduleDate, LocalTime startTime, LocalTime endTime, boolean isComplete, ScheduleType type, PersonalSchedule personalSchedule, GroupSchedule groupSchedule) { this.title = title; this.content = content; this.scheduleDate = scheduleDate; this.startTime = startTime; this.endTime = endTime; this.isComplete = isComplete; - this.groupRoom = groupRoom; - this.user = user; - } - - public void checkOwnership(Long userId) throws BusinessException { - if (!this.user.getId().equals(userId)) { - throw new BusinessException(ErrorCode.UNAUTHORIZED_SCHEDULE); - } + this.type = type; + this.personalSchedule = personalSchedule; + this.groupSchedule = groupSchedule; } public void update(String title, String content, LocalTime startTime, LocalTime endTime) { @@ -77,18 +76,4 @@ public void update(String title, String content, LocalTime startTime, LocalTime Optional.ofNullable(startTime).ifPresent(value -> this.startTime = value); Optional.ofNullable(endTime).ifPresent(value -> this.endTime = value); } - - public void toggleComplete() { - if (isComplete) { - this.isComplete = false; - return; - } - this.isComplete = true; - } - - public void addUser(User user) { - this.user = user; - user.getSchedules().add(this); - } - } diff --git a/src/main/java/com/tukorea/planding/domain/schedule/entity/ScheduleType.java b/src/main/java/com/tukorea/planding/domain/schedule/entity/ScheduleType.java new file mode 100644 index 0000000..de5ab82 --- /dev/null +++ b/src/main/java/com/tukorea/planding/domain/schedule/entity/ScheduleType.java @@ -0,0 +1,6 @@ +package com.tukorea.planding.domain.schedule.entity; + +public enum ScheduleType { + PERSONAL, + GROUP +} diff --git a/src/main/java/com/tukorea/planding/domain/schedule/repository/GroupScheduleAttendanceRepository.java b/src/main/java/com/tukorea/planding/domain/schedule/repository/GroupScheduleAttendanceRepository.java index a9796a6..46a97e7 100644 --- a/src/main/java/com/tukorea/planding/domain/schedule/repository/GroupScheduleAttendanceRepository.java +++ b/src/main/java/com/tukorea/planding/domain/schedule/repository/GroupScheduleAttendanceRepository.java @@ -1,11 +1,12 @@ package com.tukorea.planding.domain.schedule.repository; import com.tukorea.planding.domain.schedule.entity.GroupScheduleAttendance; +import com.tukorea.planding.domain.schedule.entity.ScheduleStatus; import org.springframework.data.jpa.repository.JpaRepository; import java.util.Optional; public interface GroupScheduleAttendanceRepository extends JpaRepository { - + Optional findByUserIdAndScheduleIdAndStatusNot(Long userId, Long scheduleId, ScheduleStatus status); Optional findByUserIdAndScheduleId(Long userId, Long scheduleId); } diff --git a/src/main/java/com/tukorea/planding/domain/schedule/repository/GroupScheduleRepository.java b/src/main/java/com/tukorea/planding/domain/schedule/repository/GroupScheduleRepository.java new file mode 100644 index 0000000..53be2e2 --- /dev/null +++ b/src/main/java/com/tukorea/planding/domain/schedule/repository/GroupScheduleRepository.java @@ -0,0 +1,7 @@ +package com.tukorea.planding.domain.schedule.repository; + +import com.tukorea.planding.domain.schedule.entity.GroupSchedule; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface GroupScheduleRepository extends JpaRepository { +} diff --git a/src/main/java/com/tukorea/planding/domain/schedule/repository/PersonalScheduleRepository.java b/src/main/java/com/tukorea/planding/domain/schedule/repository/PersonalScheduleRepository.java new file mode 100644 index 0000000..0b29bee --- /dev/null +++ b/src/main/java/com/tukorea/planding/domain/schedule/repository/PersonalScheduleRepository.java @@ -0,0 +1,7 @@ +package com.tukorea.planding.domain.schedule.repository; + +import com.tukorea.planding.domain.schedule.entity.PersonalSchedule; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PersonalScheduleRepository extends JpaRepository { +} diff --git a/src/main/java/com/tukorea/planding/domain/schedule/repository/ScheduleRepository.java b/src/main/java/com/tukorea/planding/domain/schedule/repository/ScheduleRepository.java index 6274e88..8cbf780 100644 --- a/src/main/java/com/tukorea/planding/domain/schedule/repository/ScheduleRepository.java +++ b/src/main/java/com/tukorea/planding/domain/schedule/repository/ScheduleRepository.java @@ -6,5 +6,4 @@ import java.util.List; public interface ScheduleRepository extends JpaRepository, ScheduleRepositoryCustom { - List findByGroupRoomId(Long groupRoomId); } diff --git a/src/main/java/com/tukorea/planding/domain/schedule/repository/ScheduleRepositoryCustom.java b/src/main/java/com/tukorea/planding/domain/schedule/repository/ScheduleRepositoryCustom.java index 1f59cc5..db3402f 100644 --- a/src/main/java/com/tukorea/planding/domain/schedule/repository/ScheduleRepositoryCustom.java +++ b/src/main/java/com/tukorea/planding/domain/schedule/repository/ScheduleRepositoryCustom.java @@ -37,4 +37,6 @@ public interface ScheduleRepositoryCustom { List findOverlapSchedules(Long userId, LocalDate date, LocalTime startDate, LocalTime endDate); List showTodaySchedule(Long userId); + + List findByGroupRoomId(Long groupRoomId); } diff --git a/src/main/java/com/tukorea/planding/domain/schedule/repository/ScheduleRepositoryCustomImpl.java b/src/main/java/com/tukorea/planding/domain/schedule/repository/ScheduleRepositoryCustomImpl.java index 9df0145..0446c9a 100644 --- a/src/main/java/com/tukorea/planding/domain/schedule/repository/ScheduleRepositoryCustomImpl.java +++ b/src/main/java/com/tukorea/planding/domain/schedule/repository/ScheduleRepositoryCustomImpl.java @@ -8,6 +8,8 @@ import java.time.LocalTime; import java.util.List; +import static com.tukorea.planding.domain.schedule.entity.QGroupSchedule.groupSchedule; +import static com.tukorea.planding.domain.schedule.entity.QPersonalSchedule.personalSchedule; import static com.tukorea.planding.domain.schedule.entity.QSchedule.schedule; @RequiredArgsConstructor @@ -18,20 +20,35 @@ public class ScheduleRepositoryCustomImpl implements ScheduleRepositoryCustom { @Override public List findWeeklyScheduleByUser(LocalDate startDate, LocalDate endDate, Long userId) { return queryFactory.selectFrom(schedule) - .where(schedule.scheduleDate.between(startDate, endDate) - .and(schedule.user.id.eq(userId))) + .leftJoin(schedule.personalSchedule, personalSchedule) + .leftJoin(schedule.groupSchedule, groupSchedule) + .where( + schedule.scheduleDate.between(startDate, endDate) + .and( + personalSchedule.user.id.eq(userId) + .or(groupSchedule.groupRoom.userGroups.any().user.id.eq(userId)) + ) + ) .fetch(); } @Override public List findOverlapSchedules(Long userId, LocalDate date, LocalTime startTime, LocalTime endTime) { return queryFactory.selectFrom(schedule) - .where(schedule.user.id.eq(userId) - .and(schedule.scheduleDate.eq(date) - .and(schedule.startTime.before(endTime)) - .and(schedule.endTime.after(startTime))) - .or(schedule.startTime.between(startTime, endTime)) - .or(schedule.endTime.between(startTime, endTime))) + .leftJoin(schedule.personalSchedule, personalSchedule) + .leftJoin(schedule.groupSchedule, groupSchedule) + .where( + schedule.scheduleDate.eq(date) + .and( + (schedule.startTime.before(endTime).and(schedule.endTime.after(startTime))) + .or(schedule.startTime.between(startTime, endTime)) + .or(schedule.endTime.between(startTime, endTime)) + ) + .and( + personalSchedule.user.id.eq(userId) + .or(groupSchedule.groupRoom.userGroups.any().user.id.eq(userId)) + ) + ) .fetch(); } @@ -39,10 +56,24 @@ public List findOverlapSchedules(Long userId, LocalDate date, LocalTim public List showTodaySchedule(Long userId) { LocalDate today = LocalDate.now(); - return queryFactory - .selectFrom(schedule) - .where(schedule.user.id.eq(userId) - .and(schedule.scheduleDate.eq(today))) + return queryFactory.selectFrom(schedule) + .leftJoin(schedule.personalSchedule, personalSchedule) + .leftJoin(schedule.groupSchedule, groupSchedule) + .where( + schedule.scheduleDate.eq(today) + .and( + personalSchedule.user.id.eq(userId) + .or(groupSchedule.groupRoom.userGroups.any().user.id.eq(userId)) + ) + ) + .fetch(); + } + + @Override + public List findByGroupRoomId(Long groupRoomId) { + return queryFactory.selectFrom(schedule) + .join(schedule.groupSchedule, groupSchedule) + .where(groupSchedule.groupRoom.id.eq(groupRoomId)) .fetch(); } } diff --git a/src/main/java/com/tukorea/planding/domain/schedule/service/CommonScheduleService.java b/src/main/java/com/tukorea/planding/domain/schedule/service/CommonScheduleService.java new file mode 100644 index 0000000..edc5ea3 --- /dev/null +++ b/src/main/java/com/tukorea/planding/domain/schedule/service/CommonScheduleService.java @@ -0,0 +1,40 @@ +package com.tukorea.planding.domain.schedule.service; + +import com.tukorea.planding.domain.schedule.dto.request.ScheduleRequest; +import com.tukorea.planding.domain.schedule.dto.response.ScheduleResponse; +import com.tukorea.planding.domain.user.dto.UserInfo; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class CommonScheduleService { + private final ScheduleQueryService scheduleQueryService; + + @Transactional(readOnly = true) + public List findOverlapSchedule(Long userId, ScheduleRequest scheduleRequest) { + return scheduleQueryService.findOverlapSchedule(userId, scheduleRequest); + } + + @Transactional(readOnly = true) + public List showTodaySchedule(UserInfo userInfo) { + return scheduleQueryService.showTodaySchedule(userInfo.getId()) + .stream() + .map(ScheduleResponse::from) + .collect(Collectors.toList()); + } + + @Transactional(readOnly = true) + public List getWeekSchedule(LocalDate startDate, LocalDate endDate, UserInfo userInfo) { + return scheduleQueryService.findWeeklyScheduleByUser(startDate, endDate, userInfo.getId()) + .stream() + .map(ScheduleResponse::from) + .sorted(ScheduleResponse.getComparatorByStartTime()) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/com/tukorea/planding/domain/schedule/service/GroupScheduleAttendanceService.java b/src/main/java/com/tukorea/planding/domain/schedule/service/GroupScheduleAttendanceService.java index 58b2bc0..a3ae464 100644 --- a/src/main/java/com/tukorea/planding/domain/schedule/service/GroupScheduleAttendanceService.java +++ b/src/main/java/com/tukorea/planding/domain/schedule/service/GroupScheduleAttendanceService.java @@ -1,6 +1,6 @@ package com.tukorea.planding.domain.schedule.service; -import com.tukorea.planding.domain.schedule.dto.GroupScheduleAttendanceRequest; +import com.tukorea.planding.domain.schedule.dto.request.GroupScheduleAttendanceRequest; import com.tukorea.planding.domain.schedule.entity.GroupScheduleAttendance; import com.tukorea.planding.domain.schedule.entity.Schedule; import com.tukorea.planding.domain.schedule.repository.GroupScheduleAttendanceRepository; diff --git a/src/main/java/com/tukorea/planding/domain/schedule/service/GroupScheduleService.java b/src/main/java/com/tukorea/planding/domain/schedule/service/GroupScheduleService.java index 11e73a4..915e703 100644 --- a/src/main/java/com/tukorea/planding/domain/schedule/service/GroupScheduleService.java +++ b/src/main/java/com/tukorea/planding/domain/schedule/service/GroupScheduleService.java @@ -1,19 +1,26 @@ package com.tukorea.planding.domain.schedule.service; +import com.tukorea.planding.domain.group.service.UserGroupService; +import com.tukorea.planding.domain.group.service.query.UserGroupQueryService; +import com.tukorea.planding.domain.schedule.dto.response.GroupScheduleResponse; import com.tukorea.planding.domain.group.entity.GroupRoom; -import com.tukorea.planding.domain.group.repository.normal.GroupRoomRepository; +import com.tukorea.planding.domain.group.entity.UserGroup; import com.tukorea.planding.domain.group.repository.usergroup.UserGroupRepository; +import com.tukorea.planding.domain.group.service.query.GroupQueryService; import com.tukorea.planding.domain.notify.dto.NotificationScheduleRequest; import com.tukorea.planding.domain.notify.entity.NotificationType; import com.tukorea.planding.domain.notify.service.NotificationService; -import com.tukorea.planding.domain.schedule.dto.ScheduleRequest; -import com.tukorea.planding.domain.schedule.entity.Schedule; +import com.tukorea.planding.domain.schedule.dto.request.ScheduleRequest; +import com.tukorea.planding.domain.schedule.dto.response.UserScheduleAttendance; +import com.tukorea.planding.domain.schedule.entity.*; +import com.tukorea.planding.domain.schedule.repository.GroupScheduleAttendanceRepository; +import com.tukorea.planding.domain.schedule.repository.GroupScheduleRepository; +import com.tukorea.planding.domain.user.dto.UserInfo; import com.tukorea.planding.domain.user.entity.User; import com.tukorea.planding.domain.user.service.UserQueryService; import com.tukorea.planding.global.error.BusinessException; import com.tukorea.planding.global.error.ErrorCode; -import com.tukorea.planding.domain.schedule.repository.ScheduleRepository; -import com.tukorea.planding.domain.schedule.dto.ScheduleResponse; +import com.tukorea.planding.domain.schedule.dto.response.ScheduleResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -21,57 +28,61 @@ import java.time.LocalDateTime; import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import static com.tukorea.planding.domain.group.entity.QGroupRoom.groupRoom; @Service @Slf4j @RequiredArgsConstructor public class GroupScheduleService { - private final ScheduleRepository scheduleRepository; - private final GroupRoomRepository groupRoomRepository; + private final ScheduleQueryService scheduleQueryService; + private final GroupQueryService groupQueryService; private final UserQueryService userQueryService; private final NotificationService notificationService; private final UserGroupRepository userGroupRepository; + private final GroupScheduleRepository groupScheduleRepository; + private final GroupScheduleAttendanceRepository groupScheduleAttendanceRepository; + private final UserGroupQueryService userGroupQueryService; + @Transactional public ScheduleResponse createGroupSchedule(String groupCode, ScheduleRequest requestSchedule) { - - // [1] 작성한 유저 User user = userQueryService.getUserByUserCode(requestSchedule.userCode()); + GroupRoom groupRoom = groupQueryService.getGroupByCode(groupCode); - // [2] 그룹방 - GroupRoom groupRoom = groupRoomRepository.findByGroupCode(groupCode) - .orElseThrow(() -> new BusinessException(ErrorCode.GROUP_ROOM_NOT_FOUND)); + userGroupQueryService.checkUserAccessToGroupRoom(groupRoom.getId(), user.getId()); - // [3] 스케줄 생성 - Schedule schedule = Schedule.builder() + GroupSchedule groupSchedule = GroupSchedule.builder() + .groupRoom(groupRoom) + .build(); + + Schedule newSchedule = Schedule.builder() .title(requestSchedule.title()) .content(requestSchedule.content()) .scheduleDate(requestSchedule.scheduleDate()) .startTime(requestSchedule.startTime()) .endTime(requestSchedule.endTime()) .isComplete(false) - .groupRoom(groupRoom) + .groupSchedule(groupSchedule) + .type(ScheduleType.GROUP) .build(); - schedule.addUser(user); - groupRoom.addSchedule(schedule); - - Schedule save = scheduleRepository.save(schedule); - - // [4] 그룹에 속해있는 유저 중 접속상태가 false인 유저 - List notificationUser = userGroupRepository.findUserByIsConnectionFalse(groupRoom.getId()); + groupSchedule.getSchedules().add(newSchedule); + groupScheduleRepository.save(groupSchedule); + Schedule savedSchedule = scheduleQueryService.save(newSchedule); - // [5] 그룹 스케줄 생성 - String createUrl = groupRoom.getGroupCode() + "/schedule/" + save.getId(); //TODO 추후 수정 + List notificationUsers = userGroupRepository.findUserByIsConnectionFalse(groupRoom.getId()); + String createUrl = groupRoom.getGroupCode() + "/schedule/" + savedSchedule.getId(); - - // [6] 그룹 구성원들에게 스케줄 생성 알림 전송 - for (User member : notificationUser) { + for (User member : notificationUsers) { NotificationScheduleRequest request = NotificationScheduleRequest.builder() .receiverCode(member.getUserCode()) .createdAt(LocalDateTime.now()) - .message(save.getTitle()) + .message(savedSchedule.getTitle()) .groupName(groupRoom.getName()) .type(NotificationType.GROUP_SCHEDULE) .url(createUrl) @@ -79,7 +90,101 @@ public ScheduleResponse createGroupSchedule(String groupCode, ScheduleRequest re notificationService.send(request); } - return ScheduleResponse.from(save); + return ScheduleResponse.from(savedSchedule); + } + + /* + 그룹룸 스케줄관련 코드 + + */ + + // 그룹룸에서 스케줄을 찾아 + // 스케줄과 유저의 참여여부를 비교 + // 현재 쿼리 8번 + // 유저 , 스케줄, 그룹, 그룹유저, 참여여부 2명 조회 + public GroupScheduleResponse getGroupScheduleById(UserInfo userInfo, Long groupRoomId, Long scheduleId) { + // 유저 프로필을 조회합니다. + User user = userQueryService.getUserProfile(userInfo.getId()); + + // 해당 스케줄의 그룹룸을 가져옵니다. + GroupRoom groupRoom = groupQueryService.getGroupById(groupRoomId); + + // 스케줄을 조회합니다. + Schedule schedule = scheduleQueryService.findScheduleById(scheduleId); + + // 그룹룸에 속한 유저 그룹들의 목록을 가져옵니다. + Set userGroups = groupRoom.getUserGroups(); + + // 유저가 해당 그룹에 속해 있는지 확인합니다. + boolean isUserInGroup = userGroups.stream() + .anyMatch(userGroup -> userGroup.getUser().getId().equals(userInfo.getId())); + + if (!isUserInGroup) { + // 유저가 그룹에 속해 있지 않다면, 예외 처리를 합니다. + throw new BusinessException(ErrorCode.ACCESS_DENIED); + } + + // 유저가 그룹에 속해 있다면, 필요한 스케줄 정보를 반환합니다. + // GroupScheduleResponse 구성 로직은 여기에 추가합니다. + return GroupScheduleResponse.from(schedule, groupRoom.getName(), getUserScheduleAttendances(groupRoom, userInfo.getId(), scheduleId)); + } + + private List getUserScheduleAttendances(GroupRoom groupRoom, Long userId, Long scheduleId) { + return groupRoom.getUserGroups().stream() + .map(userGroup -> { + // 실제 출석 상태를 데이터베이스에서 조회하거나 다른 로직을 통해 결정합니다. + Optional attendance = groupScheduleAttendanceRepository.findByUserIdAndScheduleIdAndStatusNot(userId, scheduleId, ScheduleStatus.UNDECIDED); + + ScheduleStatus status = attendance + .map(GroupScheduleAttendance::getStatus) + .orElse(ScheduleStatus.UNDECIDED); + + return new UserScheduleAttendance( + userGroup.getUser().getUserCode(), + userGroup.getUser().getUsername(), + status + ); + }) + // UNDECIDED인 상태 제외 + .collect(Collectors.toList()); + } + + + @Transactional(readOnly = true) + public List getSchedulesByGroupRoom(Long groupRoomId, UserInfo userInfo) { + // [1] 유저가 그룹룸에 접근할 권리가있는지 확인 + checkUserAccessToGroupRoom(groupRoomId, userInfo.getId()); + // [2] 그룹룸 ID를 기반으로 스케줄을 조회 + List schedules = scheduleQueryService.findByGroupRoomId(groupRoomId); + GroupRoom groupRoom = groupQueryService.getGroupById(groupRoomId); + // [3] dto 반환 + return scheduleQueryService.findByGroupRoomId(groupRoomId).stream() + .map(schedule -> { + List attendances = getUserScheduleAttendances(groupRoom, userInfo.getId(), schedule.getId()); + return GroupScheduleResponse.from(schedule, groupRoom.getName(), attendances); + }) + .collect(Collectors.toList()); } + public ScheduleResponse updateScheduleByGroupRoom(Long groupRoomId, Long scheduleId, ScheduleRequest scheduleRequest, UserInfo userInfo) { + // [1] 그룹룸에 수정하려는 유저가 존재하는지 확인 + checkUserAccessToGroupRoom(groupRoomId, userInfo.getId()); + // [2] 스케줄을 업데이트 + Schedule schedule = scheduleQueryService.findScheduleById(scheduleId); + schedule.update(scheduleRequest.title(), scheduleRequest.content(), scheduleRequest.startTime(), scheduleRequest.endTime()); + // [3] dto 반환 + return ScheduleResponse.from(schedule); + } + + + public void deleteScheduleByGroupRoom(Long groupRoomId, Long scheduleId, UserInfo userInfo) { + checkUserAccessToGroupRoom(groupRoomId, userInfo.getId()); + scheduleQueryService.deleteById(scheduleId); + } + + private void checkUserAccessToGroupRoom(Long groupRoomId, Long userId) { + userGroupQueryService.checkUserAccessToGroupRoom(groupRoomId, userId); + } + + } diff --git a/src/main/java/com/tukorea/planding/domain/schedule/service/PersonalScheduleService.java b/src/main/java/com/tukorea/planding/domain/schedule/service/PersonalScheduleService.java new file mode 100644 index 0000000..a06d643 --- /dev/null +++ b/src/main/java/com/tukorea/planding/domain/schedule/service/PersonalScheduleService.java @@ -0,0 +1,79 @@ +package com.tukorea.planding.domain.schedule.service; + +import com.tukorea.planding.domain.schedule.dto.request.ScheduleRequest; +import com.tukorea.planding.domain.schedule.dto.response.PersonalScheduleResponse; +import com.tukorea.planding.domain.schedule.dto.response.ScheduleResponse; +import com.tukorea.planding.domain.schedule.entity.PersonalSchedule; +import com.tukorea.planding.domain.schedule.entity.Schedule; +import com.tukorea.planding.domain.schedule.entity.ScheduleType; +import com.tukorea.planding.domain.schedule.repository.PersonalScheduleRepository; +import com.tukorea.planding.domain.user.dto.UserInfo; +import com.tukorea.planding.domain.user.entity.User; +import com.tukorea.planding.domain.user.service.UserQueryService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.util.List; +import java.util.stream.Collectors; + +@Service +@Transactional +@RequiredArgsConstructor +public class PersonalScheduleService { + + private final ScheduleQueryService scheduleQueryService; + private final UserQueryService userQueryService; + private final PersonalScheduleRepository personalScheduleRepository; + + public PersonalScheduleResponse createSchedule(UserInfo userInfo, ScheduleRequest scheduleRequest) { + User user = userQueryService.getUserByUserCode(userInfo.getUserCode()); + + // 개인 스케줄 생성 + PersonalSchedule personalSchedule = PersonalSchedule.builder() + .user(user) + .build(); + + Schedule newSchedule = Schedule.builder() + .personalSchedule(personalSchedule) + .title(scheduleRequest.title()) + .content(scheduleRequest.content()) + .scheduleDate(scheduleRequest.scheduleDate()) + .startTime(scheduleRequest.startTime()) + .endTime(scheduleRequest.endTime()) + .isComplete(false) + .type(ScheduleType.PERSONAL) + .build(); + + // 개인 스케줄에 스케줄 추가 + personalSchedule.getSchedules().add(newSchedule); + + personalScheduleRepository.save(personalSchedule); + + Schedule save = scheduleQueryService.save(newSchedule); + + return PersonalScheduleResponse.from(save); + } + + @Transactional(readOnly = true) + public PersonalScheduleResponse getSchedule(Long scheduleId, UserInfo userInfo) { + Schedule schedule = scheduleQueryService.findScheduleById(scheduleId); + schedule.getPersonalSchedule().checkOwnership(userInfo.getId()); + return PersonalScheduleResponse.from(schedule); + } + + public void deleteSchedule(UserInfo userInfo, Long scheduleId) { + Schedule schedule = scheduleQueryService.findScheduleById(scheduleId); + schedule.getPersonalSchedule().checkOwnership(userInfo.getId()); + scheduleQueryService.delete(schedule); + } + + + public PersonalScheduleResponse updateSchedule(Long scheduleId, ScheduleRequest scheduleRequest, UserInfo userInfo) { + Schedule schedule = scheduleQueryService.findScheduleById(scheduleId); + schedule.getPersonalSchedule().checkOwnership(userInfo.getId()); + schedule.update(scheduleRequest.title(), scheduleRequest.content(), scheduleRequest.startTime(), scheduleRequest.endTime()); + return PersonalScheduleResponse.from(schedule); + } +} diff --git a/src/main/java/com/tukorea/planding/domain/schedule/service/ScheduleQueryService.java b/src/main/java/com/tukorea/planding/domain/schedule/service/ScheduleQueryService.java index 8cf880f..cedc8fa 100644 --- a/src/main/java/com/tukorea/planding/domain/schedule/service/ScheduleQueryService.java +++ b/src/main/java/com/tukorea/planding/domain/schedule/service/ScheduleQueryService.java @@ -1,7 +1,8 @@ package com.tukorea.planding.domain.schedule.service; -import com.tukorea.planding.domain.schedule.dto.ScheduleRequest; -import com.tukorea.planding.domain.schedule.dto.ScheduleResponse; +import com.tukorea.planding.domain.schedule.dto.request.ScheduleRequest; +import com.tukorea.planding.domain.schedule.dto.response.PersonalScheduleResponse; +import com.tukorea.planding.domain.schedule.dto.response.ScheduleResponse; import com.tukorea.planding.domain.schedule.entity.Schedule; import com.tukorea.planding.domain.schedule.repository.ScheduleRepository; import com.tukorea.planding.global.error.BusinessException; diff --git a/src/main/java/com/tukorea/planding/domain/schedule/service/ScheduleService.java b/src/main/java/com/tukorea/planding/domain/schedule/service/ScheduleService.java deleted file mode 100644 index d46a62e..0000000 --- a/src/main/java/com/tukorea/planding/domain/schedule/service/ScheduleService.java +++ /dev/null @@ -1,124 +0,0 @@ -package com.tukorea.planding.domain.schedule.service; - -import com.tukorea.planding.domain.group.service.UserGroupService; -import com.tukorea.planding.domain.user.entity.User; -import com.tukorea.planding.domain.user.dto.UserInfo; -import com.tukorea.planding.domain.user.service.UserQueryService; -import com.tukorea.planding.domain.schedule.entity.Schedule; -import com.tukorea.planding.domain.schedule.dto.ScheduleRequest; -import com.tukorea.planding.domain.schedule.dto.ScheduleResponse; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDate; -import java.util.List; -import java.util.stream.Collectors; - -@Service -@Transactional -@RequiredArgsConstructor -public class ScheduleService { - - private final ScheduleQueryService scheduleQueryService; - private final UserGroupService userGroupService; - private final UserQueryService userQueryService; - - public ScheduleResponse createSchedule(UserInfo userInfo, ScheduleRequest scheduleRequest) { - User user = userQueryService.getUserByUserCode(userInfo.getUserCode()); - - Schedule newSchedule = Schedule.builder() - .user(user) - .title(scheduleRequest.title()) - .content(scheduleRequest.content()) - .scheduleDate(scheduleRequest.scheduleDate()) - .startTime(scheduleRequest.startTime()) - .endTime(scheduleRequest.endTime()) - .isComplete(false) - .build(); - - Schedule save = scheduleQueryService.save(newSchedule); - - return ScheduleResponse.from(save); - } - - public ScheduleResponse getSchedule(Long scheduleId, UserInfo userInfo) { - Schedule schedule = scheduleQueryService.findScheduleById(scheduleId); - schedule.checkOwnership(userInfo.getId()); - return ScheduleResponse.from(schedule); - } - - public void deleteSchedule(UserInfo userInfo, Long scheduleId) { - Schedule schedule = scheduleQueryService.findScheduleById(scheduleId); - schedule.checkOwnership(userInfo.getId()); - scheduleQueryService.delete(schedule); - } - - public List getWeekSchedule(LocalDate startDate, LocalDate endDate, UserInfo userInfo) { - return scheduleQueryService.findWeeklyScheduleByUser(startDate, endDate, userInfo.getId()) - .stream() - .map(ScheduleResponse::from) - .sorted(ScheduleResponse.getComparatorByStartTime()) - .collect(Collectors.toList()); - } - - public ScheduleResponse updateSchedule(Long scheduleId, ScheduleRequest scheduleRequest, UserInfo userInfo) { - Schedule schedule = scheduleQueryService.findScheduleById(scheduleId); - schedule.checkOwnership(userInfo.getId()); - schedule.update(scheduleRequest.title(), scheduleRequest.content(), scheduleRequest.startTime(), scheduleRequest.endTime()); - return ScheduleResponse.from(schedule); - } - - /* - 그룹룸 스케줄관련 코드 - - */ - public ScheduleResponse getGroupSchedule(Long groupRoomId, Long scheduleId, UserInfo userInfo) { - checkUserAccessToGroupRoom(groupRoomId, userInfo.getId()); - Schedule schedule = scheduleQueryService.findScheduleById(scheduleId); - return ScheduleResponse.from(schedule); - } - - public List getSchedulesByGroupRoom(Long groupRoomId, UserInfo userInfo) { - // [1] 유저가 그룹룸에 접근할 권리가있는지 확인 - checkUserAccessToGroupRoom(groupRoomId, userInfo.getId()); - // [2] 그룹룸 ID를 기반으로 스케줄을 조회 - List schedules = scheduleQueryService.findByGroupRoomId(groupRoomId); - // [3] dto 반환 - return schedules.stream() - .map(ScheduleResponse::from) - .collect(Collectors.toList()); - } - - public ScheduleResponse updateScheduleByGroupRoom(Long groupRoomId, Long scheduleId, ScheduleRequest scheduleRequest, UserInfo userInfo) { - // [1] 그룹룸에 수정하려는 유저가 존재하는지 확인 - checkUserAccessToGroupRoom(groupRoomId, userInfo.getId()); - // [2] 스케줄을 업데이트 - Schedule schedule = scheduleQueryService.findScheduleById(scheduleId); - schedule.update(scheduleRequest.title(), scheduleRequest.content(), scheduleRequest.startTime(), scheduleRequest.endTime()); - // [3] dto 반환 - return ScheduleResponse.from(schedule); - } - - - public void deleteScheduleByGroupRoom(Long groupRoomId, Long scheduleId, UserInfo userInfo) { - checkUserAccessToGroupRoom(groupRoomId, userInfo.getId()); - scheduleQueryService.deleteById(scheduleId); - } - - public List findOverlapSchedule(Long userId, ScheduleRequest scheduleRequest) { - return scheduleQueryService.findOverlapSchedule(userId, scheduleRequest); - } - - public List showTodaySchedule(UserInfo userInfo) { - return scheduleQueryService.showTodaySchedule(userInfo.getId()) - .stream() - .map(ScheduleResponse::from) - .collect(Collectors.toList()); - } - - private void checkUserAccessToGroupRoom(Long groupRoomId, Long userId) { - userGroupService.checkUserAccessToGroupRoom(groupRoomId, userId); - } - -} diff --git a/src/main/java/com/tukorea/planding/domain/user/service/UserService.java b/src/main/java/com/tukorea/planding/domain/user/service/UserService.java index 7ae8141..95e8036 100644 --- a/src/main/java/com/tukorea/planding/domain/user/service/UserService.java +++ b/src/main/java/com/tukorea/planding/domain/user/service/UserService.java @@ -58,6 +58,7 @@ public ProfileResponse getProfile(UserInfo userInfo) { .username(userProfile.getUsername()) .profileImage(userProfile.getProfileImage()) .groupFavorite((long) userProfile.getGroupFavorites().size()) + .groupRequest((long) 0) .role(Role.USER) .build(); } diff --git a/src/test/java/com/tukorea/planding/global/error/GlobalExceptionControllerTest.java b/src/test/java/com/tukorea/planding/global/error/GlobalExceptionControllerTest.java index dcb9472..e74554c 100644 --- a/src/test/java/com/tukorea/planding/global/error/GlobalExceptionControllerTest.java +++ b/src/test/java/com/tukorea/planding/global/error/GlobalExceptionControllerTest.java @@ -3,7 +3,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.tukorea.planding.global.config.security.SecurityConfig; import com.tukorea.planding.global.config.security.jwt.JwtAuthenticationFilter; -import com.tukorea.planding.domain.schedule.controller.ScheduleController; +import com.tukorea.planding.domain.schedule.controller.PersonalScheduleController; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -31,7 +31,7 @@ @ExtendWith(MockitoExtension.class) @MockBean(JpaMetamodelMappingContext.class) -@WebMvcTest(controllers = {ScheduleController.class, GlobalExceptionController.class},excludeFilters = { +@WebMvcTest(controllers = {PersonalScheduleController.class, GlobalExceptionController.class},excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {SecurityConfig.class, JwtAuthenticationFilter.class})}) class GlobalExceptionControllerTest { diff --git a/src/test/java/com/tukorea/planding/schedule/controller/ScheduleControllerTest.java b/src/test/java/com/tukorea/planding/schedule/controller/PersonalScheduleControllerTest.java similarity index 79% rename from src/test/java/com/tukorea/planding/schedule/controller/ScheduleControllerTest.java rename to src/test/java/com/tukorea/planding/schedule/controller/PersonalScheduleControllerTest.java index e19ca44..eaeb42d 100644 --- a/src/test/java/com/tukorea/planding/schedule/controller/ScheduleControllerTest.java +++ b/src/test/java/com/tukorea/planding/schedule/controller/PersonalScheduleControllerTest.java @@ -1,12 +1,12 @@ package com.tukorea.planding.schedule.controller; import com.fasterxml.jackson.databind.ObjectMapper; -import com.tukorea.planding.domain.schedule.controller.ScheduleController; +import com.tukorea.planding.domain.schedule.controller.PersonalScheduleController; import com.tukorea.planding.domain.user.mapper.UserMapper; import com.tukorea.planding.global.config.security.SecurityConfig; import com.tukorea.planding.global.config.security.jwt.JwtAuthenticationFilter; -import com.tukorea.planding.domain.schedule.dto.ScheduleRequest; -import com.tukorea.planding.domain.schedule.service.ScheduleService; +import com.tukorea.planding.domain.schedule.dto.request.ScheduleRequest; +import com.tukorea.planding.domain.schedule.service.PersonalScheduleService; import com.tukorea.planding.domain.user.entity.User; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -31,15 +31,15 @@ @ExtendWith(MockitoExtension.class) @MockBean(JpaMetamodelMappingContext.class) -@WebMvcTest(controllers = {ScheduleController.class}, excludeFilters = { +@WebMvcTest(controllers = {PersonalScheduleController.class}, excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {SecurityConfig.class, JwtAuthenticationFilter.class})}) -class ScheduleControllerTest { +class PersonalScheduleControllerTest { @MockBean - private ScheduleService scheduleService; + private PersonalScheduleService personalScheduleService; @InjectMocks - private ScheduleController scheduleController; + private PersonalScheduleController personalScheduleController; @Autowired MockMvc mockMvc; @@ -58,7 +58,7 @@ void createSchedule() throws Exception{ .title("test") .build(); - given(scheduleService.createSchedule(UserMapper.toUserInfo(user),schedule)).willThrow(UsernameNotFoundException.class); + given(personalScheduleService.createSchedule(UserMapper.toUserInfo(user),schedule)).willThrow(UsernameNotFoundException.class); ResultActions actions = mockMvc.perform(MockMvcRequestBuilders.post("/api/v1/schedule") diff --git a/src/test/java/com/tukorea/planding/schedule/service/ScheduleServiceTest.java b/src/test/java/com/tukorea/planding/schedule/service/PersonalScheduleServiceTest.java similarity index 59% rename from src/test/java/com/tukorea/planding/schedule/service/ScheduleServiceTest.java rename to src/test/java/com/tukorea/planding/schedule/service/PersonalScheduleServiceTest.java index 778bd02..1c7b2c1 100644 --- a/src/test/java/com/tukorea/planding/schedule/service/ScheduleServiceTest.java +++ b/src/test/java/com/tukorea/planding/schedule/service/PersonalScheduleServiceTest.java @@ -1,11 +1,15 @@ package com.tukorea.planding.schedule.service; -import com.tukorea.planding.domain.schedule.dto.ScheduleRequest; -import com.tukorea.planding.domain.schedule.dto.ScheduleResponse; +import com.tukorea.planding.domain.schedule.dto.request.ScheduleRequest; +import com.tukorea.planding.domain.schedule.dto.response.PersonalScheduleResponse; +import com.tukorea.planding.domain.schedule.dto.response.ScheduleResponse; +import com.tukorea.planding.domain.schedule.entity.PersonalSchedule; import com.tukorea.planding.domain.schedule.entity.Schedule; +import com.tukorea.planding.domain.schedule.repository.PersonalScheduleRepository; +import com.tukorea.planding.domain.schedule.repository.ScheduleRepository; import com.tukorea.planding.domain.schedule.repository.ScheduleRepositoryCustomImpl; import com.tukorea.planding.domain.schedule.service.ScheduleQueryService; -import com.tukorea.planding.domain.schedule.service.ScheduleService; +import com.tukorea.planding.domain.schedule.service.PersonalScheduleService; import com.tukorea.planding.domain.user.entity.SocialType; import com.tukorea.planding.domain.user.entity.User; import com.tukorea.planding.domain.user.mapper.UserMapper; @@ -27,48 +31,41 @@ import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) @Transactional -class ScheduleServiceTest { +class PersonalScheduleServiceTest { @InjectMocks - private ScheduleService scheduleService; + PersonalScheduleService personalScheduleService; @Mock UserQueryService userQueryService; @Mock - ScheduleRepositoryCustomImpl scheduleRepositoryCustomImpl; + ScheduleQueryService scheduleQueryService; @Mock - ScheduleQueryService scheduleQueryService; + ScheduleRepository scheduleRepository; + + @Mock + PersonalScheduleRepository personalScheduleRepository; private User testUser; private Schedule schedule; + private PersonalSchedule personalSchedule; private ScheduleRequest scheduleRequest; - private Schedule createAndSaveSchedule(User user, LocalTime startTime, LocalTime endTime) { - return Schedule.builder() - .user(user) - .scheduleDate(LocalDate.now()) - .title("title") - .content("content") - .startTime(startTime) - .endTime(endTime) - .build(); - } @BeforeEach void setUp() { - testUser = new User("test", "profile", "username", Role.USER, SocialType.KAKAO, null, "#test"); // 테스트용 사용자 정보 초기화 - schedule = new Schedule("title", "content", LocalDate.now(), LocalTime.of(9, 0), LocalTime.of(10, 0), true, null, testUser); + personalSchedule = new PersonalSchedule(testUser); + schedule = new Schedule("title", "content", LocalDate.now(), LocalTime.of(9, 0), LocalTime.of(10, 0), true, personalSchedule, null); scheduleRequest = new ScheduleRequest("#test", "title", "content", LocalDate.now(), LocalTime.of(9, 0), LocalTime.of(10, 0)); } @@ -77,9 +74,10 @@ void setUp() { void create_스케줄_생성() { // given when(scheduleQueryService.save(any(Schedule.class))).thenReturn(schedule); + when(personalScheduleRepository.save(any(PersonalSchedule.class))).thenReturn(personalSchedule); // when - ScheduleResponse result = scheduleService.createSchedule(UserMapper.toUserInfo(testUser), scheduleRequest); + PersonalScheduleResponse result = personalScheduleService.createSchedule(UserMapper.toUserInfo(testUser), scheduleRequest); // then assertNotNull(result); @@ -93,30 +91,31 @@ void setUp() { void delete_스케줄_삭제() { //given when(scheduleQueryService.findScheduleById(1L)).thenReturn(schedule); + doNothing().when(personalSchedule).checkOwnership(1L); //when - scheduleService.deleteSchedule(UserMapper.toUserInfo(testUser), 1L); + personalScheduleService.deleteSchedule(UserMapper.toUserInfo(testUser), 1L); //then verify(scheduleQueryService).delete(schedule); } - @Test - public void 주간개인스케줄_가져오기() { - //given - List responses = Collections.singletonList(schedule); - when(userQueryService.getUserByUserCode(any())).thenReturn(testUser); - when(scheduleRepositoryCustomImpl.findWeeklyScheduleByUser(any(), any(), eq(testUser))).thenReturn(responses); - - //when - List result = scheduleService.getWeekSchedule(LocalDate.now(), LocalDate.now().plusDays(7), UserMapper.toUserInfo(testUser)); - - //then - assertNotNull(result); - assertEquals(1, result.size()); - assertEquals(result.get(0).startTime(), schedule.getStartTime()); - assertEquals(result.get(0).endTime(), schedule.getEndTime()); - } +// @Test +// public void 주간개인스케줄_가져오기() { +// //given +// List responses = Collections.singletonList(schedule); +// when(userQueryService.getUserByUserCode(any())).thenReturn(testUser); +// when(scheduleRepository.findWeeklyScheduleByUser(any(), any(), eq(testUser.getId()))).thenReturn(responses); +// +// //when +// List result = personalScheduleService.getWeekSchedule(LocalDate.now(), LocalDate.now().plusDays(7), UserMapper.toUserInfo(testUser)); +// +// //then +// assertNotNull(result); +// assertEquals(1, result.size()); +// assertEquals(result.get(0).startTime(), schedule.getStartTime()); +// assertEquals(result.get(0).endTime(), schedule.getEndTime()); +// } @Test public void update_스케줄수정() {