Skip to content

Commit

Permalink
#30 [FEAT] 팀원 회고 상황 조회 API
Browse files Browse the repository at this point in the history
  • Loading branch information
yeseul106 committed Jul 17, 2023
1 parent 49f0e22 commit 1f18e6d
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import java.util.*;
import java.util.stream.Collectors;

import static com.puzzling.puzzlingServer.common.util.DateUtil.checkTodayIsReviewDay;

@Service
@RequiredArgsConstructor
public class ProjectServiceImpl implements ProjectService {
Expand Down Expand Up @@ -74,7 +76,7 @@ public ProjectOwnPuzzleResponseDto getMyPuzzles(Long memberId, Long projectId, S
Page<Review> pageReviews = reviewRepository.findTop15ByMemberIdAndProjectId(memberId, projectId, pageable);
List<Review> top15Reviews = pageReviews.getContent();

Boolean isReviewDay = checkTodayIsReviewDay(today, projectId);
Boolean isReviewDay = checkTodayIsReviewDay(today, findProjectById(projectId).getReviewCycle());
Boolean hasTodayReview = reviewRepository.existsReviewByReviewDate(today);

List<PuzzleObjectDto> result = new ArrayList<>();
Expand All @@ -99,7 +101,7 @@ public ProjectTeamPuzzleResponseDto getTeamPuzzles(Principal principal, Long pro
throw new BadRequestException(ErrorStatus.VALIDATION_REQUEST_MISSING_EXCEPTION.getMessage());
}
Long memberId = MemberUtil.getMemberId(principal);
Boolean isReviewDay = checkTodayIsReviewDay(today, projectId);
Boolean isReviewDay = checkTodayIsReviewDay(today, findProjectById(projectId).getReviewCycle());
Boolean hasTodayReview = reviewRepository.existsReviewByReviewDate(today);
List<Review> reviews = reviewRepository.findAllByProjectIdOrderByReviewDateAsc(projectId);

Expand Down Expand Up @@ -232,19 +234,6 @@ private Project findProjectById(Long projectId) {
.orElseThrow(() -> new NotFoundException(ErrorStatus.NOT_FOUND_PROJECT.getMessage()));
}

private Boolean checkTodayIsReviewDay (String today, Long projectId) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate todayDate = LocalDate.parse(today, formatter);

DayOfWeek dayOfWeek = todayDate.getDayOfWeek();
Locale koreanLocale = new Locale("ko", "KR");
String dayOfWeekKorean = dayOfWeek.getDisplayName(TextStyle.SHORT, koreanLocale);

String reviewCycle = findProjectById(projectId).getReviewCycle();
List<String> weekdayList = Arrays.asList(reviewCycle.split(","));
return weekdayList.contains(dayOfWeekKorean);
}

private ProjectMyPuzzleObjectDto mapperMyPuzzleObject(Long memberId, Long projectId) {
Member findMember = findMemberById(memberId);
int puzzleCount = reviewRepository.findByMemberIdAndProjectId(memberId, projectId).size();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.puzzling.puzzlingServer.api.review.dto.request.ReviewAARRequestDto;
import com.puzzling.puzzlingServer.api.review.dto.response.ReviewPreviousTemplateResponseDto;

import com.puzzling.puzzlingServer.api.review.dto.response.ReviewTeamStatusResponseDto;
import com.puzzling.puzzlingServer.api.review.dto.response.ReviewTemplateGetResponseDto;
import com.puzzling.puzzlingServer.api.review.dto.request.ReviewTILRequestDto;
import com.puzzling.puzzlingServer.api.review.service.ReviewService;
Expand Down Expand Up @@ -49,12 +50,18 @@ public ApiResponse createReviewAAR(@PathVariable("memberId") Long memberId,@Path

@GetMapping("member/{memberId}/project/{projectId}/review/previous-template")
public ApiResponse<ReviewPreviousTemplateResponseDto> getPreviousReviewTemplate(@PathVariable Long memberId, @PathVariable Long projectId) {
return ApiResponse.success(SuccessStatus.GET_REVIEW_PREVIOUS_TEMPLATE, reviewService.getPreviousReviewTemplate(memberId, projectId));
return ApiResponse.success(SuccessStatus.GET_REVIEW_PREVIOUS_TEMPLATE_SUCCESS, reviewService.getPreviousReviewTemplate(memberId, projectId));

}

@GetMapping("member/{memberId}/project/{projectId}/actionplan")
public ApiResponse<ReviewActionPlanResponseDto> getReviewActionPlans(@PathVariable Long memberId, @PathVariable Long projectId) {
return ApiResponse.success(SuccessStatus.GET_REVIEW_ACTION_PLAN, reviewService.getReviewActionPlans(memberId, projectId));
return ApiResponse.success(SuccessStatus.GET_REVIEW_ACTION_PLAN_SUCCESS, reviewService.getReviewActionPlans(memberId, projectId));
}

@GetMapping("project/{projectId}/team/review")
public ApiResponse<ReviewTeamStatusResponseDto> getTeamReviewStatus(@PathVariable Long projectId, @RequestParam String startDate,
@RequestParam String endDate) {
return ApiResponse.success(SuccessStatus.GET_REVIEW_TEAM_STATUS_SUCCESS, reviewService.getTeamReviewStatus(projectId, startDate, endDate));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.puzzling.puzzlingServer.api.review.dto.response;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

import static lombok.AccessLevel.PRIVATE;

@Getter
@NoArgsConstructor(access = PRIVATE)
@AllArgsConstructor
public class ReviewTeamStatusResponseDto {
private String reviewDay;
private String reviewDate;
private List<ReviewWriterObjectDto> reviewWriters;
private List<ReviewWriterObjectDto> nonReviewWriters;

public static ReviewTeamStatusResponseDto of (String reviewDay, String reviewDate, List<ReviewWriterObjectDto> reviewWriters,
List<ReviewWriterObjectDto> nonReviewWriters) {
return new ReviewTeamStatusResponseDto(reviewDay, reviewDate, reviewWriters, nonReviewWriters);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.puzzling.puzzlingServer.api.review.dto.response;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import static lombok.AccessLevel.PRIVATE;

@Getter
@NoArgsConstructor(access = PRIVATE)
@AllArgsConstructor
public class ReviewWriterObjectDto {
private String memberNickname;
private String memberRole;

public static ReviewWriterObjectDto of (String memberNickname, String memberRole) {
return new ReviewWriterObjectDto(memberNickname, memberRole);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.Optional;


public interface ReviewRepository extends JpaRepository<Review, Long> {
Expand All @@ -22,6 +23,7 @@ public interface ReviewRepository extends JpaRepository<Review, Long> {

List<Review> findAllByProjectIdOrderByReviewDateAsc(Long projectId);

List<Review> findAllByMemberIdAndProjectIdOrderByReviewDateAsc(Long memberId, Long projectId);
List<Review> findAllByMemberIdAndProjectIdOrderByReviewDateDesc(Long memberId, Long projectId);

Optional<Review> findByMemberIdAndProjectIdAndReviewDate(Long memberId, Long projectId, String ReviewDate);
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.puzzling.puzzlingServer.api.review.service.Impl;

import com.puzzling.puzzlingServer.api.project.domain.Project;
import com.puzzling.puzzlingServer.api.project.domain.UserProject;
import com.puzzling.puzzlingServer.api.project.repository.ProjectRepository;
import com.puzzling.puzzlingServer.api.project.repository.UserProjectRepository;
import com.puzzling.puzzlingServer.api.review.domain.Review;
import com.puzzling.puzzlingServer.api.review.dto.request.Review5FRequestDto;
import com.puzzling.puzzlingServer.api.review.dto.response.ReviewActionPlanResponseDto;
import com.puzzling.puzzlingServer.api.review.dto.response.*;
import com.puzzling.puzzlingServer.api.review.dto.request.ReviewAARRequestDto;

import com.puzzling.puzzlingServer.api.review.dto.response.ReviewPreviousTemplateResponseDto;
import com.puzzling.puzzlingServer.api.review.dto.response.ReviewTemplateGetResponseDto;
import com.puzzling.puzzlingServer.api.review.dto.request.ReviewTILRequestDto;
import com.puzzling.puzzlingServer.api.review.repository.ReviewRepository;
import com.puzzling.puzzlingServer.api.review.service.ReviewService;
Expand All @@ -18,7 +18,6 @@
import com.puzzling.puzzlingServer.api.template.Repository.ReviewTILRepository;
import com.puzzling.puzzlingServer.api.template.Repository.ReviewTemplateRepository;

import com.puzzling.puzzlingServer.api.template.Repository.*;

import com.puzzling.puzzlingServer.api.template.domain.Review5F;
import com.puzzling.puzzlingServer.api.template.domain.ReviewAAR;
Expand All @@ -33,11 +32,17 @@

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.util.*;
import java.util.stream.Collectors;

import static com.puzzling.puzzlingServer.common.response.ErrorStatus.NOT_FOUND_PROJECT;
import static com.puzzling.puzzlingServer.common.util.DateUtil.checkTodayIsReviewDay;
import static com.puzzling.puzzlingServer.common.util.DateUtil.getDayOfWeek;


@Service
@RequiredArgsConstructor
Expand All @@ -49,6 +54,8 @@ public class ReviewServiceImpl implements ReviewService {
private final Review5FRepository review5FRepository;
private final ReviewAARRepository reviewAARRepository;
private final ReviewRepository reviewRepository;
private final ProjectRepository projectRepository;

@Override
@Transactional
public List<ReviewTemplateGetResponseDto> getReviewTemplateAll() {
Expand Down Expand Up @@ -156,6 +163,8 @@ public void createReviewAAR(Long memberId, Long projectId, ReviewAARRequestDto r
reviewARRRepository.save(reviewAAR);
}

@Override
@Transactional
public ReviewPreviousTemplateResponseDto getPreviousReviewTemplate(Long memberId, Long projectId) {
UserProject findUserProject = findUserProjectByMemberIdAndProjectId(memberId, projectId);
return ReviewPreviousTemplateResponseDto.of(findUserProject.getReviewTemplateId());
Expand Down Expand Up @@ -191,6 +200,45 @@ public List<ReviewActionPlanResponseDto> getReviewActionPlans(Long memberId, Lon
.collect(Collectors.toList());
}

@Override
@Transactional
public List<ReviewTeamStatusResponseDto> getTeamReviewStatus(Long projectId, String startDate, String endDate) {

List<ReviewTeamStatusResponseDto> result = new ArrayList<>();

//1. 프로젝트 id로 userProjects 리스트 뽑아오기
List<UserProject> userProjects = userProjectRepository.findAllByProjectId(projectId);

//2. 프로젝트 회고 주기 가져오기
String reviewCycle = findProjectById(projectId).getReviewCycle();

//3.startDate와 endDate 사이에 회고 주기에 맞는 날짜 계산
List<String> reviewDates = generateReviewDates(startDate, endDate, reviewCycle);

for (String reviewDate : reviewDates) {
List<ReviewWriterObjectDto> reviewWriters = new ArrayList<>();
List<ReviewWriterObjectDto> nonReviewWriters = new ArrayList<>();

for (UserProject userProject : userProjects) {
Long memberId = userProject.getMember().getId();
Optional<Review> findReview = reviewRepository.findByMemberIdAndProjectIdAndReviewDate(memberId, projectId, reviewDate);

if (findReview.isPresent()) {
reviewWriters.add(ReviewWriterObjectDto.of(userProject.getNickname(), userProject.getRole()));
} else {
nonReviewWriters.add(ReviewWriterObjectDto.of(userProject.getNickname(), userProject.getRole()));
}
}
result.add(ReviewTeamStatusResponseDto.of(getDayOfWeek(reviewDate), reviewDate, reviewWriters, nonReviewWriters));
}
return result;
}

private Project findProjectById (Long projectId) {
return projectRepository.findById(projectId).orElseThrow(() ->
new NotFoundException(NOT_FOUND_PROJECT.getMessage()));
}

private ReviewTemplate findReviewTemplateById (Long reviewTemplateId) {
return reviewTemplateRepository.findById(reviewTemplateId)
.orElseThrow(() -> new NotFoundException("해당하는 회고 팀플릿이 없습니다."));
Expand All @@ -214,4 +262,19 @@ private <T> T findReviewByReviewId(Long reviewId, JpaRepository<T, Long> reposit
throw new NotFoundException(reviewTemplate + " 형식으로 작성한 회고를 찾을 수 없습니다.");
}
}

private List<String> generateReviewDates(String startDate, String endDate, String reviewCycle) {
LocalDate start = LocalDate.parse(startDate, DateTimeFormatter.ISO_DATE);
LocalDate end = LocalDate.parse(endDate, DateTimeFormatter.ISO_DATE);

List<String> reviewDates = new ArrayList<>();

for (LocalDate date = start; !date.isAfter(end); date = date.plusDays(1)) {
if (checkTodayIsReviewDay( date.format(DateTimeFormatter.ISO_DATE), reviewCycle)) {
reviewDates.add(date.format(DateTimeFormatter.ISO_DATE));
}
}
return reviewDates;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.puzzling.puzzlingServer.api.review.dto.request.ReviewAARRequestDto;
import com.puzzling.puzzlingServer.api.review.dto.response.ReviewPreviousTemplateResponseDto;

import com.puzzling.puzzlingServer.api.review.dto.response.ReviewTeamStatusResponseDto;
import com.puzzling.puzzlingServer.api.review.dto.response.ReviewTemplateGetResponseDto;
import com.puzzling.puzzlingServer.api.review.dto.request.ReviewTILRequestDto;

Expand All @@ -23,4 +24,6 @@ public interface ReviewService {
ReviewPreviousTemplateResponseDto getPreviousReviewTemplate(Long memberId, Long projectId);

List<ReviewActionPlanResponseDto> getReviewActionPlans(Long memberId, Long projectId);

List<ReviewTeamStatusResponseDto> getTeamReviewStatus(Long projectId, String startDate, String endDate);
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ public enum SuccessStatus {
*/
GET_REVIEW_TEMPLATE_SUCCESS(HttpStatus.OK,"회고 템플릿 목록 조회 성공"),
POST_REVIEW_SUCCESS(HttpStatus.CREATED,"회고 글 작성 성공"),
GET_REVIEW_PREVIOUS_TEMPLATE(HttpStatus.OK, "이전 회고 템플릿 조회 성공"),
GET_REVIEW_ACTION_PLAN(HttpStatus.OK, "ACTIONPLAN 내용 조회 성공")
GET_REVIEW_PREVIOUS_TEMPLATE_SUCCESS(HttpStatus.OK, "이전 회고 템플릿 조회 성공"),
GET_REVIEW_ACTION_PLAN_SUCCESS(HttpStatus.OK, "ACTIONPLAN 내용 조회 성공"),
GET_REVIEW_TEAM_STATUS_SUCCESS(HttpStatus.OK, "팀원 회고 상황 조회 성공")
;

private final HttpStatus httpStatus;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.puzzling.puzzlingServer.common.util;

import lombok.RequiredArgsConstructor;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

@RequiredArgsConstructor
public class DateUtil {

public static Boolean checkTodayIsReviewDay(String today, String reviewCycle) {
String dayOfWeekKorean = getDayOfWeek(today);
List<String> weekdayList = Arrays.asList(reviewCycle.split(","));
return weekdayList.contains(dayOfWeekKorean);
}

public static String getDayOfWeek(String dateStr) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate todayDate = LocalDate.parse(dateStr, formatter);

DayOfWeek dayOfWeek = todayDate.getDayOfWeek();
Locale koreanLocale = new Locale("ko", "KR");
String dayOfWeekKorean = dayOfWeek.getDisplayName(TextStyle.SHORT, koreanLocale);

return dayOfWeekKorean;
}
}

0 comments on commit 1f18e6d

Please sign in to comment.