diff --git a/src/main/java/life/mosu/mosuserver/application/auth/processor/SignUpAccountStepProcessor.java b/src/main/java/life/mosu/mosuserver/application/auth/processor/SignUpAccountStepProcessor.java index bab8cb99..6adfd03c 100644 --- a/src/main/java/life/mosu/mosuserver/application/auth/processor/SignUpAccountStepProcessor.java +++ b/src/main/java/life/mosu/mosuserver/application/auth/processor/SignUpAccountStepProcessor.java @@ -18,7 +18,8 @@ public class SignUpAccountStepProcessor implements StepProcessor { existingUser.updateOAuthUser( info.gender(), diff --git a/src/main/java/life/mosu/mosuserver/application/refund/RefundService.java b/src/main/java/life/mosu/mosuserver/application/refund/RefundService.java index ffd8d406..2cbbff09 100644 --- a/src/main/java/life/mosu/mosuserver/application/refund/RefundService.java +++ b/src/main/java/life/mosu/mosuserver/application/refund/RefundService.java @@ -10,10 +10,12 @@ import life.mosu.mosuserver.global.exception.ErrorCode; import life.mosu.mosuserver.infra.toss.dto.CancelTossPaymentResponse; import life.mosu.mosuserver.presentation.refund.dto.MergedRefundRequest; +import life.mosu.mosuserver.presentation.refund.dto.RefundAmountResponse; import life.mosu.mosuserver.presentation.refund.dto.RefundRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; @@ -28,6 +30,16 @@ public class RefundService { private final TossRefundProcessor tossRefundProcessor; private final PaymentJpaRepository paymentJpaRepository; + @Transactional(propagation = Propagation.SUPPORTS, readOnly = true) + public RefundAmountResponse getRefundAmount(String paymentKey, Long examApplicationId) { + PaymentWithLunchProjection targetPayment = findPaymentOrThrow(paymentKey, + examApplicationId); + + int totalQuantity = getTotalPaymentCount(paymentKey); + int refundAmount = calculateRefundAmount(totalQuantity, targetPayment.lunchChecked()); + return RefundAmountResponse.of(refundAmount); + } + @Transactional public void doProcess(Long userId, MergedRefundRequest request) { RefundRequest details = request.details(); diff --git a/src/main/java/life/mosu/mosuserver/application/user/UserService.java b/src/main/java/life/mosu/mosuserver/application/user/UserService.java index 39c9a663..be991f70 100644 --- a/src/main/java/life/mosu/mosuserver/application/user/UserService.java +++ b/src/main/java/life/mosu/mosuserver/application/user/UserService.java @@ -51,4 +51,8 @@ public UserInfoResponse getUserInfo(Long userId) { return UserInfoResponse.from(user); } + + public Boolean isPhoneNumberAvailable(String phoneNumber) { + return !userJpaRepository.existsByPhoneNumber(phoneNumber); + } } diff --git a/src/main/java/life/mosu/mosuserver/domain/user/repository/UserJpaRepository.java b/src/main/java/life/mosu/mosuserver/domain/user/repository/UserJpaRepository.java index cd553965..e5038a33 100644 --- a/src/main/java/life/mosu/mosuserver/domain/user/repository/UserJpaRepository.java +++ b/src/main/java/life/mosu/mosuserver/domain/user/repository/UserJpaRepository.java @@ -10,8 +10,9 @@ public interface UserJpaRepository extends JpaRepository { boolean existsByLoginId(String loginId); - Optional findByNameAndPhoneNumber(String name, String phoneNumber); Optional findByPhoneNumber(String phoneNumber); + + boolean existsByPhoneNumber(String phoneNumber); } diff --git a/src/main/java/life/mosu/mosuserver/global/filter/Whitelist.java b/src/main/java/life/mosu/mosuserver/global/filter/Whitelist.java index 47e65e9e..ea197fdb 100644 --- a/src/main/java/life/mosu/mosuserver/global/filter/Whitelist.java +++ b/src/main/java/life/mosu/mosuserver/global/filter/Whitelist.java @@ -42,6 +42,9 @@ public enum Whitelist { FAQ("/api/v1/faq", WhitelistMethod.GET), NOTICE("/api/v1/notice", WhitelistMethod.GET), USER_ID_CHECK("/api/v1/user/check-id", WhitelistMethod.GET), + USER_PHONE_NUMBER_CHECK("/api/v1/user/check-phone-number", WhitelistMethod.GET), + + CUSTOMER_KEY_CHECK("/api/v1/user/customer-key", WhitelistMethod.GET), EXAM("/api/v1/exam", WhitelistMethod.GET), EXAM_AREAS("/api/v1/exam/areas", WhitelistMethod.GET), EXAM_ALL("/api/v1/exam/all", WhitelistMethod.GET), diff --git a/src/main/java/life/mosu/mosuserver/presentation/refund/RefundController.java b/src/main/java/life/mosu/mosuserver/presentation/refund/RefundController.java index 85688606..ce09a8e4 100644 --- a/src/main/java/life/mosu/mosuserver/presentation/refund/RefundController.java +++ b/src/main/java/life/mosu/mosuserver/presentation/refund/RefundController.java @@ -4,16 +4,19 @@ import life.mosu.mosuserver.global.annotation.UserId; import life.mosu.mosuserver.global.util.ApiResponseWrapper; import life.mosu.mosuserver.presentation.refund.dto.MergedRefundRequest; +import life.mosu.mosuserver.presentation.refund.dto.RefundAmountResponse; import life.mosu.mosuserver.presentation.refund.dto.RefundRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.GetMapping; 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; @RestController @@ -24,6 +27,15 @@ public class RefundController { private final RefundService refundService; + @GetMapping() + ResponseEntity> getRefundAmount( + @RequestParam(required = true) String paymentKey, + @RequestParam(required = true) Long examApplicationId) { + var response = refundService.getRefundAmount(paymentKey, examApplicationId); + return ResponseEntity.ok( + ApiResponseWrapper.success(HttpStatus.OK, "환불 금액 조회 성공", response)); + } + @PostMapping("/{paymentKey}") @PreAuthorize("isAuthenticated() and hasRole('USER')") ResponseEntity> process( diff --git a/src/main/java/life/mosu/mosuserver/presentation/refund/dto/RefundAmountResponse.java b/src/main/java/life/mosu/mosuserver/presentation/refund/dto/RefundAmountResponse.java new file mode 100644 index 00000000..2cfd00f8 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/presentation/refund/dto/RefundAmountResponse.java @@ -0,0 +1,11 @@ +package life.mosu.mosuserver.presentation.refund.dto; + +public record RefundAmountResponse( + int amount +) { + + public static RefundAmountResponse of(int amount) { + return new RefundAmountResponse(amount); + } + +} diff --git a/src/main/java/life/mosu/mosuserver/presentation/user/UserController.java b/src/main/java/life/mosu/mosuserver/presentation/user/UserController.java index 0a5f0bf3..016bb936 100644 --- a/src/main/java/life/mosu/mosuserver/presentation/user/UserController.java +++ b/src/main/java/life/mosu/mosuserver/presentation/user/UserController.java @@ -2,10 +2,12 @@ import life.mosu.mosuserver.application.user.UserService; import life.mosu.mosuserver.global.annotation.LoginIdPattern; +import life.mosu.mosuserver.global.annotation.PhoneNumberPattern; import life.mosu.mosuserver.global.annotation.UserId; import life.mosu.mosuserver.global.util.ApiResponseWrapper; -import life.mosu.mosuserver.presentation.user.dto.request.IsLoginIdAvailableResponse; import life.mosu.mosuserver.presentation.user.dto.response.CustomerKeyResponse; +import life.mosu.mosuserver.presentation.user.dto.response.IsLoginIdAvailableResponse; +import life.mosu.mosuserver.presentation.user.dto.response.IsPhoneNumberAvailableResponse; import life.mosu.mosuserver.presentation.user.dto.response.UserInfoResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; @@ -58,4 +60,14 @@ public ResponseEntity> isLoginIdA IsLoginIdAvailableResponse.from(isLoginIdAvailable))); } + @GetMapping("/check-phone-number") + public ResponseEntity> isPhoneNumberAvailable( + @PhoneNumberPattern @RequestParam String phoneNumber + ) { + Boolean isPhoneNumberAvailable = userService.isPhoneNumberAvailable(phoneNumber); + + return ResponseEntity.ok( + ApiResponseWrapper.success(HttpStatus.OK, "User PhoneNumber 등록 가능 여부 조회 성공", + IsPhoneNumberAvailableResponse.from(isPhoneNumberAvailable))); + } } diff --git a/src/main/java/life/mosu/mosuserver/presentation/user/UserControllerDocs.java b/src/main/java/life/mosu/mosuserver/presentation/user/UserControllerDocs.java index c766bb29..64fc6785 100644 --- a/src/main/java/life/mosu/mosuserver/presentation/user/UserControllerDocs.java +++ b/src/main/java/life/mosu/mosuserver/presentation/user/UserControllerDocs.java @@ -10,8 +10,8 @@ import life.mosu.mosuserver.global.annotation.LoginIdPattern; import life.mosu.mosuserver.global.annotation.UserId; import life.mosu.mosuserver.global.util.ApiResponseWrapper; -import life.mosu.mosuserver.presentation.user.dto.request.IsLoginIdAvailableResponse; import life.mosu.mosuserver.presentation.user.dto.response.CustomerKeyResponse; +import life.mosu.mosuserver.presentation.user.dto.response.IsLoginIdAvailableResponse; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestParam; diff --git a/src/main/java/life/mosu/mosuserver/presentation/user/dto/request/IsLoginIdAvailableResponse.java b/src/main/java/life/mosu/mosuserver/presentation/user/dto/response/IsLoginIdAvailableResponse.java similarity index 79% rename from src/main/java/life/mosu/mosuserver/presentation/user/dto/request/IsLoginIdAvailableResponse.java rename to src/main/java/life/mosu/mosuserver/presentation/user/dto/response/IsLoginIdAvailableResponse.java index 81854a7f..48a0aa70 100644 --- a/src/main/java/life/mosu/mosuserver/presentation/user/dto/request/IsLoginIdAvailableResponse.java +++ b/src/main/java/life/mosu/mosuserver/presentation/user/dto/response/IsLoginIdAvailableResponse.java @@ -1,4 +1,4 @@ -package life.mosu.mosuserver.presentation.user.dto.request; +package life.mosu.mosuserver.presentation.user.dto.response; public record IsLoginIdAvailableResponse( Boolean isLoginIdAvailable diff --git a/src/main/java/life/mosu/mosuserver/presentation/user/dto/response/IsPhoneNumberAvailableResponse.java b/src/main/java/life/mosu/mosuserver/presentation/user/dto/response/IsPhoneNumberAvailableResponse.java new file mode 100644 index 00000000..91a5ff05 --- /dev/null +++ b/src/main/java/life/mosu/mosuserver/presentation/user/dto/response/IsPhoneNumberAvailableResponse.java @@ -0,0 +1,10 @@ +package life.mosu.mosuserver.presentation.user.dto.response; + +public record IsPhoneNumberAvailableResponse( + Boolean isPhoneNumberAvailable +) { + + public static IsPhoneNumberAvailableResponse from(Boolean isPhoneNumberAvailable) { + return new IsPhoneNumberAvailableResponse(isPhoneNumberAvailable); + } +}