Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: 내 할일 목록 조회 API 추가 #671

Merged
merged 8 commits into from
Aug 24, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.gdschongik.gdsc.domain.study.application.StudentStudyDetailService;
import com.gdschongik.gdsc.domain.study.dto.response.AssignmentDashboardResponse;
import com.gdschongik.gdsc.domain.study.dto.response.StudyStudentSessionResponse;
import com.gdschongik.gdsc.domain.study.dto.response.StudyTodoResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
Expand All @@ -29,6 +30,13 @@ public ResponseEntity<AssignmentDashboardResponse> getSubmittableAssignments(
return ResponseEntity.ok(response);
}

@Operation(summary = "내 할일 리스트 조회", description = "해당 스터디의 내 할일 리스트를 조회합니다")
@GetMapping("/todo")
public ResponseEntity<List<StudyTodoResponse>> getStudyTodoList(@RequestParam(name = "studyId") Long studyId) {
List<StudyTodoResponse> response = studentStudyDetailService.getStudyTodoList(studyId);
return ResponseEntity.ok(response);
}

// TODO 스터디 세션 워딩을 커리큘럼으로 변경해야함
@Operation(summary = "스터디 커리큘럼 조회", description = "해당 스터디의 커리큘럼들을 조회합니다.")
@GetMapping("/sessions")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@
import com.gdschongik.gdsc.domain.study.dto.response.AssignmentDashboardResponse;
import com.gdschongik.gdsc.domain.study.dto.response.AssignmentSubmittableDto;
import com.gdschongik.gdsc.domain.study.dto.response.StudyStudentSessionResponse;
import com.gdschongik.gdsc.domain.study.dto.response.StudyTodoResponse;
import com.gdschongik.gdsc.global.exception.CustomException;
import com.gdschongik.gdsc.global.exception.ErrorCode;
import com.gdschongik.gdsc.global.util.MemberUtil;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -54,6 +57,31 @@ studyDetail, getSubmittedAssignment(assignmentHistories, studyDetail)))
}

@Transactional(readOnly = true)
public List<StudyTodoResponse> getStudyTodoList(Long studyId) {
Member member = memberUtil.getCurrentMember();
final List<StudyDetail> studyDetails = studyDetailRepository.findAllByStudyIdOrderByWeekAsc(studyId);
final List<AssignmentHistory> assignmentHistories =
assignmentHistoryRepository.findAssignmentHistoriesByStudentAndStudy(member, studyId);
final List<Attendance> attendances = attendanceRepository.findByMemberAndStudyId(member, studyId);

LocalDate now = LocalDate.now();
List<StudyTodoResponse> response = new ArrayList<>();
// 출석체크 정보 (개설 상태이고, 오늘이 출석체크날짜인 것)
studyDetails.stream()
.filter(studyDetail -> studyDetail.getSession().isOpen()
&& studyDetail.getAttendanceDay().equals(now))
.forEach(studyDetail -> response.add(StudyTodoResponse.createAttendanceType(
studyDetail, now, isAttended(attendances, studyDetail))));

// 과제 정보 (오늘이 과제 제출 기간에 포함된 과제 정보)
studyDetails.stream()
.filter(studyDetail -> studyDetail.getAssignment().isOpen()
&& studyDetail.getAssignment().isDeadlineRemaining())
.forEach(studyDetail -> response.add(StudyTodoResponse.createAssignmentType(
studyDetail, getSubmittedAssignment(assignmentHistories, studyDetail))));
return response;
}

public List<StudyStudentSessionResponse> getStudySessions(Long studyId) {
Member member = memberUtil.getCurrentMember();
final List<StudyDetail> studyDetails = studyDetailRepository.findAllByStudyIdOrderByWeekAsc(studyId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.gdschongik.gdsc.domain.study.domain.vo.Session;
import com.gdschongik.gdsc.global.exception.CustomException;
import jakarta.persistence.*;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
Expand Down Expand Up @@ -97,10 +98,25 @@ public boolean isAssignmentDeadlineRemaining() {

// 스터디 시작일자 + 현재 주차 * 7 + (스터디 요일 - 스터디 기간 시작 요일)
public LocalDate getAttendanceDay() {
return study.getStartDate()
.plusDays(week * 7
+ study.getDayOfWeek().getValue()
- study.getStartDate().getDayOfWeek().getValue());
// 스터디 시작일자
LocalDate startDate = study.getStartDate();

// 스터디 요일
DayOfWeek studyDayOfWeek = study.getDayOfWeek();

// 스터디 기간 시작 요일
DayOfWeek startDayOfWeek = startDate.getDayOfWeek();
seulgi99 marked this conversation as resolved.
Show resolved Hide resolved

// 스터디 요일이 스터디 기간 시작 요일보다 앞서면, 다음 주로 넘어가게 처리
Long daysDifference = Long.valueOf(studyDayOfWeek.getValue() - startDayOfWeek.getValue());
if (daysDifference < 0) {
daysDifference += 7;
}

// 현재 주차에 따른 일수 계산
Long daysToAdd = (week - 1) * 7 + daysDifference;

return startDate.plusDays(daysToAdd);
}

public void updateSession(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,9 @@ public static Session generateSession(
.status(status)
.build();
}

// 데이터 전달 로직
public boolean isOpen() {
return status == StudyStatus.OPEN;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.gdschongik.gdsc.domain.study.dto.response;

import static com.gdschongik.gdsc.domain.study.dto.response.StudyTodoResponse.StudyTodoType.ASSIGNMENT;
import static com.gdschongik.gdsc.domain.study.dto.response.StudyTodoResponse.StudyTodoType.ATTENDANCE;

import com.gdschongik.gdsc.domain.study.domain.AssignmentHistory;
import com.gdschongik.gdsc.domain.study.domain.StudyDetail;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDate;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

public record StudyTodoResponse(
Long studyDetailId,
@Schema(description = "현 주차수") Long week,
@Schema(description = "할일 타입") StudyTodoType todoType,
@Schema(description = "마감 시각") LocalDateTime deadLine,
@Schema(description = "출석 상태 (출석타입일 때만 사용)") AttendanceStatusResponse attendanceStatus,
@Schema(description = "과제 제목 (과제타입일 때만 사용)") String assignmentTitle,
@Schema(description = "과제 제출 상태 (과제타입일 때만 사용)") AssignmentSubmissionStatusResponse assignmentSubmissionStatus) {

public static StudyTodoResponse createAttendanceType(StudyDetail studyDetail, LocalDate now, boolean isAttended) {
return new StudyTodoResponse(
studyDetail.getId(),
studyDetail.getWeek(),
ATTENDANCE,
studyDetail.getAttendanceDay().atTime(23, 59, 59),
AttendanceStatusResponse.of(studyDetail, now, isAttended),
null,
null);
}

public static StudyTodoResponse createAssignmentType(StudyDetail studyDetail, AssignmentHistory assignmentHistory) {
return new StudyTodoResponse(
studyDetail.getId(),
studyDetail.getWeek(),
ASSIGNMENT,
studyDetail.getAssignment().getDeadline(),
null,
studyDetail.getAssignment().getTitle(),
AssignmentSubmissionStatusResponse.from(assignmentHistory));
}

@Getter
@RequiredArgsConstructor
public enum StudyTodoType {
ATTENDANCE("출석"),
ASSIGNMENT("과제");

private final String value;
}
}