-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #126 from IT-Cotato/release
[Main] V2.2024.08.22.01
- Loading branch information
Showing
100 changed files
with
2,738 additions
and
459 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
132 changes: 132 additions & 0 deletions
132
src/main/java/org/cotato/csquiz/api/attendance/controller/AttendanceController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package org.cotato.csquiz.api.attendance.controller; | ||
|
||
import io.swagger.v3.oas.annotations.Operation; | ||
import io.swagger.v3.oas.annotations.responses.ApiResponse; | ||
import io.swagger.v3.oas.annotations.tags.Tag; | ||
import jakarta.validation.Valid; | ||
import jakarta.validation.constraints.Max; | ||
import jakarta.validation.constraints.Min; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.cotato.csquiz.api.attendance.dto.AttendResponse; | ||
import org.cotato.csquiz.api.attendance.dto.AttendanceRecordResponse; | ||
import org.cotato.csquiz.api.attendance.dto.AttendancesResponse; | ||
import org.cotato.csquiz.api.attendance.dto.MemberAttendanceRecordsResponse; | ||
import org.cotato.csquiz.api.attendance.dto.OfflineAttendanceRequest; | ||
import org.cotato.csquiz.api.attendance.dto.OnlineAttendanceRequest; | ||
import org.cotato.csquiz.api.attendance.dto.UpdateAttendanceRequest; | ||
import org.cotato.csquiz.api.attendance.dto.AttendanceTimeResponse; | ||
import org.cotato.csquiz.domain.attendance.service.AttendanceAdminService; | ||
import org.cotato.csquiz.domain.attendance.service.AttendanceRecordService; | ||
import org.cotato.csquiz.domain.attendance.service.AttendanceService; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||
import org.springframework.validation.annotation.Validated; | ||
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.PostMapping; | ||
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; | ||
|
||
@Slf4j | ||
@Tag(name = "출석 정보", description = "출석 관련 API 입니다.") | ||
@RestController | ||
@Validated | ||
@RequiredArgsConstructor | ||
@RequestMapping("/v2/api/attendances") | ||
public class AttendanceController { | ||
|
||
private final AttendanceAdminService attendanceAdminService; | ||
private final AttendanceService attendanceService; | ||
private final AttendanceRecordService attendanceRecordService; | ||
|
||
@Operation(summary = "출석 정보 변경 API") | ||
@PatchMapping | ||
public ResponseEntity<Void> updateAttendance(@RequestBody @Valid UpdateAttendanceRequest request) { | ||
attendanceAdminService.updateAttendanceByAttendanceId(request); | ||
return ResponseEntity.noContent().build(); | ||
} | ||
|
||
@Operation(summary = "세션 시간 반환 API") | ||
@GetMapping("/info") | ||
public ResponseEntity<AttendanceTimeResponse> findAttendanceTimeInfo(@RequestParam("sessionId") Long sessionId) { | ||
return ResponseEntity.status(HttpStatus.OK).body(attendanceService.findAttendanceTimeInfo(sessionId)); | ||
} | ||
|
||
@Operation(summary = "회원 출결사항 기간 단위 조회 API") | ||
@GetMapping("/records") | ||
public ResponseEntity<List<AttendanceRecordResponse>> findAttendanceRecords( | ||
@RequestParam(name = "generationId") Long generationId, | ||
@RequestParam(name = "month", required = false) @Min(value = 1, message = "달은 1 이상이어야 합니다.") @Max(value = 12, message = "달은 12 이하이어야 합니다") Integer month | ||
) { | ||
return ResponseEntity.ok().body(attendanceAdminService.findAttendanceRecords(generationId, month)); | ||
} | ||
|
||
@Operation(summary = "회원 출결사항 출석 단위 조회 API") | ||
@GetMapping("/{attendance-id}/records") | ||
public ResponseEntity<List<AttendanceRecordResponse>> findAttendanceRecordsByAttendance( | ||
@PathVariable("attendance-id") Long attendanceId) { | ||
return ResponseEntity.ok().body(attendanceAdminService.findAttendanceRecordsByAttendance(attendanceId)); | ||
} | ||
|
||
@Operation(summary = "기수별 출석 목록 조회 API") | ||
@GetMapping | ||
public ResponseEntity<AttendancesResponse> findAttendancesByGeneration(@RequestParam("generationId") Long generationId) { | ||
return ResponseEntity.ok().body(attendanceService.findAttendancesByGenerationId(generationId)); | ||
} | ||
|
||
@Operation(summary = "대면 출결 입력 API", | ||
responses = { | ||
@ApiResponse( | ||
responseCode = "200", | ||
description = "성공" | ||
), | ||
@ApiResponse( | ||
responseCode = "409", | ||
description = "이미 출석을 완료함" | ||
), | ||
@ApiResponse( | ||
responseCode = "400", | ||
description = "출석 시간이 아님" | ||
) | ||
} | ||
) | ||
@PostMapping(value = "/records/offline") | ||
public ResponseEntity<AttendResponse> submitOfflineAttendanceRecord(@RequestBody @Valid OfflineAttendanceRequest request, | ||
@AuthenticationPrincipal Long memberId) { | ||
return ResponseEntity.ok().body(attendanceRecordService.submitRecord(request, memberId)); | ||
} | ||
|
||
@Operation(summary = "비대면 출결 입력 API", | ||
responses = { | ||
@ApiResponse( | ||
responseCode = "200", | ||
description = "성공" | ||
), | ||
@ApiResponse( | ||
responseCode = "409", | ||
description = "이미 출석을 완료함" | ||
), | ||
@ApiResponse( | ||
responseCode = "400", | ||
description = "출석 시간이 아님" | ||
) | ||
}) | ||
@PostMapping(value = "/records/online") | ||
public ResponseEntity<AttendResponse> submitOnlineAttendanceRecord(@RequestBody @Valid OnlineAttendanceRequest request, | ||
@AuthenticationPrincipal Long memberId) { | ||
return ResponseEntity.ok().body(attendanceRecordService.submitRecord(request, memberId)); | ||
} | ||
|
||
@Operation(summary = "부원의 기수별 출결 기록 반환 API") | ||
@GetMapping("/records/members") | ||
public ResponseEntity<MemberAttendanceRecordsResponse> findAllRecordsByGeneration(@RequestParam("generationId") Long generationId , | ||
@AuthenticationPrincipal Long memberId) { | ||
return ResponseEntity.ok().body(attendanceRecordService.findAllRecordsBy(generationId, memberId)); | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/main/java/org/cotato/csquiz/api/attendance/dto/AttendResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package org.cotato.csquiz.api.attendance.dto; | ||
|
||
import org.cotato.csquiz.domain.attendance.enums.AttendanceResult; | ||
|
||
public record AttendResponse( | ||
AttendanceResult status, | ||
String message | ||
) { | ||
public static AttendResponse from(AttendanceResult status) { | ||
return new AttendResponse( | ||
status, | ||
status.getMessage() | ||
); | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
src/main/java/org/cotato/csquiz/api/attendance/dto/AttendanceDeadLineDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package org.cotato.csquiz.api.attendance.dto; | ||
|
||
import com.fasterxml.jackson.annotation.JsonFormat; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import java.time.LocalTime; | ||
import java.util.Objects; | ||
import lombok.Builder; | ||
import org.cotato.csquiz.domain.attendance.enums.DeadLine; | ||
|
||
public record AttendanceDeadLineDto( | ||
@Schema(example = "19:05:00") | ||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm:ss") | ||
LocalTime attendanceDeadLine, | ||
@Schema(example = "19:20:00") | ||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm:ss") | ||
LocalTime lateDeadLine | ||
) { | ||
|
||
@Builder | ||
public AttendanceDeadLineDto { | ||
if (Objects.isNull(attendanceDeadLine)) { | ||
attendanceDeadLine = DeadLine.DEFAULT_ATTENDANCE_DEADLINE.getTime(); | ||
} | ||
if (Objects.isNull(lateDeadLine)) { | ||
lateDeadLine = DeadLine.DEFAULT_LATE_DEADLINE.getTime(); | ||
} | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
src/main/java/org/cotato/csquiz/api/attendance/dto/AttendanceParams.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package org.cotato.csquiz.api.attendance.dto; | ||
|
||
import java.time.LocalDateTime; | ||
import org.cotato.csquiz.domain.attendance.enums.AttendanceType; | ||
|
||
public interface AttendanceParams { | ||
|
||
AttendanceType attendanceType(); | ||
|
||
Long attendanceId(); | ||
|
||
LocalDateTime requestTime(); | ||
} |
31 changes: 31 additions & 0 deletions
31
src/main/java/org/cotato/csquiz/api/attendance/dto/AttendanceRecordResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package org.cotato.csquiz.api.attendance.dto; | ||
|
||
import org.cotato.csquiz.domain.auth.entity.Member; | ||
import org.cotato.csquiz.domain.auth.enums.MemberPosition; | ||
|
||
|
||
public record AttendanceRecordResponse( | ||
AttendanceMemberInfo memberInfo, | ||
AttendanceStatistic statistic | ||
) { | ||
public static AttendanceRecordResponse of(Member member, AttendanceStatistic attendanceStatistic) { | ||
return new AttendanceRecordResponse( | ||
AttendanceMemberInfo.from(member), | ||
attendanceStatistic | ||
); | ||
} | ||
|
||
public record AttendanceMemberInfo( | ||
Long memberId, | ||
String memberName, | ||
MemberPosition position | ||
){ | ||
static AttendanceMemberInfo from(Member member) { | ||
return new AttendanceMemberInfo( | ||
member.getId(), | ||
member.getName(), | ||
member.getPosition() | ||
); | ||
} | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/main/java/org/cotato/csquiz/api/attendance/dto/AttendanceResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package org.cotato.csquiz.api.attendance.dto; | ||
|
||
import java.time.LocalDate; | ||
import lombok.Builder; | ||
import org.cotato.csquiz.domain.attendance.enums.AttendanceOpenStatus; | ||
|
||
@Builder | ||
public record AttendanceResponse( | ||
Long sessionId, | ||
Long attendanceId, | ||
String sessionTitle, | ||
LocalDate sessionDate, | ||
AttendanceOpenStatus openStatus | ||
) { | ||
} |
35 changes: 35 additions & 0 deletions
35
src/main/java/org/cotato/csquiz/api/attendance/dto/AttendanceStatistic.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package org.cotato.csquiz.api.attendance.dto; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.stream.Collectors; | ||
import org.cotato.csquiz.domain.attendance.entity.AttendanceRecord; | ||
import org.cotato.csquiz.domain.attendance.enums.AttendanceResult; | ||
import org.cotato.csquiz.domain.attendance.enums.AttendanceType; | ||
|
||
public record AttendanceStatistic( | ||
Integer online, | ||
Integer offline, | ||
Integer late, | ||
Integer absent | ||
) { | ||
public static AttendanceStatistic of(List<AttendanceRecord> attendanceRecords, Integer totalAttendance) { | ||
Map<AttendanceResult, List<AttendanceRecord>> countByStatus = attendanceRecords.stream() | ||
.collect(Collectors.groupingBy(AttendanceRecord::getAttendanceResult)); | ||
List<AttendanceRecord> presentRecords = countByStatus.getOrDefault(AttendanceResult.PRESENT, List.of()); | ||
|
||
int onlineCount = (int) presentRecords.stream() | ||
.filter(record -> AttendanceType.ONLINE == record.getAttendanceType()) | ||
.count(); | ||
int offLineCount = (int) presentRecords.stream() | ||
.filter(record -> AttendanceType.OFFLINE == record.getAttendanceType()) | ||
.count(); | ||
|
||
return new AttendanceStatistic( | ||
onlineCount, | ||
offLineCount, | ||
countByStatus.getOrDefault(AttendanceResult.LATE, List.of()).size(), | ||
totalAttendance - attendanceRecords.size() | ||
); | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
src/main/java/org/cotato/csquiz/api/attendance/dto/AttendanceTimeResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package org.cotato.csquiz.api.attendance.dto; | ||
|
||
import java.time.LocalDateTime; | ||
import java.time.LocalTime; | ||
|
||
public record AttendanceTimeResponse( | ||
Long sessionId, | ||
LocalTime attendanceDeadLine, | ||
LocalTime lateDeadLine | ||
) { | ||
public static AttendanceTimeResponse of(Long sessionId, LocalDateTime attendanceDeadLine, LocalDateTime lateDeadLine) { | ||
return new AttendanceTimeResponse( | ||
sessionId, | ||
attendanceDeadLine.toLocalTime(), | ||
lateDeadLine.toLocalTime() | ||
); | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/java/org/cotato/csquiz/api/attendance/dto/AttendancesResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package org.cotato.csquiz.api.attendance.dto; | ||
|
||
import java.util.List; | ||
import lombok.Builder; | ||
|
||
@Builder | ||
public record AttendancesResponse( | ||
Long generationId, | ||
Long generationNumber, | ||
List<AttendanceResponse> attendances | ||
) { | ||
} |
57 changes: 57 additions & 0 deletions
57
src/main/java/org/cotato/csquiz/api/attendance/dto/MemberAttendResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package org.cotato.csquiz.api.attendance.dto; | ||
|
||
import io.swagger.v3.oas.annotations.media.Schema; | ||
import java.time.LocalDate; | ||
import org.cotato.csquiz.domain.attendance.entity.Attendance; | ||
import org.cotato.csquiz.domain.attendance.entity.AttendanceRecord; | ||
import org.cotato.csquiz.domain.attendance.enums.AttendanceOpenStatus; | ||
import org.cotato.csquiz.domain.attendance.enums.AttendanceResult; | ||
import org.cotato.csquiz.domain.attendance.enums.AttendanceType; | ||
import org.cotato.csquiz.domain.generation.entity.Session; | ||
|
||
public record MemberAttendResponse( | ||
@Schema(description = "세션 PK") | ||
Long sessionId, | ||
@Schema(description = "출석 PK") | ||
Long attendanceId, | ||
@Schema(description = "멤버 PK") | ||
Long memberId, | ||
@Schema(description = "세션 타이틀", example = "3주차 세션") | ||
String sessionTitle, | ||
@Schema(description = "세션 날짜") | ||
LocalDate sessionDate, | ||
@Schema(description = "출결 진행 여부", examples = { | ||
"CLOSED", "OPEN" | ||
}) | ||
AttendanceOpenStatus isOpened, | ||
@Schema(description = "출결 형식", nullable = true) | ||
AttendanceType attendanceType, | ||
@Schema(description = "마감된 출석에 대한 출결 결과", nullable = true) | ||
AttendanceResult attendanceResult | ||
) { | ||
public static MemberAttendResponse closedAttendanceResponse(Session session, AttendanceRecord attendanceRecord) { | ||
return new MemberAttendResponse( | ||
session.getId(), | ||
attendanceRecord.getAttendance().getId(), | ||
attendanceRecord.getMemberId(), | ||
session.getTitle(), | ||
session.getSessionDate(), | ||
AttendanceOpenStatus.CLOSED, | ||
attendanceRecord.getAttendanceType(), | ||
attendanceRecord.getAttendanceResult() | ||
); | ||
} | ||
|
||
public static MemberAttendResponse openedAttendanceResponse(Attendance attendance, Session session, Long memberId) { | ||
return new MemberAttendResponse( | ||
session.getId(), | ||
attendance.getId(), | ||
memberId, | ||
session.getTitle(), | ||
session.getSessionDate(), | ||
AttendanceOpenStatus.OPEN, | ||
null, | ||
null | ||
); | ||
} | ||
} |
Oops, something went wrong.