Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,10 @@ public CreateAssignmentResponse createAssignment(
// 2. 과제 수정
@Operation(summary = "과제 수정", description = "과제에 대한 과제명/주차/날짜를 운영진이 수정합니다.")
@PatchMapping("/modify/{assignmentId}")
@ResponseStatus(HttpStatus.OK)
public ModifyAssignmentResponse modifyAssignment(
@PathVariable Integer assignmentId,
@RequestBody ModifyAssignmentRequest request
){
) {
return assignmentService.modifyAssignment(assignmentId, request);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import lombok.Getter;

import java.time.DayOfWeek;
import java.time.LocalDate;

@Getter
Expand All @@ -12,5 +13,5 @@ public class CreateAssignmentRequest {

private String week;

private LocalDate sessionDate;
private DayOfWeek day;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.example.Piroin.project.domain.assignment.dto;

import lombok.Getter;

import java.time.DayOfWeek;
import java.time.LocalDate;

@Getter
Expand All @@ -9,5 +11,5 @@ public class ModifyAssignmentRequest {

private String week;

private LocalDate sessionDate;
private DayOfWeek day;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@
import com.example.Piroin.project.domain.assignment.entity.AssignmentItem;
import org.springframework.data.jpa.repository.JpaRepository;

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

public interface AssignmentItemRepository extends JpaRepository<AssignmentItem, Integer> {

void deleteAllByAssignmentId(Integer assignmentId);

Optional<AssignmentItem> findByUserIdAndAssignmentId(Long userId, Integer assignmentId);

List<AssignmentItem> findByUserIdAndAssignmentWeek(
Long userId,
String week
);

Optional<AssignmentItem> findById(Integer id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
import com.example.Piroin.project.domain.assignment.entity.Assignment;
import org.springframework.data.jpa.repository.JpaRepository;

import java.time.LocalDate;
import java.util.List;

public interface AssignmentRepository extends JpaRepository<Assignment, Integer> {

List<Assignment> findByWeekOrderBySessionDateAsc(String week);

List<Assignment> findBySessionDate(LocalDate sessionDate);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,27 @@
import com.example.Piroin.project.domain.assignment.exception.code.AssignmentErrorCode;
import com.example.Piroin.project.domain.assignment.repository.AssignmentItemRepository;
import com.example.Piroin.project.domain.assignment.repository.AssignmentRepository;
import com.example.Piroin.project.domain.attendance.entity.Attendance;
import com.example.Piroin.project.domain.attendance.entity.AttendanceCode;
import com.example.Piroin.project.domain.attendance.repository.AttendanceCodeRepository;
import com.example.Piroin.project.domain.attendance.repository.AttendanceRepository;
import com.example.Piroin.project.domain.curriculum.entity.StudySession;
import com.example.Piroin.project.domain.curriculum.exception.CurriculumException;
import com.example.Piroin.project.domain.curriculum.exception.code.CurriculumErrorCode;
import com.example.Piroin.project.domain.curriculum.repository.CurriculumRepository;
import com.example.Piroin.project.domain.curriculum.service.CurriculumService;
import com.example.Piroin.project.domain.user.dto.*;
import com.example.Piroin.project.domain.user.entity.User;
import com.example.Piroin.project.domain.user.enums.Role;
import com.example.Piroin.project.domain.user.repository.UserRepository;
import jakarta.transaction.Transactional;
import com.example.Piroin.project.domain.user.service.UserService;
import org.springframework.transaction.annotation.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

@Service
Expand All @@ -26,19 +40,52 @@ public class AssignmentService {
private final AssignmentRepository assignmentRepository;
private final AssignmentItemRepository assignmentItemRepository;
private final UserRepository userRepository;
private final AttendanceRepository attendanceRepository;
private final CurriculumRepository curriculumRepository;
private final AttendanceCodeRepository attendanceCodeRepository;

// 1. 과제 생성
public CreateAssignmentResponse createAssignment(CreateAssignmentRequest request) {
@Transactional
public CreateAssignmentResponse createAssignment(
CreateAssignmentRequest request
) {

// week 문자열 -> Long 변환
Long week = Long.valueOf(request.getWeek());

// 해당 주차 세션들 조회
List<StudySession> sessions =
curriculumRepository.findByWeek(week);

// 요청한 요일과 일치하는 세션 찾기
StudySession matchedSession = sessions.stream()
.filter(session ->
session.getSessionDate().getDayOfWeek()
== request.getDay()
)
.findFirst()
.orElseThrow(() ->
new CurriculumException(
CurriculumErrorCode.SESSION_DATE_NOT_FOUND
));

// 실제 날짜 추출
LocalDate sessionDate = matchedSession.getSessionDate();

// Assignment 생성
Assignment assignment = Assignment.builder()
.title(request.getTitle())
.week(request.getWeek())
.sessionDate(request.getSessionDate())
.sessionDate(sessionDate)
.build();

assignmentRepository.save(assignment);

List<User> users = userRepository.findAll();

// 생성한 과제로 모든 부원에게 assignmentItem 생성하기
// ADMIN 제외 MEMBER만 조회 추천
List<User> users =
userRepository.findByRole(Role.MEMBER);

List<AssignmentItem> assignmentItems = users.stream()
.map(user -> AssignmentItem.builder()
Expand All @@ -53,23 +100,65 @@ public CreateAssignmentResponse createAssignment(CreateAssignmentRequest request
return new CreateAssignmentResponse(assignment.getId());
}


// 2. 과제 수정
public ModifyAssignmentResponse modifyAssignment(Integer assignmentId,
ModifyAssignmentRequest request) {
@Transactional
public ModifyAssignmentResponse modifyAssignment(
Integer assignmentId,
ModifyAssignmentRequest request
) {

Assignment assignment = assignmentRepository.findById(assignmentId)
.orElseThrow(() -> new AssignmentException(
AssignmentErrorCode.ASSIGNMENT_NOT_FOUND
));

/*
1. 최종적으로 사용할 week 결정
- request에 있으면 그 값 사용
- 없으면 기존 assignment 값 사용
*/
String finalWeek = request.getWeek() != null
? request.getWeek()
: assignment.getWeek();

/*
2. 최종적으로 사용할 day 결정
- request에 있으면 그 값 사용
- 없으면 기존 sessionDate의 요일 사용
*/
DayOfWeek finalDay = request.getDay() != null
? request.getDay()
: assignment.getSessionDate().getDayOfWeek();

/*
3. week/day 조합으로 StudySession 조회해서
새로운 sessionDate 계산
*/

// request에서 보낸 주차에 해당하는 세션들을 전부 찾아 리스트에 저장.
List<StudySession> weekSessions = curriculumRepository.findByWeek(Long.parseLong(finalWeek));

// request에서 보낸 요일에 해당하는 세션을 찾음.
StudySession studySession = weekSessions.stream()
.filter(s -> s.getSessionDate().getDayOfWeek() == finalDay) // 자바끼리 요일 비교
.findFirst()
.orElseThrow(() -> new CurriculumException(
CurriculumErrorCode.STUDY_SESSION_NOT_FOUND
));

// 그 세션의 날짜를 추출.
LocalDate newSessionDate = studySession.getSessionDate();

/*
4. 수정 적용
*/
assignment.update(
request.getTitle(),
request.getWeek(),
request.getSessionDate()
finalWeek,
newSessionDate
);

assignmentRepository.save(assignment);

return new ModifyAssignmentResponse(assignment.getId());
}

Expand Down Expand Up @@ -147,4 +236,106 @@ private String convertDay(DayOfWeek dayOfWeek) {
};
}


// 5. (운영진) 학생들 과제 상태 열람
@Transactional(readOnly = true)
public StudentWeeklyStatusResponse getStudentWeeklyStatus(
Long userId,
Long week
) {

List<StudySession> sessions =
curriculumRepository.findByWeek(week);

List<DayStatusResponse> dayResponses = new ArrayList<>();

for (StudySession session : sessions) {

LocalDate sessionDate = session.getSessionDate();

String day =
sessionDate.getDayOfWeek().toString();

/*
* 과제 조회
*/
List<Assignment> assignments =
assignmentRepository.findBySessionDate(sessionDate);

List<AssignmentStatusResponse> assignmentResponses =
assignments.stream()
.map(assignment -> {

AssignmentItem item =
assignmentItemRepository
.findByUserIdAndAssignmentId(
userId,
assignment.getId()
)
.orElse(null);

String submitted =
item == null
? "PENDING"
: item.getSubmitted().name();

return AssignmentStatusResponse.builder()
.assignmentItemId(
item != null ? item.getId() : null
)
.assignmentId(assignment.getId())
.title(assignment.getTitle())
.submitted(submitted)
.build();
})
.toList();

/*
* 출석 조회
*/
List<AttendanceCode> attendanceCodes =
attendanceCodeRepository.findByAttendanceDate(sessionDate);

List<AttendanceStatusResponse> attendanceResponses =
attendanceCodes.stream()
.map(code -> {

Attendance attendance =
attendanceRepository
.findByUserIdAndAttendanceCodeId(
userId,
code.getId()
)
.orElse(null);

boolean attended =
attendance != null &&
attendance.getStatus();

return AttendanceStatusResponse.builder()
.attendanceId(
attendance != null ? attendance.getId() : null
)
.attendanceCodeId(code.getId())
.attendanceOrder(code.getAttendanceOrder())
.attended(attended)
.build();
})
.toList();

dayResponses.add(
DayStatusResponse.builder()
.day(day)
.sessionDate(sessionDate)
.assignments(assignmentResponses)
.attendances(attendanceResponses)
.build()
);
}

return StudentWeeklyStatusResponse.builder()
.week(week)
.days(dayResponses)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,12 @@ public class AdminAttendanceController {
@PostMapping("/admin/attendance/start")
public AttendanceCodeResponse startAttendance() {

// 1. 오늘 날짜 구하기 (LocalDate 활용)
// 오늘 날짜
LocalDate today = LocalDate.now();

// 2. 서비스가 원하는 "yyyy-MM-dd" 형식의 문자열로 포맷팅
String todayStr = today.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));

// 3. 포맷팅된 오늘 날짜 문자열을 서비스에 넘겨줍니다.
AttendanceCode code = attendanceService.generateCodeAndCreateAttendances(todayStr);
// 서비스 호출
AttendanceCode code =
attendanceService.generateCodeAndCreateAttendances(today);

return AttendanceCodeResponse.from(code);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import jakarta.persistence.*;
import lombok.*;

import java.time.LocalDate;

@Entity
@Table(name = "attendance_code")
@Getter
Expand All @@ -16,7 +18,7 @@ public class AttendanceCode {
private Integer id; // SERIAL 타입에 매칭 (Long -> Integer)

@Column(name = "attendance_date")
private String attendanceDate;
private LocalDate attendanceDate;

@Column(name = "attendance_order")
private String attendanceOrder; // '1, 2, 3' 코멘트 항목
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ public interface AttendanceCodeRepository extends JpaRepository<AttendanceCode,
// Optional<AttendanceCode> findByCodeAndStudySessionId(String code, Long studySessionId);

// 특정 날짜에 발급된 코드 개수 조회
long countByAttendanceDate(String attendanceDate);
long countByAttendanceDate(LocalDate attendanceDate);

// 만료되지 않은 코드 목록 조회
List<AttendanceCode> findByIsExpiredFalse();

Optional<AttendanceCode> findByCode(String code);

List<AttendanceCode> findByAttendanceDate(LocalDate attendanceDate);
}


Loading
Loading