diff --git a/src/main/java/leets/weeth/domain/attendance/application/dto/AttendanceDTO.java b/src/main/java/leets/weeth/domain/attendance/application/dto/AttendanceDTO.java index 1a2bcc8c..394b21c3 100644 --- a/src/main/java/leets/weeth/domain/attendance/application/dto/AttendanceDTO.java +++ b/src/main/java/leets/weeth/domain/attendance/application/dto/AttendanceDTO.java @@ -1,5 +1,7 @@ package leets.weeth.domain.attendance.application.dto; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; import leets.weeth.domain.attendance.domain.entity.enums.Status; import java.time.LocalDateTime; @@ -36,4 +38,19 @@ public record Response( public record CheckIn( Integer code ) {} + + public record AttendanceInfo( + Long id, + Status status, + Integer weekNumber, + String name, + String position, + String department, + String studentId + ) {} + + public record UpdateStatus( + @NotNull Long attendanceId, + @NotNull @Pattern(regexp = "ATTEND|ABSENT")String status + ) {} } diff --git a/src/main/java/leets/weeth/domain/attendance/application/mapper/AttendanceMapper.java b/src/main/java/leets/weeth/domain/attendance/application/mapper/AttendanceMapper.java index 2f1e85db..9b6fa8c7 100644 --- a/src/main/java/leets/weeth/domain/attendance/application/mapper/AttendanceMapper.java +++ b/src/main/java/leets/weeth/domain/attendance/application/mapper/AttendanceMapper.java @@ -32,4 +32,16 @@ public interface AttendanceMapper { @Mapping(target = "end", source = "attendance.meeting.end"), @Mapping(target = "location", source = "attendance.meeting.location"), }) AttendanceDTO.Response toResponseDto(Attendance attendance); + + @Mappings({ + @Mapping(target = "id", source = "attendance.id"), + @Mapping(target = "status", source = "attendance.status"), + @Mapping(target = "weekNumber", source = "attendance.meeting.weekNumber"), + @Mapping(target = "name", source = "attendance.user.name"), + @Mapping(target = "position", source = "attendance.user.position"), + @Mapping(target = "department", source = "attendance.user.department"), + @Mapping(target = "studentId", source = "attendance.user.studentId") + }) + AttendanceDTO.AttendanceInfo toAttendanceInfoDto(Attendance attendance); + } diff --git a/src/main/java/leets/weeth/domain/attendance/application/usecase/AttendanceUseCase.java b/src/main/java/leets/weeth/domain/attendance/application/usecase/AttendanceUseCase.java index 6f61a801..e73f1221 100644 --- a/src/main/java/leets/weeth/domain/attendance/application/usecase/AttendanceUseCase.java +++ b/src/main/java/leets/weeth/domain/attendance/application/usecase/AttendanceUseCase.java @@ -1,5 +1,8 @@ package leets.weeth.domain.attendance.application.usecase; +import java.util.List; +import leets.weeth.domain.attendance.application.dto.AttendanceDTO; +import leets.weeth.domain.attendance.application.dto.AttendanceDTO.AttendanceInfo; import leets.weeth.domain.attendance.application.exception.AttendanceCodeMismatchException; import java.time.LocalDate; @@ -14,5 +17,9 @@ public interface AttendanceUseCase { Detail findAll(Long userId); + List findAllAttendanceByMeeting(Long meetingId); + void close(LocalDate now, Integer cardinal); + + void updateAttendanceStatus(List attendanceUpdates); } diff --git a/src/main/java/leets/weeth/domain/attendance/application/usecase/AttendanceUseCaseImpl.java b/src/main/java/leets/weeth/domain/attendance/application/usecase/AttendanceUseCaseImpl.java index 939a1cbd..bdaaab5f 100644 --- a/src/main/java/leets/weeth/domain/attendance/application/usecase/AttendanceUseCaseImpl.java +++ b/src/main/java/leets/weeth/domain/attendance/application/usecase/AttendanceUseCaseImpl.java @@ -73,7 +73,16 @@ public AttendanceDTO.Detail findAll(Long userId) { return mapper.toDetailDto(user, responses); } + @Override + public List findAllAttendanceByMeeting(Long meetingId) { + Meeting meeting = meetingGetService.find(meetingId); + + List attendances = attendanceGetService.findAllByMeeting(meeting); + return attendances.stream() + .map(mapper::toAttendanceInfoDto) + .toList(); + } @Override public void close(LocalDate now, Integer cardinal) { List meetings = meetingGetService.find(cardinal); @@ -91,4 +100,20 @@ public void close(LocalDate now, Integer cardinal) { attendanceUpdateService.close(attendanceList); } + @Override + @Transactional + public void updateAttendanceStatus(List attendanceUpdates) { + attendanceUpdates.forEach(update -> { + Attendance attendance = attendanceGetService.findByAttendanceId(update.attendanceId()); + User user = attendance.getUser(); + + if (attendance.getStatus() == Status.ATTEND) { + attendance.close(); + user.removeAttend(); + } else { + attendance.attend(); + user.removeAbsent(); + } + }); + } } diff --git a/src/main/java/leets/weeth/domain/attendance/domain/service/AttendanceGetService.java b/src/main/java/leets/weeth/domain/attendance/domain/service/AttendanceGetService.java index 1164078a..d0dd1ad0 100644 --- a/src/main/java/leets/weeth/domain/attendance/domain/service/AttendanceGetService.java +++ b/src/main/java/leets/weeth/domain/attendance/domain/service/AttendanceGetService.java @@ -1,5 +1,6 @@ package leets.weeth.domain.attendance.domain.service; +import leets.weeth.domain.attendance.application.exception.AttendanceNotFoundException; import leets.weeth.domain.attendance.domain.entity.Attendance; import leets.weeth.domain.attendance.domain.repository.AttendanceRepository; import leets.weeth.domain.schedule.domain.entity.Meeting; @@ -17,4 +18,8 @@ public class AttendanceGetService { public List findAllByMeeting(Meeting meeting) { return attendanceRepository.findAllByMeeting(meeting); } + public Attendance findByAttendanceId(Long attendanceId) { + return attendanceRepository.findById(attendanceId) + .orElseThrow(AttendanceNotFoundException::new); + } } diff --git a/src/main/java/leets/weeth/domain/attendance/presentation/AttendanceAdminController.java b/src/main/java/leets/weeth/domain/attendance/presentation/AttendanceAdminController.java index 5f8aab92..4dfc223b 100644 --- a/src/main/java/leets/weeth/domain/attendance/presentation/AttendanceAdminController.java +++ b/src/main/java/leets/weeth/domain/attendance/presentation/AttendanceAdminController.java @@ -1,13 +1,20 @@ package leets.weeth.domain.attendance.presentation; import static leets.weeth.domain.attendance.presentation.ResponseMessage.ATTENDANCE_CLOSE_SUCCESS; +import static leets.weeth.domain.attendance.presentation.ResponseMessage.ATTENDANCE_FIND_DETAIL_SUCCESS; +import static leets.weeth.domain.attendance.presentation.ResponseMessage.ATTENDANCE_UPDATED_SUCCESS; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.List; +import leets.weeth.domain.attendance.application.dto.AttendanceDTO; import leets.weeth.domain.attendance.application.usecase.AttendanceUseCase; import leets.weeth.global.common.response.CommonResponse; import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -28,4 +35,17 @@ public CommonResponse close(@RequestParam LocalDate now, @RequestParam Int attendanceUseCase.close(now, cardinal); return CommonResponse.createSuccess(ATTENDANCE_CLOSE_SUCCESS.getMessage()); } + + @GetMapping("/{meetingId}") + @Operation(summary = "모든 인원 정기모임 출석 정보 조회") + public CommonResponse> getAllAttendance(@PathVariable Long meetingId) { + return CommonResponse.createSuccess(ATTENDANCE_FIND_DETAIL_SUCCESS.getMessage(), attendanceUseCase.findAllAttendanceByMeeting(meetingId)); + } + + @PatchMapping("/status") + @Operation(summary = "모든 인원 정기모임 개별 출석 상태 수정") + public CommonResponse updateAttendanceStatus(@RequestBody List attendanceUpdates) { + attendanceUseCase.updateAttendanceStatus(attendanceUpdates); + return CommonResponse.createSuccess(ATTENDANCE_UPDATED_SUCCESS.getMessage()); + } } diff --git a/src/main/java/leets/weeth/domain/attendance/presentation/ResponseMessage.java b/src/main/java/leets/weeth/domain/attendance/presentation/ResponseMessage.java index 2f3f9ffd..f3cc9cae 100644 --- a/src/main/java/leets/weeth/domain/attendance/presentation/ResponseMessage.java +++ b/src/main/java/leets/weeth/domain/attendance/presentation/ResponseMessage.java @@ -8,6 +8,8 @@ public enum ResponseMessage { //AttendanceAdminController 관련 ATTENDANCE_CLOSE_SUCCESS("출석이 성공적으로 마감되었습니다."), + ATTENDANCE_UPDATED_SUCCESS("개별 출석 상태가 성공적으로 수정되었습니다."), + ATTENDANCE_FIND_DETAIL_SUCCESS("모든 인원의 정기모임 출석 정보가 성공적으로 조회되었습니다."), //AttendanceController 관련 ATTENDANCE_CHECKIN_SUCCESS("출석이 성공적으로 처리되었습니다."),