generated from pricelees/issue-pr-template
[#34] 회원 / 인증 도메인 재정의 #43
@ -7,9 +7,10 @@ import org.springframework.data.repository.findByIdOrNull
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import roomescape.common.config.next
|
||||
import roomescape.member.business.MemberService
|
||||
import roomescape.member.infrastructure.persistence.Role
|
||||
import roomescape.member.web.MemberSummaryRetrieveResponse
|
||||
import roomescape.common.dto.CurrentUserContext
|
||||
import roomescape.common.dto.PrincipalType
|
||||
import roomescape.member.business.UserService
|
||||
import roomescape.member.web.UserContactRetrieveResponse
|
||||
import roomescape.payment.business.PaymentService
|
||||
import roomescape.payment.web.PaymentRetrieveResponse
|
||||
import roomescape.reservation.exception.ReservationErrorCode
|
||||
@ -31,7 +32,7 @@ class ReservationService(
|
||||
private val reservationRepository: ReservationRepository,
|
||||
private val reservationValidator: ReservationValidator,
|
||||
private val scheduleService: ScheduleService,
|
||||
private val memberService: MemberService,
|
||||
private val userService: UserService,
|
||||
private val themeService: ThemeService,
|
||||
private val canceledReservationRepository: CanceledReservationRepository,
|
||||
private val tsidFactory: TsidFactory,
|
||||
@ -40,14 +41,14 @@ class ReservationService(
|
||||
|
||||
@Transactional
|
||||
fun createPendingReservation(
|
||||
memberId: Long,
|
||||
user: CurrentUserContext,
|
||||
request: PendingReservationCreateRequest
|
||||
): PendingReservationCreateResponse {
|
||||
log.info { "[ReservationService.createPendingReservation] Pending 예약 생성 시작: schedule=${request.scheduleId}" }
|
||||
|
||||
validateCanCreate(request)
|
||||
|
||||
val reservation: ReservationEntity = request.toEntity(id = tsidFactory.next(), memberId = memberId)
|
||||
val reservation: ReservationEntity = request.toEntity(id = tsidFactory.next(), userId = user.id)
|
||||
|
||||
return PendingReservationCreateResponse(reservationRepository.save(reservation).id)
|
||||
.also { "[ReservationService.createPendingReservation] Pending 예약 생성 완료: reservationId=${it}, schedule=${request.scheduleId}" }
|
||||
@ -70,18 +71,17 @@ class ReservationService(
|
||||
}
|
||||
|
||||
@Transactional
|
||||
fun cancelReservation(memberId: Long, reservationId: Long, request: ReservationCancelRequest) {
|
||||
log.info { "[ReservationService.cancelReservation] 예약 취소 시작: memberId=${memberId}, reservationId=${reservationId}" }
|
||||
fun cancelReservation(user: CurrentUserContext, reservationId: Long, request: ReservationCancelRequest) {
|
||||
log.info { "[ReservationService.cancelReservation] 예약 취소 시작: userId=${user.id}, reservationId=${reservationId}" }
|
||||
|
||||
val reservation: ReservationEntity = findOrThrow(reservationId)
|
||||
val member: MemberSummaryRetrieveResponse = memberService.findSummaryById(memberId)
|
||||
|
||||
run {
|
||||
scheduleService.updateSchedule(
|
||||
reservation.scheduleId,
|
||||
ScheduleUpdateRequest(status = ScheduleStatus.AVAILABLE)
|
||||
)
|
||||
saveCanceledReservation(member, reservation, request.cancelReason)
|
||||
saveCanceledReservation(user, reservation, request.cancelReason)
|
||||
reservation.cancel()
|
||||
}.also {
|
||||
log.info { "[ReservationService.cancelReservation] 예약 취소 완료: reservationId=${reservationId}" }
|
||||
@ -89,10 +89,10 @@ class ReservationService(
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
fun findSummaryByMemberId(memberId: Long): ReservationSummaryRetrieveListResponse {
|
||||
log.info { "[ReservationService.findSummaryByMemberId] 예약 조회 시작: memberId=${memberId}" }
|
||||
fun findUserSummaryReservation(user: CurrentUserContext): ReservationSummaryRetrieveListResponse {
|
||||
log.info { "[ReservationService.findSummaryByMemberId] 예약 조회 시작: userId=${user.id}" }
|
||||
|
||||
val reservations: List<ReservationEntity> = reservationRepository.findAllByMemberId(memberId)
|
||||
val reservations: List<ReservationEntity> = reservationRepository.findAllByUserId(user.id)
|
||||
|
||||
return ReservationSummaryRetrieveListResponse(reservations.map {
|
||||
val schedule: ScheduleSummaryResponse = scheduleService.findSummaryById(it.scheduleId)
|
||||
@ -106,7 +106,7 @@ class ReservationService(
|
||||
status = it.status
|
||||
)
|
||||
}).also {
|
||||
log.info { "[ReservationService.findSummaryByMemberId] ${it.reservations.size}개의 예약 조회 완료: memberId=${memberId}" }
|
||||
log.info { "[ReservationService.findSummaryByMemberId] ${it.reservations.size}개의 예약 조회 완료: userId=${user.id}" }
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,11 +115,11 @@ class ReservationService(
|
||||
log.info { "[ReservationService.findDetailById] 예약 상세 조회 시작: reservationId=${id}" }
|
||||
|
||||
val reservation: ReservationEntity = findOrThrow(id)
|
||||
val member: MemberSummaryRetrieveResponse = memberService.findSummaryById(reservation.memberId)
|
||||
val user: UserContactRetrieveResponse = userService.findContactById(reservation.userId)
|
||||
val paymentDetail: PaymentRetrieveResponse = paymentService.findDetailByReservationId(id)
|
||||
|
||||
return reservation.toReservationDetailRetrieveResponse(
|
||||
member = member,
|
||||
user = user,
|
||||
payment = paymentDetail
|
||||
).also {
|
||||
log.info { "[ReservationService.findDetailById] 예약 상세 조회 완료: reservationId=${id}" }
|
||||
@ -138,19 +138,19 @@ class ReservationService(
|
||||
}
|
||||
|
||||
private fun saveCanceledReservation(
|
||||
member: MemberSummaryRetrieveResponse,
|
||||
user: CurrentUserContext,
|
||||
reservation: ReservationEntity,
|
||||
cancelReason: String
|
||||
) {
|
||||
if (member.role != Role.ADMIN && reservation.memberId != member.id) {
|
||||
log.warn { "[ReservationService.createCanceledPayment] 예약자 본인 또는 관리자가 아닌 회원의 취소 요청: reservationId=${reservation.id}, memberId=${member.id}" }
|
||||
if (user.type != PrincipalType.ADMIN && reservation.userId != user.id) {
|
||||
log.warn { "[ReservationService.createCanceledPayment] 예약자 본인 또는 관리자가 아닌 회원의 취소 요청: reservationId=${reservation.id}, userId=${user.id}" }
|
||||
throw ReservationException(ReservationErrorCode.NO_PERMISSION_TO_CANCEL_RESERVATION)
|
||||
}
|
||||
|
||||
CanceledReservationEntity(
|
||||
id = tsidFactory.next(),
|
||||
reservationId = reservation.id,
|
||||
canceledBy = member.id,
|
||||
canceledBy = user.id,
|
||||
cancelReason = cancelReason,
|
||||
canceledAt = LocalDateTime.now(),
|
||||
status = CanceledReservationStatus.PROCESSING
|
||||
|
||||
@ -1,16 +1,14 @@
|
||||
package roomescape.reservation.docs
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import io.swagger.v3.oas.annotations.Parameter
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponses
|
||||
import jakarta.validation.Valid
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.web.bind.annotation.PathVariable
|
||||
import org.springframework.web.bind.annotation.RequestBody
|
||||
import roomescape.auth.web.support.Authenticated
|
||||
import roomescape.auth.web.support.CurrentUser
|
||||
import roomescape.auth.web.support.LoginRequired
|
||||
import roomescape.auth.web.support.MemberId
|
||||
import roomescape.auth.web.support.UserOnly
|
||||
import roomescape.common.dto.CurrentUserContext
|
||||
import roomescape.common.dto.response.CommonApiResponse
|
||||
@ -18,6 +16,7 @@ import roomescape.reservation.web.*
|
||||
|
||||
interface ReservationAPI {
|
||||
|
||||
@UserOnly
|
||||
@Operation(summary = "결제 대기 예약 저장", tags = ["로그인이 필요한 API"])
|
||||
@ApiResponses(ApiResponse(responseCode = "200", description = "성공", useReturnTypeSchema = true))
|
||||
fun createPendingReservation(
|
||||
@ -32,7 +31,7 @@ interface ReservationAPI {
|
||||
@PathVariable("id") id: Long
|
||||
): ResponseEntity<CommonApiResponse<Unit>>
|
||||
|
||||
@UserOnly
|
||||
@Authenticated
|
||||
@Operation(summary = "예약 취소", tags = ["로그인이 필요한 API"])
|
||||
@ApiResponses(ApiResponse(responseCode = "200", description = "성공", useReturnTypeSchema = true))
|
||||
fun cancelReservation(
|
||||
@ -41,6 +40,7 @@ interface ReservationAPI {
|
||||
@Valid @RequestBody request: ReservationCancelRequest
|
||||
): ResponseEntity<CommonApiResponse<Unit>>
|
||||
|
||||
@UserOnly
|
||||
@Operation(summary = "회원별 예약 요약 목록 조회", tags = ["로그인이 필요한 API"])
|
||||
@ApiResponses(ApiResponse(responseCode = "200", description = "성공", useReturnTypeSchema = true))
|
||||
fun findSummaryByMemberId(
|
||||
|
||||
@ -19,7 +19,7 @@ class ReservationController(
|
||||
@CurrentUser user: CurrentUserContext,
|
||||
@Valid @RequestBody request: PendingReservationCreateRequest
|
||||
): ResponseEntity<CommonApiResponse<PendingReservationCreateResponse>> {
|
||||
val response = reservationService.createPendingReservation(user.id, request)
|
||||
val response = reservationService.createPendingReservation(user, request)
|
||||
|
||||
return ResponseEntity.ok(CommonApiResponse(response))
|
||||
}
|
||||
@ -39,7 +39,7 @@ class ReservationController(
|
||||
@PathVariable reservationId: Long,
|
||||
@Valid @RequestBody request: ReservationCancelRequest
|
||||
): ResponseEntity<CommonApiResponse<Unit>> {
|
||||
reservationService.cancelReservation(user.id, reservationId, request)
|
||||
reservationService.cancelReservation(user, reservationId, request)
|
||||
|
||||
return ResponseEntity.ok().body(CommonApiResponse())
|
||||
}
|
||||
@ -48,7 +48,7 @@ class ReservationController(
|
||||
override fun findSummaryByMemberId(
|
||||
@CurrentUser user: CurrentUserContext,
|
||||
): ResponseEntity<CommonApiResponse<ReservationSummaryRetrieveListResponse>> {
|
||||
val response = reservationService.findSummaryByMemberId(user.id)
|
||||
val response = reservationService.findUserSummaryReservation(user)
|
||||
|
||||
return ResponseEntity.ok(CommonApiResponse(response))
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package roomescape.reservation.web
|
||||
|
||||
import jakarta.validation.constraints.NotEmpty
|
||||
import roomescape.member.web.MemberSummaryRetrieveResponse
|
||||
import roomescape.member.web.UserContactRetrieveResponse
|
||||
import roomescape.payment.web.PaymentRetrieveResponse
|
||||
import roomescape.reservation.infrastructure.persistence.ReservationEntity
|
||||
import roomescape.reservation.infrastructure.persistence.ReservationStatus
|
||||
@ -48,18 +48,18 @@ data class ReservationSummaryRetrieveListResponse(
|
||||
|
||||
data class ReservationDetailRetrieveResponse(
|
||||
val id: Long,
|
||||
val member: MemberSummaryRetrieveResponse,
|
||||
val user: UserContactRetrieveResponse,
|
||||
val applicationDateTime: LocalDateTime,
|
||||
val payment: PaymentRetrieveResponse,
|
||||
)
|
||||
|
||||
fun ReservationEntity.toReservationDetailRetrieveResponse(
|
||||
member: MemberSummaryRetrieveResponse,
|
||||
user: UserContactRetrieveResponse,
|
||||
payment: PaymentRetrieveResponse,
|
||||
): ReservationDetailRetrieveResponse {
|
||||
return ReservationDetailRetrieveResponse(
|
||||
id = this.id,
|
||||
member = member,
|
||||
user = user,
|
||||
applicationDateTime = this.createdAt,
|
||||
payment = payment,
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user