From 0d75aa8f954e4121e2ea715b85060387af4f7467 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=90=ED=98=84=EA=B2=BD?= Date: Thu, 5 Oct 2023 08:59:40 +0900 Subject: [PATCH 1/4] =?UTF-8?q?fix:=20=EC=84=B8=EB=AF=B8=EB=82=98=20?= =?UTF-8?q?=EC=B6=9C=EC=84=9D=EA=B3=BC=20=EB=B2=8C=EC=A0=90=20=EB=B6=80?= =?UTF-8?q?=EC=97=AC=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../merit/application/MeritLogService.java | 29 ---- .../application/SeminarAttendanceService.java | 31 +--- .../dao/SeminarAttendanceRepository.java | 8 +- .../SeminarAttendanceServiceTest.java | 142 ------------------ 4 files changed, 7 insertions(+), 203 deletions(-) diff --git a/src/main/java/com/keeper/homepage/domain/merit/application/MeritLogService.java b/src/main/java/com/keeper/homepage/domain/merit/application/MeritLogService.java index 371498c1c..dd09d9d23 100644 --- a/src/main/java/com/keeper/homepage/domain/merit/application/MeritLogService.java +++ b/src/main/java/com/keeper/homepage/domain/merit/application/MeritLogService.java @@ -11,8 +11,6 @@ import com.keeper.homepage.domain.merit.entity.MeritLog; import com.keeper.homepage.domain.merit.entity.MeritType; import com.keeper.homepage.global.error.BusinessException; -import java.time.LocalDate; -import java.time.LocalDateTime; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -28,9 +26,6 @@ public class MeritLogService { private final MeritTypeRepository meritTypeRepository; private final MemberFindService memberFindService; - private static final long SEMINAR_ABSENCE_MERIT_TYPE_ID = 2; - private static final long SEMINAR_DUAL_LATENESS_MERIT_TYPE_ID = 3; - @Transactional public Long recordMerit(long memberId, long meritTypeId) { Member member = memberFindService.findById(memberId); @@ -46,30 +41,6 @@ public Long recordMerit(long memberId, long meritTypeId) { .getId(); } - @Transactional - public void giveSeminarAbsenceDemerit(Member member) { - MeritType meritType = meritTypeRepository.findById(SEMINAR_ABSENCE_MERIT_TYPE_ID).orElseThrow(); - - meritLogRepository.save(MeritLog.builder() - .memberId(member.getId()) - .memberRealName(member.getRealName()) - .memberGeneration(member.getGeneration()) - .meritType(meritType) - .build()); - } - - @Transactional - public void giveDualSeminarLatenessDemerit(Member member) { - MeritType meritType = meritTypeRepository.findById(SEMINAR_DUAL_LATENESS_MERIT_TYPE_ID).orElseThrow(); - - meritLogRepository.save(MeritLog.builder() - .memberId(member.getId()) - .memberRealName(member.getRealName()) - .memberGeneration(member.getGeneration()) - .meritType(meritType) - .build()); - } - public Page findAllByMeritType(Pageable pageable, String meritType) { return switch (meritType) { case "MERIT" -> meritLogRepository.findMeritLogs(pageable); diff --git a/src/main/java/com/keeper/homepage/domain/seminar/application/SeminarAttendanceService.java b/src/main/java/com/keeper/homepage/domain/seminar/application/SeminarAttendanceService.java index cb2987e64..a9912f9de 100644 --- a/src/main/java/com/keeper/homepage/domain/seminar/application/SeminarAttendanceService.java +++ b/src/main/java/com/keeper/homepage/domain/seminar/application/SeminarAttendanceService.java @@ -1,10 +1,6 @@ package com.keeper.homepage.domain.seminar.application; -import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.SeminarAttendanceStatusType.ABSENCE; -import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.SeminarAttendanceStatusType.ATTENDANCE; import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.SeminarAttendanceStatusType.BEFORE_ATTENDANCE; -import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.SeminarAttendanceStatusType.LATENESS; -import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.getSeminarAttendanceStatusBy; import static com.keeper.homepage.global.error.ErrorCode.SEMINAR_ATTENDANCE_ATTEMPT_NOT_AVAILABLE; import static com.keeper.homepage.global.error.ErrorCode.SEMINAR_ATTENDANCE_CODE_NOT_AVAILABLE; import static com.keeper.homepage.global.error.ErrorCode.SEMINAR_ATTENDANCE_DUPLICATE; @@ -13,7 +9,6 @@ import com.keeper.homepage.domain.member.application.convenience.MemberFindService; import com.keeper.homepage.domain.member.entity.Member; -import com.keeper.homepage.domain.merit.application.MeritLogService; import com.keeper.homepage.domain.seminar.application.convenience.ValidSeminarFindService; import com.keeper.homepage.domain.seminar.dao.SeminarAttendanceRepository; import com.keeper.homepage.domain.seminar.dto.request.SeminarAttendanceStatusRequest; @@ -26,7 +21,6 @@ import com.keeper.homepage.global.util.redis.RedisUtil; import com.keeper.homepage.global.util.semester.SemesterUtil; import java.time.LocalDate; -import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -45,7 +39,6 @@ public class SeminarAttendanceService { private final ValidSeminarFindService validSeminarFindService; private final MemberFindService memberFindService; private final SeminarAttendanceRepository attendanceRepository; - private final MeritLogService meritLogService; private static final int MAX_ATTEMPT_COUNT = 5; private static final int ONE_HOUR = 60 * 60; @@ -63,7 +56,6 @@ public SeminarAttendanceResponse attendance(Long seminarId, Member member, Strin SeminarAttendanceStatusType type = seminar.getStatus().getType(); seminarAttendance.changeStatus(type); - giveAttendanceDemerit(type, member); return SeminarAttendanceResponse.of(seminarAttendance); } @@ -90,21 +82,6 @@ private void checkDuplicateAttendance(SeminarAttendance seminarAttendance) { } } - private void giveAttendanceDemerit(SeminarAttendanceStatusType type, Member member) { - if (type == ATTENDANCE) { - return; - } - if (type == LATENESS) { - if (member.isDualLateness()) { - meritLogService.giveDualSeminarLatenessDemerit(member); - } - return; - } - if (type == ABSENCE) { - meritLogService.giveSeminarAbsenceDemerit(member); - } - } - @Transactional public void changeStatus(long attendanceId, SeminarAttendanceStatusRequest request) { SeminarAttendance seminarAttendance = attendanceRepository.findById(attendanceId) @@ -115,13 +92,7 @@ public void changeStatus(long attendanceId, SeminarAttendanceStatusRequest reque @Scheduled(cron = "0 0 0 * * ?", zone = "Asia/Seoul") // 매일 자정에 실행 public void changeAllBeforeAttendanceToAbsence() { - List beforeAttendances = attendanceRepository - .findAllBySeminarAttendanceStatus(getSeminarAttendanceStatusBy(BEFORE_ATTENDANCE)); - - beforeAttendances.forEach(seminarAttendance -> { - seminarAttendance.changeStatus((ABSENCE)); - meritLogService.giveSeminarAbsenceDemerit(seminarAttendance.getMember()); - }); + attendanceRepository.updateAllBeforeAttendanceToAbsence(); } public Page getAttendances(Pageable pageable) { diff --git a/src/main/java/com/keeper/homepage/domain/seminar/dao/SeminarAttendanceRepository.java b/src/main/java/com/keeper/homepage/domain/seminar/dao/SeminarAttendanceRepository.java index 0b32db293..5d1b63f9e 100644 --- a/src/main/java/com/keeper/homepage/domain/seminar/dao/SeminarAttendanceRepository.java +++ b/src/main/java/com/keeper/homepage/domain/seminar/dao/SeminarAttendanceRepository.java @@ -3,11 +3,11 @@ import com.keeper.homepage.domain.member.entity.Member; import com.keeper.homepage.domain.seminar.entity.Seminar; import com.keeper.homepage.domain.seminar.entity.SeminarAttendance; -import com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus; import java.time.LocalDate; import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -17,7 +17,11 @@ public interface SeminarAttendanceRepository extends JpaRepository findBySeminarAndMember(Seminar seminar, Member member); - List findAllBySeminarAttendanceStatus(SeminarAttendanceStatus status); + @Modifying + @Query("UPDATE SeminarAttendance s " + + "SET s.seminarAttendanceStatus.id = 3 " + + "WHERE s.seminarAttendanceStatus.id = 5") + void updateAllBeforeAttendanceToAbsence(); @Query("SELECT s FROM SeminarAttendance s " + "WHERE s.member.id = :memberId " diff --git a/src/test/java/com/keeper/homepage/domain/seminar/application/SeminarAttendanceServiceTest.java b/src/test/java/com/keeper/homepage/domain/seminar/application/SeminarAttendanceServiceTest.java index 1ec4fe317..0b425552f 100644 --- a/src/test/java/com/keeper/homepage/domain/seminar/application/SeminarAttendanceServiceTest.java +++ b/src/test/java/com/keeper/homepage/domain/seminar/application/SeminarAttendanceServiceTest.java @@ -1,20 +1,14 @@ package com.keeper.homepage.domain.seminar.application; -import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.SeminarAttendanceStatusType.ABSENCE; -import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.SeminarAttendanceStatusType.BEFORE_ATTENDANCE; import static com.keeper.homepage.global.error.ErrorCode.SEMINAR_ATTENDANCE_ATTEMPT_NOT_AVAILABLE; import static com.keeper.homepage.global.error.ErrorCode.SEMINAR_ATTENDANCE_CODE_NOT_AVAILABLE; -import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; import com.keeper.homepage.IntegrationTest; import com.keeper.homepage.domain.member.entity.Member; -import com.keeper.homepage.domain.merit.entity.MeritLog; import com.keeper.homepage.domain.seminar.entity.Seminar; import com.keeper.homepage.global.error.BusinessException; import java.time.LocalDate; -import java.time.LocalDateTime; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -47,140 +41,4 @@ class AttemptLimitTest { .hasMessageContaining(SEMINAR_ATTENDANCE_ATTEMPT_NOT_AVAILABLE.getMessage()); } } - - @Nested - @DisplayName("세미나 지각 & 결석 벌점 테스트") - class SeminarDemeritTest { - - private Member member, admin; - private static final long SEMINAR_ABSENCE_MERIT_TYPE_ID = 2; - private static final long SEMINAR_DUAL_LATENESS_MERIT_TYPE_ID = 3; - - @BeforeEach - void setUp() { - admin = memberTestHelper.generate(); - member = memberTestHelper.generate(); - } - - @Test - @DisplayName("세미나 출석일 경우 벌점이 부여되지 않아야 한다.") - public void 세미나_출석일_경우_벌점이_부여되지_않아야_한다() throws Exception { - //given - LocalDateTime now = LocalDateTime.now(); - - long seminarId = seminarService.save(LocalDate.now()).id(); - String attendanceCode = seminarService.start(admin, seminarId, now.plusMinutes(5), now.plusMinutes(10)) - .attendanceCode(); - - //when - seminarAttendanceService.attendance(seminarId, member, attendanceCode); - - em.flush(); - em.clear(); - - //then - assertThat(meritLogRepository.findByMemberId(member.getId())).isEmpty(); - } - - @Test - @DisplayName("세미나 결석일 경우 벌점이 부여되어야 한다.") - public void 세미나_결석일_경우_벌점이_부여되어야_한다() throws Exception { - //given - LocalDateTime now = LocalDateTime.now(); - - long seminarId = seminarService.save(LocalDate.now()).id(); - String attendanceCode = seminarService.start(admin, seminarId, now.minusMinutes(10), now.minusMinutes(5)) - .attendanceCode(); - - //when - seminarAttendanceService.attendance(seminarId, member, attendanceCode); - - em.flush(); - em.clear(); - - //then - MeritLog meritLog = meritLogRepository.findByMemberId(member.getId()).orElseThrow(); - assertThat(meritLog.getMeritType().getId()).isEqualTo(SEMINAR_ABSENCE_MERIT_TYPE_ID); - } - - @Test - @DisplayName("세미나 지각 1회일 경우 벌점이 부여되지 않아야 한다.") - public void 세미나_지각_1회일_경우_벌점이_부여되지_않아야_한다() throws Exception { - //given - LocalDateTime now = LocalDateTime.now(); - - long seminarId = seminarService.save(LocalDate.now()).id(); - String attendanceCode = seminarService.start(admin, seminarId, now.minusMinutes(5), now.plusDays(5)) - .attendanceCode(); - - //when - seminarAttendanceService.attendance(seminarId, member, attendanceCode); - - em.flush(); - em.clear(); - - //then - assertThat(meritLogRepository.findByMemberId(member.getId())).isEmpty(); - } - - @Test - @DisplayName("세미나 지각 2회일 경우 벌점이 부여되어야 한다.") - public void 세미나_지각_2회일_경우_벌점이_부여되어야_한다() throws Exception { - //given - LocalDateTime now = LocalDateTime.now(); - - long seminarId = seminarService.save(now.toLocalDate()).id(); - String attendanceCode = seminarService.start(admin, seminarId, now.minusMinutes(5), now.plusDays(5)) - .attendanceCode(); - - long otherSeminarId = seminarService.save(now.plusDays(1).toLocalDate()).id(); - String otherAttendanceCode = seminarService.start(admin, otherSeminarId, now.minusMinutes(5), now.plusDays(5)) - .attendanceCode(); - - //when - seminarAttendanceService.attendance(seminarId, member, attendanceCode); - em.flush(); - em.clear(); - - member = memberRepository.findById(member.getId()).orElseThrow(); - seminarAttendanceService.attendance(otherSeminarId, member, otherAttendanceCode); - - em.flush(); - em.clear(); - - //then - MeritLog meritLog = meritLogRepository.findByMemberId(member.getId()).orElseThrow(); - assertThat(meritLog.getMeritType().getId()).isEqualTo(SEMINAR_DUAL_LATENESS_MERIT_TYPE_ID); - } - - @Test - @DisplayName("출석을 하지 않은 회원은 결석으로 간주되어 벌점이 부여되어야 한다.") - public void 출석을_하지_않은_회원은_결석으로_간주되어_벌점이_부여되어야_한다() throws Exception { - //given - LocalDateTime now = LocalDateTime.now(); - - long seminarId = seminarService.save(LocalDate.now()).id(); - seminarService.start(admin, seminarId, now.minusMinutes(10), now.minusMinutes(5)); - - em.flush(); - em.clear(); - member = memberRepository.findById(member.getId()).orElseThrow(); - assertThat(member.getSeminarAttendances()).hasSize(1); - assertThat(member.getSeminarAttendances().get(0).getSeminarAttendanceStatus().getType()) - .isEqualTo(BEFORE_ATTENDANCE); - - //when - seminarAttendanceService.changeAllBeforeAttendanceToAbsence(); - em.flush(); - em.clear(); - - //then - member = memberRepository.findById(member.getId()).orElseThrow(); - assertThat(member.getSeminarAttendances()).hasSize(1); - assertThat(member.getSeminarAttendances().get(0).getSeminarAttendanceStatus().getType()).isEqualTo(ABSENCE); - - MeritLog meritLog = meritLogRepository.findByMemberId(member.getId()).orElseThrow(); - assertThat(meritLog.getMeritType().getId()).isEqualTo(SEMINAR_ABSENCE_MERIT_TYPE_ID); - } - } } From c23572697515a7fa1234c515086d9e3fb3158f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=90=ED=98=84=EA=B2=BD?= Date: Thu, 5 Oct 2023 09:22:48 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=EC=A7=80=EA=B0=81,=20=EA=B0=9C?= =?UTF-8?q?=EC=9D=B8=EC=82=AC=EC=A0=95=EC=9D=BC=20=EA=B2=BD=EC=9A=B0?= =?UTF-8?q?=EC=97=90=EB=A7=8C=20=EC=B6=9C=EC=84=9D=20=EC=83=81=ED=83=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EC=8B=9C=20=EC=82=AC=EC=9C=A0=EB=A5=BC=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/SeminarAttendanceController.java | 5 +- .../application/SeminarAttendanceService.java | 12 +++-- .../SeminarAttendanceExcuseRepository.java | 4 ++ .../dao/SeminarAttendanceRepository.java | 4 +- .../seminar/entity/SeminarAttendance.java | 2 +- .../api/SeminarAttendanceControllerTest.java | 2 +- .../SeminarAttendanceServiceTest.java | 53 +++++++++++++++++++ .../dao/SeminarAttendanceRepositoryTest.java | 12 +++-- 8 files changed, 79 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/keeper/homepage/domain/seminar/api/SeminarAttendanceController.java b/src/main/java/com/keeper/homepage/domain/seminar/api/SeminarAttendanceController.java index bfe53f65f..09b633f87 100644 --- a/src/main/java/com/keeper/homepage/domain/seminar/api/SeminarAttendanceController.java +++ b/src/main/java/com/keeper/homepage/domain/seminar/api/SeminarAttendanceController.java @@ -53,11 +53,12 @@ public ResponseEntity> getAttendances( return ResponseEntity.ok(responses); } - @PatchMapping("/attendances/{attendanceId}") // TODO: 관리자 권한으로 접근 가능하게 설정 + @Secured({"ROLE_회장", "ROLE_부회장", "ROLE_서기"}) + @PatchMapping("/attendances/{attendanceId}") public ResponseEntity changeAttendanceStatus( @PathVariable long attendanceId, @RequestBody @Valid SeminarAttendanceStatusRequest request) { - seminarAttendanceService.changeStatus(attendanceId, request); + seminarAttendanceService.changeStatus(attendanceId, request.statusType(), request.excuse()); return ResponseEntity.noContent().build(); } } diff --git a/src/main/java/com/keeper/homepage/domain/seminar/application/SeminarAttendanceService.java b/src/main/java/com/keeper/homepage/domain/seminar/application/SeminarAttendanceService.java index a9912f9de..73de5eeee 100644 --- a/src/main/java/com/keeper/homepage/domain/seminar/application/SeminarAttendanceService.java +++ b/src/main/java/com/keeper/homepage/domain/seminar/application/SeminarAttendanceService.java @@ -1,6 +1,8 @@ package com.keeper.homepage.domain.seminar.application; import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.SeminarAttendanceStatusType.BEFORE_ATTENDANCE; +import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.SeminarAttendanceStatusType.LATENESS; +import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.SeminarAttendanceStatusType.PERSONAL; import static com.keeper.homepage.global.error.ErrorCode.SEMINAR_ATTENDANCE_ATTEMPT_NOT_AVAILABLE; import static com.keeper.homepage.global.error.ErrorCode.SEMINAR_ATTENDANCE_CODE_NOT_AVAILABLE; import static com.keeper.homepage.global.error.ErrorCode.SEMINAR_ATTENDANCE_DUPLICATE; @@ -11,7 +13,6 @@ import com.keeper.homepage.domain.member.entity.Member; import com.keeper.homepage.domain.seminar.application.convenience.ValidSeminarFindService; import com.keeper.homepage.domain.seminar.dao.SeminarAttendanceRepository; -import com.keeper.homepage.domain.seminar.dto.request.SeminarAttendanceStatusRequest; import com.keeper.homepage.domain.seminar.dto.response.SeminarAttendanceManageResponse; import com.keeper.homepage.domain.seminar.dto.response.SeminarAttendanceResponse; import com.keeper.homepage.domain.seminar.entity.Seminar; @@ -83,11 +84,14 @@ private void checkDuplicateAttendance(SeminarAttendance seminarAttendance) { } @Transactional - public void changeStatus(long attendanceId, SeminarAttendanceStatusRequest request) { + public void changeStatus(long attendanceId, SeminarAttendanceStatusType statusType, String excuse) { SeminarAttendance seminarAttendance = attendanceRepository.findById(attendanceId) .orElseThrow(() -> new BusinessException(attendanceId, "attendanceId", SEMINAR_ATTENDANCE_NOT_FOUND)); - - seminarAttendance.changeStatus(request.excuse(), request.statusType()); + if (statusType == LATENESS || statusType == PERSONAL) { + seminarAttendance.changeStatus(statusType, excuse); + return; + } + seminarAttendance.changeStatus(statusType); } @Scheduled(cron = "0 0 0 * * ?", zone = "Asia/Seoul") // 매일 자정에 실행 diff --git a/src/main/java/com/keeper/homepage/domain/seminar/dao/SeminarAttendanceExcuseRepository.java b/src/main/java/com/keeper/homepage/domain/seminar/dao/SeminarAttendanceExcuseRepository.java index 63a8a936f..810cc495e 100644 --- a/src/main/java/com/keeper/homepage/domain/seminar/dao/SeminarAttendanceExcuseRepository.java +++ b/src/main/java/com/keeper/homepage/domain/seminar/dao/SeminarAttendanceExcuseRepository.java @@ -1,8 +1,12 @@ package com.keeper.homepage.domain.seminar.dao; +import com.keeper.homepage.domain.seminar.entity.SeminarAttendance; import com.keeper.homepage.domain.seminar.entity.SeminarAttendanceExcuse; +import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; public interface SeminarAttendanceExcuseRepository extends JpaRepository { + Optional findAllBySeminarAttendance(SeminarAttendance seminarAttendance); + } diff --git a/src/main/java/com/keeper/homepage/domain/seminar/dao/SeminarAttendanceRepository.java b/src/main/java/com/keeper/homepage/domain/seminar/dao/SeminarAttendanceRepository.java index 5d1b63f9e..801a35e56 100644 --- a/src/main/java/com/keeper/homepage/domain/seminar/dao/SeminarAttendanceRepository.java +++ b/src/main/java/com/keeper/homepage/domain/seminar/dao/SeminarAttendanceRepository.java @@ -19,8 +19,8 @@ public interface SeminarAttendanceRepository extends JpaRepository getExcuse() { return Optional.ofNullable(this.getSeminarAttendanceExcuse().getAbsenceExcuse()); } - public void changeStatus(String excuse, SeminarAttendanceStatusType type) { + public void changeStatus(SeminarAttendanceStatusType type, String excuse) { seminarAttendanceStatus = getSeminarAttendanceStatusBy(type); if (seminarAttendanceExcuse == null) { seminarAttendanceExcuse = SeminarAttendanceExcuse.builder() diff --git a/src/test/java/com/keeper/homepage/domain/seminar/api/SeminarAttendanceControllerTest.java b/src/test/java/com/keeper/homepage/domain/seminar/api/SeminarAttendanceControllerTest.java index b3b1d8976..309477603 100644 --- a/src/test/java/com/keeper/homepage/domain/seminar/api/SeminarAttendanceControllerTest.java +++ b/src/test/java/com/keeper/homepage/domain/seminar/api/SeminarAttendanceControllerTest.java @@ -219,7 +219,7 @@ public void should_success_when_changeSeminarAttendanceStatus() throws Exception .description("출석 상태를 변경하고자 하는 세미나 출석 ID") ), requestFields( - field("excuse", "세미나 사유"), + field("excuse", "세미나 사유").optional(), field("statusType", "출석 타입")) )).andReturn(); } diff --git a/src/test/java/com/keeper/homepage/domain/seminar/application/SeminarAttendanceServiceTest.java b/src/test/java/com/keeper/homepage/domain/seminar/application/SeminarAttendanceServiceTest.java index 0b425552f..93f99c334 100644 --- a/src/test/java/com/keeper/homepage/domain/seminar/application/SeminarAttendanceServiceTest.java +++ b/src/test/java/com/keeper/homepage/domain/seminar/application/SeminarAttendanceServiceTest.java @@ -1,12 +1,18 @@ package com.keeper.homepage.domain.seminar.application; +import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.SeminarAttendanceStatusType.ABSENCE; +import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.SeminarAttendanceStatusType.BEFORE_ATTENDANCE; +import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.SeminarAttendanceStatusType.LATENESS; +import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.getSeminarAttendanceStatusBy; import static com.keeper.homepage.global.error.ErrorCode.SEMINAR_ATTENDANCE_ATTEMPT_NOT_AVAILABLE; import static com.keeper.homepage.global.error.ErrorCode.SEMINAR_ATTENDANCE_CODE_NOT_AVAILABLE; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; import com.keeper.homepage.IntegrationTest; import com.keeper.homepage.domain.member.entity.Member; import com.keeper.homepage.domain.seminar.entity.Seminar; +import com.keeper.homepage.domain.seminar.entity.SeminarAttendance; import com.keeper.homepage.global.error.BusinessException; import java.time.LocalDate; import org.junit.jupiter.api.DisplayName; @@ -41,4 +47,51 @@ class AttemptLimitTest { .hasMessageContaining(SEMINAR_ATTENDANCE_ATTEMPT_NOT_AVAILABLE.getMessage()); } } + + @Nested + @DisplayName("세미나 출석 상태 변경 테스트") + class ChangeAttendanceStatusTest { + + @Test + @DisplayName("지각, 개인사정으로 변경할 경우 사유도 변경되어야 한다.") + public void 지각_개인사정으로_변경할_경우_사유도_변경되어야_한다() throws Exception { + //given + SeminarAttendance seminarAttendance = seminarAttendanceTestHelper.builder() + .seminarAttendanceStatus(getSeminarAttendanceStatusBy(BEFORE_ATTENDANCE)) + .build(); + long seminarAttendanceId = seminarAttendance.getId(); + String excuse = "늦잠"; + + //when + seminarAttendanceService.changeStatus(seminarAttendance.getId(), LATENESS, excuse); + em.flush(); + em.clear(); + + //then + SeminarAttendance findSeminarAttendance = seminarAttendanceRepository.findById(seminarAttendanceId).orElseThrow(); + assertThat(findSeminarAttendance.getSeminarAttendanceStatus().getType()).isEqualTo(LATENESS); + assertThat(findSeminarAttendance.getSeminarAttendanceExcuse()).isNotNull(); + assertThat(findSeminarAttendance.getSeminarAttendanceExcuse().getAbsenceExcuse()).isEqualTo(excuse); + } + + @Test + @DisplayName("지각, 개인사정 외의 출석 상태 타입으로 변경할 경우 사유는 변경되지 않는다.") + public void 지각_개인사정_외의_출석_상태_타입으로_변경할_경우_사유는_변경되지_않는다() throws Exception { + //given + SeminarAttendance seminarAttendance = seminarAttendanceTestHelper.builder() + .seminarAttendanceStatus(getSeminarAttendanceStatusBy(BEFORE_ATTENDANCE)) + .build(); + long seminarAttendanceId = seminarAttendance.getId(); + + //when + seminarAttendanceService.changeStatus(seminarAttendance.getId(), ABSENCE, null); + em.flush(); + em.clear(); + + //then + SeminarAttendance findSeminarAttendance = seminarAttendanceRepository.findById(seminarAttendanceId).orElseThrow(); + assertThat(findSeminarAttendance.getSeminarAttendanceStatus().getType()).isEqualTo(ABSENCE); + assertThat(findSeminarAttendance.getSeminarAttendanceExcuse()).isNull(); + } + } } diff --git a/src/test/java/com/keeper/homepage/domain/seminar/dao/SeminarAttendanceRepositoryTest.java b/src/test/java/com/keeper/homepage/domain/seminar/dao/SeminarAttendanceRepositoryTest.java index 488bf26b2..a2e83c9c0 100644 --- a/src/test/java/com/keeper/homepage/domain/seminar/dao/SeminarAttendanceRepositoryTest.java +++ b/src/test/java/com/keeper/homepage/domain/seminar/dao/SeminarAttendanceRepositoryTest.java @@ -53,7 +53,8 @@ void should_check_when_SavedSeminarAttendance() { seminarAttendance = seminarAttendanceRepository.findById(seminarAttendanceId).orElseThrow(); assertThat(seminarAttendance.getMember().getId()).isEqualTo(member.getId()); - assertThat(seminarAttendance.getMember().getProfile().getStudentId()).isEqualTo(member.getProfile().getStudentId()); + assertThat(seminarAttendance.getMember().getProfile().getStudentId()).isEqualTo( + member.getProfile().getStudentId()); assertThat(seminarAttendance.getSeminar().getId()).isEqualTo(seminar.getId()); assertThat(seminarAttendance.getSeminar().getAttendanceCode()).isEqualTo(seminar.getAttendanceCode()); assertThat(seminarAttendance.getSeminar().getName()).isNotNull(); @@ -70,7 +71,7 @@ class SeminarAttendanceExcuseAndStatusTest { @DisplayName("DB에 세미나 지각 사유를 저장해야 한다.") void should_success_when_saveAttendExcuseSeminar() { String excuse = "늦게 일어나서"; - seminarAttendance.changeStatus(excuse, LATENESS); + seminarAttendance.changeStatus(LATENESS, excuse); em.flush(); em.clear(); @@ -96,12 +97,12 @@ public void should_returnEmpty_when_EmptyAttendExcuseSeminar() throws Exception @DisplayName("DB에 세미나 지각 사유를 수정해야 한다.") void should_success_when_modifyAttendExcuseSeminar() { String excuse = "늦게 일어났습니다!"; - seminarAttendance.changeStatus("늦게 일어나서", LATENESS); + seminarAttendance.changeStatus(LATENESS, "늦게 일어나서"); em.flush(); em.clear(); seminarAttendance = seminarAttendanceRepository.findById(seminarAttendanceId).orElseThrow(); - seminarAttendance.changeStatus(excuse, LATENESS); + seminarAttendance.changeStatus(LATENESS, excuse); SeminarAttendanceExcuse attendanceExcuse = seminarAttendanceExcuseRepository.findById(seminarAttendanceId) .orElseThrow(); @@ -113,10 +114,11 @@ void should_success_when_modifyAttendExcuseSeminar() { @Nested @DisplayName("세미나 참석 삭제 테스트") class SeminarAttendanceDeleteTest { + @Test @DisplayName("DB에 저장된 세미나 참석 정보를 삭제했을 때 지각 사유도 삭제되어야 한다.") void should_deleteSeminarAttendance_when_deleteSeminarAttendanceStatus() { - seminarAttendance.changeStatus("늦게 일어나서", LATENESS); + seminarAttendance.changeStatus(LATENESS, "늦게 일어나서"); em.flush(); em.clear(); From 5332ee7dd4f5b503a45c056b0098490981ac0dfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=90=ED=98=84=EA=B2=BD?= Date: Thu, 5 Oct 2023 09:32:24 +0900 Subject: [PATCH 3/4] =?UTF-8?q?feat:=20=EC=84=B8=EB=AF=B8=EB=82=98=20?= =?UTF-8?q?=EC=B6=9C=EC=84=9D=20=EC=A0=95=EB=B3=B4=20=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=9D=91=EB=8B=B5=EC=97=90=20=EC=B4=9D=20?= =?UTF-8?q?=EC=B6=9C=EC=84=9D,=20=EC=A7=80=EA=B0=81,=20=EA=B2=B0=EC=84=9D,?= =?UTF-8?q?=20=EA=B0=9C=EC=9D=B8=EC=82=AC=EC=A0=95=20=EC=88=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SeminarAttendanceManageResponse.java | 20 +++++++++++++++++++ .../seminar/entity/SeminarAttendance.java | 5 +++++ .../api/SeminarAttendanceControllerTest.java | 4 ++++ 3 files changed, 29 insertions(+) diff --git a/src/main/java/com/keeper/homepage/domain/seminar/dto/response/SeminarAttendanceManageResponse.java b/src/main/java/com/keeper/homepage/domain/seminar/dto/response/SeminarAttendanceManageResponse.java index 7f9d52373..512086957 100644 --- a/src/main/java/com/keeper/homepage/domain/seminar/dto/response/SeminarAttendanceManageResponse.java +++ b/src/main/java/com/keeper/homepage/domain/seminar/dto/response/SeminarAttendanceManageResponse.java @@ -1,5 +1,9 @@ package com.keeper.homepage.domain.seminar.dto.response; +import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.SeminarAttendanceStatusType.ABSENCE; +import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.SeminarAttendanceStatusType.ATTENDANCE; +import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.SeminarAttendanceStatusType.LATENESS; +import static com.keeper.homepage.domain.seminar.entity.SeminarAttendanceStatus.SeminarAttendanceStatusType.PERSONAL; import static lombok.AccessLevel.PACKAGE; import static lombok.AccessLevel.PRIVATE; @@ -21,6 +25,10 @@ public class SeminarAttendanceManageResponse { private String memberName; private String generation; private List attendances; + private long totalAttendance; + private long totalLateness; + private long totalAbsence; + private long totalPersonal; public static SeminarAttendanceManageResponse of(Member member, List seminarAttendances) { return SeminarAttendanceManageResponse.builder() @@ -28,6 +36,18 @@ public static SeminarAttendanceManageResponse of(Member member, List seminarAttendance.isStatus(ATTENDANCE)) + .count()) + .totalLateness(seminarAttendances.stream() + .filter(seminarAttendance -> seminarAttendance.isStatus(LATENESS)) + .count()) + .totalAbsence(seminarAttendances.stream() + .filter(seminarAttendance -> seminarAttendance.isStatus(ABSENCE)) + .count()) + .totalPersonal(seminarAttendances.stream() + .filter(seminarAttendance -> seminarAttendance.isStatus(PERSONAL)) + .count()) .build(); } } diff --git a/src/main/java/com/keeper/homepage/domain/seminar/entity/SeminarAttendance.java b/src/main/java/com/keeper/homepage/domain/seminar/entity/SeminarAttendance.java index d7751eadb..35e4a9e34 100644 --- a/src/main/java/com/keeper/homepage/domain/seminar/entity/SeminarAttendance.java +++ b/src/main/java/com/keeper/homepage/domain/seminar/entity/SeminarAttendance.java @@ -94,4 +94,9 @@ public boolean isLateness() { SeminarAttendanceStatusType type = getSeminarAttendanceStatus().getType(); return type.equals(LATENESS); } + + public boolean isStatus(SeminarAttendanceStatusType statusType) { + SeminarAttendanceStatusType type = getSeminarAttendanceStatus().getType(); + return type.equals(statusType); + } } diff --git a/src/test/java/com/keeper/homepage/domain/seminar/api/SeminarAttendanceControllerTest.java b/src/test/java/com/keeper/homepage/domain/seminar/api/SeminarAttendanceControllerTest.java index 309477603..17633dd95 100644 --- a/src/test/java/com/keeper/homepage/domain/seminar/api/SeminarAttendanceControllerTest.java +++ b/src/test/java/com/keeper/homepage/domain/seminar/api/SeminarAttendanceControllerTest.java @@ -311,6 +311,10 @@ FieldDescriptor[] getAttendances() { fieldWithPath("attendances[].attendDate").description("세미나 출석 날짜"), fieldWithPath("attendances[].attendanceStatus").description("세미나 출석 상태"), fieldWithPath("attendances[].excuse").description("세미나 결석/지각 사유").optional(), + fieldWithPath("totalAttendance").description("총 출석일"), + fieldWithPath("totalLateness").description("총 지각일"), + fieldWithPath("totalAbsence").description("총 결석일"), + fieldWithPath("totalPersonal").description("총 개인사정일"), }; } } From f780c87a4051041b84297b6ed90df0b4db3757ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=86=90=ED=98=84=EA=B2=BD?= Date: Fri, 6 Oct 2023 12:49:48 +0900 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20equals=20=EB=8C=80=EC=8B=A0=20=3D=3D?= =?UTF-8?q?=20=EC=97=B0=EC=82=B0=EC=9E=90=EB=A5=BC=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../homepage/domain/seminar/entity/SeminarAttendance.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/keeper/homepage/domain/seminar/entity/SeminarAttendance.java b/src/main/java/com/keeper/homepage/domain/seminar/entity/SeminarAttendance.java index 35e4a9e34..729f41ecc 100644 --- a/src/main/java/com/keeper/homepage/domain/seminar/entity/SeminarAttendance.java +++ b/src/main/java/com/keeper/homepage/domain/seminar/entity/SeminarAttendance.java @@ -92,11 +92,11 @@ private SeminarAttendance(Seminar seminar, Member member, public boolean isLateness() { SeminarAttendanceStatusType type = getSeminarAttendanceStatus().getType(); - return type.equals(LATENESS); + return type == LATENESS; } public boolean isStatus(SeminarAttendanceStatusType statusType) { SeminarAttendanceStatusType type = getSeminarAttendanceStatus().getType(); - return type.equals(statusType); + return type == statusType; } }