diff --git a/DuDoong-Api/src/main/java/band/gosrock/api/order/controller/OrderAdminController.java b/DuDoong-Api/src/main/java/band/gosrock/api/order/controller/OrderAdminController.java index 5aa59054..d083df50 100644 --- a/DuDoong-Api/src/main/java/band/gosrock/api/order/controller/OrderAdminController.java +++ b/DuDoong-Api/src/main/java/band/gosrock/api/order/controller/OrderAdminController.java @@ -10,6 +10,7 @@ import band.gosrock.api.order.service.ApproveOrderUseCase; import band.gosrock.api.order.service.CancelOrderUseCase; import band.gosrock.api.order.service.ReadOrderUseCase; +import band.gosrock.api.order.service.RefuseOrderUseCase; import band.gosrock.common.annotation.ApiErrorExceptionsExample; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; @@ -35,6 +36,8 @@ public class OrderAdminController { private final ReadOrderUseCase readOrderUseCase; private final CancelOrderUseCase cancelOrderUseCase; + private final RefuseOrderUseCase refuseOrderUseCase; + @Operation(summary = "어드민 목록 내 테이블 조회 OrderStage 는 꼭 보내주삼!") @GetMapping public PageResponse getEventOrders( @@ -52,7 +55,7 @@ public OrderResponse cancelOrder( return cancelOrderUseCase.execute(eventId, orderUuid); } - @Operation(summary = "주문 승인하기 . 호스트 관리자가 티켓 주문을 승인합니다. ( 어드민 이벤트쪽으로 이동예정 )") + @Operation(summary = "주문 승인하기 . 호스트 관리자가 티켓 주문을 승인합니다.") @ApiErrorExceptionsExample(ApproveOrderExceptionDocs.class) @PostMapping("/{order_uuid}/approve") public OrderResponse confirmOrder( @@ -60,6 +63,13 @@ public OrderResponse confirmOrder( return approveOrderUseCase.execute(eventId, orderUuid); } + @Operation(summary = "승인 주문 거절하기 . 호스트 관리자가 승인 대기중인 주문을 거절합니다.") + @PostMapping("/{order_uuid}/refuse") + public OrderResponse refuseOrder( + @PathVariable Long eventId, @PathVariable("order_uuid") String orderUuid) { + return refuseOrderUseCase.execute(eventId, orderUuid); + } + @Operation(summary = "주문관리 리스트 페이지에서 주문 상세정보 조회할때") @GetMapping("/{order_uuid}") public OrderResponse getEventOrderDetail( diff --git a/DuDoong-Api/src/main/java/band/gosrock/api/order/service/RefuseOrderUseCase.java b/DuDoong-Api/src/main/java/band/gosrock/api/order/service/RefuseOrderUseCase.java new file mode 100644 index 00000000..ffede5e4 --- /dev/null +++ b/DuDoong-Api/src/main/java/band/gosrock/api/order/service/RefuseOrderUseCase.java @@ -0,0 +1,26 @@ +package band.gosrock.api.order.service; + +import static band.gosrock.api.common.aop.hostRole.FindHostFrom.EVENT_ID; +import static band.gosrock.api.common.aop.hostRole.HostQualification.MANAGER; + +import band.gosrock.api.common.aop.hostRole.HostRolesAllowed; +import band.gosrock.api.order.model.dto.response.OrderResponse; +import band.gosrock.api.order.model.mapper.OrderMapper; +import band.gosrock.common.annotation.UseCase; +import band.gosrock.domain.domains.order.service.WithdrawOrderService; +import lombok.RequiredArgsConstructor; + +@UseCase +@RequiredArgsConstructor +public class RefuseOrderUseCase { + + private final WithdrawOrderService withdrawOrderService; + + private final OrderMapper orderMapper; + + @HostRolesAllowed(role = MANAGER, findHostFrom = EVENT_ID, applyTransaction = false) + public OrderResponse execute(Long eventId, String orderUuid) { + withdrawOrderService.refuseOrder(orderUuid); + return orderMapper.toOrderResponse(orderUuid); + } +} diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/domain/Order.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/domain/Order.java index 3604e3c0..dfa6e18a 100644 --- a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/domain/Order.java +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/domain/Order.java @@ -239,6 +239,14 @@ public void cancel(OrderValidator orderValidator) { Events.raise(WithDrawOrderEvent.from(this)); } + /** 관리자가 승인 대기 중인 주문을 거절합니다. */ + public void refuse(OrderValidator orderValidator) { + orderValidator.validCanRefuse(this); + this.orderStatus = OrderStatus.CANCELED; + this.withDrawAt = LocalDateTime.now(); + Events.raise(WithDrawOrderEvent.from(this)); + } + /** 사용자가 주문을 환불 시킵니다. */ public void refund(Long currentUserId, OrderValidator orderValidator) { orderValidator.validOwner(this, currentUserId); diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/domain/validator/OrderValidator.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/domain/validator/OrderValidator.java index 3bb54f8e..25b62c37 100644 --- a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/domain/validator/OrderValidator.java +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/domain/validator/OrderValidator.java @@ -121,6 +121,13 @@ public void validCanCancel(Order order) { validCanWithDraw(order); } + /** 거절할 수 있는 승인 대기중인 주문인지 검증합니다. */ + public void validCanRefuse(Order order) { + validAvailableRefundDate(order); + validStatusCanRefuse(getOrderStatus(order)); + validCanWithDraw(order); + } + /** 환불 할 수 있는 주문인지 검증합니다. */ public void validCanRefund(Order order) { validAvailableRefundDate(order); @@ -280,6 +287,11 @@ public Boolean isStatusCanWithDraw(OrderStatus orderStatus) { || Objects.equals(orderStatus, OrderStatus.APPROVED); } + /** 주문상태가 철회가능한 상태인지를 반환합니다. */ + public Boolean isStatusCanRefuse(OrderStatus orderStatus) { + return Objects.equals(orderStatus, OrderStatus.PENDING_APPROVE); + } + /** 주문 상태가 취소가능한 상태인지 검증합니다. */ public void validStatusCanCancel(OrderStatus orderStatus) { if (!isStatusCanWithDraw(orderStatus)) { @@ -293,6 +305,12 @@ public void validStatusCanRefund(OrderStatus orderStatus) { throw CanNotRefundOrderException.EXCEPTION; } } + /** 주문 상태가 관리자 취소가능한 상태인지 검증합니다. */ + public void validStatusCanRefuse(OrderStatus orderStatus) { + if (!isStatusCanRefuse(orderStatus)) { + throw CanNotCancelOrderException.EXCEPTION; + } + } /** 주문 상태가 결제방식의 승인 가능한 상태인지 검증합니다. */ public void validStatusCanPaymentConfirm(OrderStatus orderStatus) { diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/exception/CanNotRefuseOrderException.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/exception/CanNotRefuseOrderException.java new file mode 100644 index 00000000..2c1cd43e --- /dev/null +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/exception/CanNotRefuseOrderException.java @@ -0,0 +1,13 @@ +package band.gosrock.domain.domains.order.exception; + + +import band.gosrock.common.exception.DuDoongCodeException; + +public class CanNotRefuseOrderException extends DuDoongCodeException { + + public static final DuDoongCodeException EXCEPTION = new CanNotRefuseOrderException(); + + private CanNotRefuseOrderException() { + super(OrderErrorCode.ORDER_CANNOT_REFUSE); + } +} diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/exception/OrderErrorCode.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/exception/OrderErrorCode.java index e0cff47d..6880d9cc 100644 --- a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/exception/OrderErrorCode.java +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/exception/OrderErrorCode.java @@ -39,7 +39,8 @@ public enum OrderErrorCode implements BaseErrorCode { APPROVE_WAITING_PURCHASE_LIMIT( BAD_REQUEST, "Order_400_15", - "승인 대기중인 주문으로 인해 티켓 최대 구매 가능 횟수를 넘겼습니다." + "이미 신청한 주문이 승인 될 때까지 기다려주세요."); + "승인 대기중인 주문으로 인해 티켓 최대 구매 가능 횟수를 넘겼습니다." + "이미 신청한 주문이 승인 될 때까지 기다려주세요."), + ORDER_CANNOT_REFUSE(BAD_REQUEST, "Order_400_16", "승인 대기중인 주문을 거절할 수 없는 상태입니다."); private Integer status; private String code; diff --git a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/service/WithdrawOrderService.java b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/service/WithdrawOrderService.java index c7aac782..44994cd8 100644 --- a/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/service/WithdrawOrderService.java +++ b/DuDoong-Domain/src/main/java/band/gosrock/domain/domains/order/service/WithdrawOrderService.java @@ -33,4 +33,11 @@ public String refundOrder(String orderUuid, Long userId) { order.refund(userId, orderValidator); return orderUuid; } + + @RedissonLock(LockName = "주문", identifier = "orderUuid") + public String refuseOrder(String orderUuid) { + Order order = orderAdaptor.findByOrderUuid(orderUuid); + order.refuse(orderValidator); + return orderUuid; + } }