diff --git a/src/main/java/life/mosu/mosuserver/application/application/ApplicationService.java b/src/main/java/life/mosu/mosuserver/application/application/ApplicationService.java index f6ba81ad..4a1348e3 100644 --- a/src/main/java/life/mosu/mosuserver/application/application/ApplicationService.java +++ b/src/main/java/life/mosu/mosuserver/application/application/ApplicationService.java @@ -41,7 +41,8 @@ public CreateApplicationResponse apply(Long userId, ApplicationRequest request) Set subjects = request.getSubjects(); - validator.ExamDateNotPassed(examIds); + validator.examNotFull(examIds); + validator.examDateNotPassed(examIds); validator.requestNoDuplicateExams(examIds); validator.examIdsAndLunchSelection(request.examApplication()); validator.noDuplicateApplication(userId, examIds); diff --git a/src/main/java/life/mosu/mosuserver/application/application/vaildator/ApplicationValidator.java b/src/main/java/life/mosu/mosuserver/application/application/vaildator/ApplicationValidator.java index e94d729d..9a9f81bf 100644 --- a/src/main/java/life/mosu/mosuserver/application/application/vaildator/ApplicationValidator.java +++ b/src/main/java/life/mosu/mosuserver/application/application/vaildator/ApplicationValidator.java @@ -3,8 +3,10 @@ import java.time.LocalDate; import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; +import life.mosu.mosuserver.application.exam.cache.ExamQuotaCacheManager; import life.mosu.mosuserver.domain.application.ApplicationJpaRepository; import life.mosu.mosuserver.domain.exam.ExamJpaEntity; import life.mosu.mosuserver.domain.exam.ExamJpaRepository; @@ -20,6 +22,7 @@ public class ApplicationValidator { private final ExamJpaRepository examJpaRepository; private final ApplicationJpaRepository applicationJpaRepository; + private final ExamQuotaCacheManager examQuotaCacheManager; public void requestNoDuplicateExams(List examIds) { Set examIdSet = new HashSet<>(examIds); @@ -30,7 +33,7 @@ public void requestNoDuplicateExams(List examIds) { public void examIdsAndLunchSelection(List requests) { if (requests == null || requests.isEmpty()) { - throw new CustomRuntimeException(ErrorCode.EXAM_APPLICATION_NOT_FOUND); + throw new CustomRuntimeException(ErrorCode.EXAM_NOT_FOUND); } List requestedExamIds = requests.stream() @@ -68,7 +71,7 @@ public void noDuplicateApplication(Long userId, List examIds) { } } - public void ExamDateNotPassed(List examIds) { + public void examDateNotPassed(List examIds) { List exams = examJpaRepository.findAllById(examIds); boolean hasPassedExam = exams.stream() .anyMatch(exam -> exam.getExamDate().isBefore(LocalDate.now())); @@ -77,4 +80,22 @@ public void ExamDateNotPassed(List examIds) { throw new CustomRuntimeException(ErrorCode.EXAM_DATE_PASSED); } } + + public void examNotFull(List examIds) { + boolean isFull = examIds.stream() + .anyMatch(examId -> { + Optional currentApplications = examQuotaCacheManager.getCurrentApplications( + examId); + Optional maxCapacity = examQuotaCacheManager.getMaxCapacity(examId); + + if (currentApplications.isPresent() && maxCapacity.isPresent()) { + return currentApplications.get() >= maxCapacity.get(); + } + return false; + }); + + if (isFull) { + throw new CustomRuntimeException(ErrorCode.APPLICATION_CLOSED); + } + } } \ No newline at end of file diff --git a/src/main/java/life/mosu/mosuserver/application/examapplication/ExamApplicationService.java b/src/main/java/life/mosu/mosuserver/application/examapplication/ExamApplicationService.java index 6907809c..fef7a1d1 100644 --- a/src/main/java/life/mosu/mosuserver/application/examapplication/ExamApplicationService.java +++ b/src/main/java/life/mosu/mosuserver/application/examapplication/ExamApplicationService.java @@ -16,7 +16,6 @@ import life.mosu.mosuserver.domain.examapplication.projection.ExamApplicationInfoProjection; import life.mosu.mosuserver.domain.examapplication.projection.ExamTicketInfoProjection; import life.mosu.mosuserver.domain.examapplication.service.ExamNumberGenerationService; -import life.mosu.mosuserver.domain.payment.PaymentJpaRepository; import life.mosu.mosuserver.global.exception.CustomRuntimeException; import life.mosu.mosuserver.global.exception.ErrorCode; import life.mosu.mosuserver.infra.persistence.s3.S3Service; @@ -39,7 +38,6 @@ public class ExamApplicationService { private final ApplicationJpaRepository applicationJpaRepository; private final ExamSubjectJpaRepository examSubjectJpaRepository; private final ExamNumberGenerationService examNumberGenerationService; - private final PaymentJpaRepository paymentJpaRepository; private final S3Service s3Service; private final FixedQuantityDiscountCalculator calculator; @@ -122,7 +120,7 @@ public ExamApplicationInfoResponse getApplication(Long userId, Long examApplicat // examApplicationId); List examApplicationEntities = examApplicationJpaRepository.findByApplicationId( applicationId); - Integer lunchCount = (int) examApplicationEntities.stream() + int lunchCount = (int) examApplicationEntities.stream() .filter(ExamApplicationJpaEntity::getIsLunchChecked) .count(); @@ -173,8 +171,11 @@ private void validateUser(Long userId, Long examApplicationId) { } private int getAppliedDiscountAmount(Integer totalAmount) { - log.info("total amount: {}", totalAmount); - return calculator.getAppliedDiscountAmount(totalAmount); + try { + return calculator.getAppliedDiscountAmount(totalAmount); + } catch (Exception ex) { + throw new CustomRuntimeException(ErrorCode.PRICE_LOAD_FAILURE); + } } private void validateExamTicketOpenDate(LocalDate examDate, String examNumber) { diff --git a/src/main/java/life/mosu/mosuserver/domain/refund/RefundJpaRepository.java b/src/main/java/life/mosu/mosuserver/domain/refund/RefundJpaRepository.java index 6a11db71..a10d64e3 100644 --- a/src/main/java/life/mosu/mosuserver/domain/refund/RefundJpaRepository.java +++ b/src/main/java/life/mosu/mosuserver/domain/refund/RefundJpaRepository.java @@ -26,7 +26,7 @@ public interface RefundJpaRepository extends JpaRepository findRefundByExamApplicationId( @Param("examApplicationId") Long examApplicationId); diff --git a/src/main/java/life/mosu/mosuserver/global/exception/ErrorCode.java b/src/main/java/life/mosu/mosuserver/global/exception/ErrorCode.java index 665b6071..93ca1f5a 100644 --- a/src/main/java/life/mosu/mosuserver/global/exception/ErrorCode.java +++ b/src/main/java/life/mosu/mosuserver/global/exception/ErrorCode.java @@ -64,6 +64,9 @@ public enum ErrorCode { APPLICATION_SCHOOL_DUPLICATED(HttpStatus.BAD_REQUEST, "동일 일자의 같은 학교를 신청할 수 없습니다."), EXAM_DUPLICATED(HttpStatus.BAD_REQUEST, "동일한 시험을 신청할 수 없습니다."), WRONG_APPLICATION_ID_TYPE(HttpStatus.BAD_REQUEST, "신청 ID 타입이 올바르지 않습니다."), + PRICE_LOAD_FAILURE(HttpStatus.CONFLICT, "신청 가격 정보를 가져오는데 실패했습니다."), + APPLICATION_CLOSED(HttpStatus.BAD_REQUEST, "신청이 마감되었습니다."), + // 프로필 관련 에러 PROFILE_ALREADY_EXISTS(HttpStatus.CONFLICT, "프로필이 이미 존재합니다."), PROFILE_NOT_FOUND(HttpStatus.NOT_FOUND, "프로필을 찾을 수 없습니다."), @@ -149,6 +152,8 @@ public enum ErrorCode { //LUA 관련 LUA_SCRIPT_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "LUA 스크립트 실행 중 오류가 발생했습니다."); + + private final HttpStatus status; private final String message; }