Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.nowait.applicationadmin.cancelOrder.dto;

import com.nowait.domainadminrdb.cancelOrder.entity.CancelReason;

public record CancelOrderRequest(CancelReason reason) { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.nowait.applicationadmin.cancelOrder.dto;

import java.time.Instant;

import com.nowait.domainadminrdb.cancelOrder.entity.CancelOrder;
import com.nowait.domainadminrdb.cancelOrder.entity.CancelReason;

import lombok.AllArgsConstructor;
import lombok.Builder;

@Builder
public class CancelOrderResponse {

private Long id;
private Long orderId;
private String orderSignature;
private CancelReason reason;
private Instant cancelAt;

public CancelOrder fromEntity() {
return CancelOrder.builder()
.id(id)
.orderId(orderId)
.orderSignature(orderSignature)
.reason(reason)
.cancelAt(cancelAt)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.nowait.applicationadmin.cancelOrder.listener;

import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;

import com.nowait.domainadminrdb.cancelOrder.entity.CancelOrder;
import com.nowait.domainadminrdb.cancelOrder.repository.CancelOrderRepository;
import com.nowait.nowaitevent.order.event.OrderCancelledEvent;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Component
@RequiredArgsConstructor
@Slf4j
public class OrderCancelledEventListener {

private final CancelOrderRepository cancelOrderRepository;

@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void on(OrderCancelledEvent event) {
try {
cancelOrderRepository.save(
CancelOrder.builder()
.orderId(event.getOrderId())
.storeId(event.getStoreId())
.orderSignature(event.getOrderSignature())
.reason(event.getReason())
.cancelAt(event.getCancelAt())
.build()
);
} catch (DataIntegrityViolationException e) {
log.debug("cancel_orders duplicate orderId={}, ignore", event.getOrderId());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.nowait.applicationadmin.cancelOrder.dto.CancelOrderRequest;
import com.nowait.applicationadmin.order.dto.OrderResponseDto;
import com.nowait.applicationadmin.order.dto.OrderStatusUpdateRequestDto;
import com.nowait.applicationadmin.order.dto.OrderStatusUpdateResponseDto;
Expand Down Expand Up @@ -63,4 +65,20 @@ public ResponseEntity<?> updateOrderStatus(
.status(HttpStatus.OK)
.body(ApiUtils.success(response));
}

@DeleteMapping("/{orderId}")
@Operation(summary = "주문 삭제", description = "특정 주문을 삭제")
@ApiResponse(responseCode = "200", description = "주문 삭제 성공")
public ResponseEntity<?> deleteOrder(
@PathVariable Long orderId,
@RequestBody CancelOrderRequest cancelOrderRequest,
@AuthenticationPrincipal MemberDetails memberDetails
) {

return ResponseEntity
.status(HttpStatus.OK)
.body(ApiUtils.success(
orderService.cancelOrder(orderId, cancelOrderRequest, memberDetails)
));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.nowait.applicationadmin.order.service;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
Expand All @@ -10,6 +11,7 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.nowait.applicationadmin.cancelOrder.dto.CancelOrderRequest;
import com.nowait.applicationadmin.order.dto.OrderResponseDto;
import com.nowait.applicationadmin.order.dto.OrderStatusUpdateResponseDto;
import com.nowait.common.enums.Role;
Expand All @@ -29,6 +31,7 @@
import com.nowait.domaincorerdb.user.exception.UserNotFoundException;
import com.nowait.domaincorerdb.user.repository.UserRepository;
import com.nowait.nowaitevent.order.event.CookingCompleteEvent;
import com.nowait.nowaitevent.order.event.OrderCancelledEvent;

import lombok.RequiredArgsConstructor;

Expand Down Expand Up @@ -87,6 +90,29 @@ public OrderStatusUpdateResponseDto updateOrderStatus(Long orderId, OrderStatus
return OrderStatusUpdateResponseDto.fromEntity(userOrder);
}

@Transactional
public OrderStatusUpdateResponseDto cancelOrder(Long orderId, CancelOrderRequest cancelOrderRequest, MemberDetails memberDetails) {
User user = userRepository.findById(memberDetails.getId()).orElseThrow(UserNotFoundException::new);
UserOrder userOrder = orderRepository.findById(orderId).orElseThrow(OrderNotFoundException::new);

if (!Role.SUPER_ADMIN.equals(user.getRole()) && !user.getStoreId().equals(userOrder.getStore().getStoreId())) {
throw new OrderUpdateUnauthorizedException();
}

userOrder.cancelOrder();

publisher.publishEvent(new OrderCancelledEvent(
userOrder.getId(),
userOrder.getStore().getStoreId(),
userOrder.getSignature(),
cancelOrderRequest.reason(),
Instant.now()
));


return OrderStatusUpdateResponseDto.fromEntity(userOrder);
}

@Transactional(readOnly = true)
public OrderSalesSumDetail getSaleSumByStoreId(MemberDetails memberDetails, LocalDate date) {
User user = userRepository.findById(memberDetails.getId()).orElseThrow(UserNotFoundException::new);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.nowait.domainadminrdb.cancelOrder.entity;

import java.time.Instant;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.PrePersist;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "cancel_orders")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder
public class CancelOrder {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(nullable = false)
private Long orderId;

@Column(name = "store_id", nullable = false)
private Long storeId;

@Column(nullable = false, length = 256)
private String orderSignature;

@Enumerated(EnumType.STRING)
@Column(nullable = false, length = 30)
private CancelReason reason;

@Column(nullable = false)
private Instant cancelAt;

@PrePersist
void prePersist() {
if (cancelAt == null) cancelAt = Instant.now();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.nowait.domainadminrdb.cancelOrder.entity;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
@Schema(description = "주문 상태 Enum")
public enum CancelReason {

@Schema(description = "단순 취소")
SIMPLE_CANCEL("단순 취소"),
@Schema(description = "메뉴 품절")
SOLD_OUT("메뉴 품절"),
@Schema(description = "기타")
ETC("기타");

private final String description;
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.nowait.domainadminrdb.cancelOrder.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.nowait.domainadminrdb.cancelOrder.entity.CancelOrder;

@Repository
public interface CancelOrderRepository extends JpaRepository<CancelOrder, Long> {
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ public enum OrderStatus {
COOKING("조리중"),

@Schema(description = "조리완료")
COOKED("조리완료");
COOKED("조리완료"),

@Schema(description = "주문취소")
CANCELLED("주문취소");

private final String description;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder
public class UserOrder extends BaseTimeEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Expand All @@ -49,6 +50,7 @@ public class UserOrder extends BaseTimeEntity {
private List<OrderItem> orderItems = new ArrayList<>();

private String sessionId;

@Column(length = 10) // 예약자 이름 길이 제한
private String depositorName;

Expand All @@ -63,4 +65,11 @@ public void updateStatus(OrderStatus newStatus) {
this.status = newStatus;
}

public void cancelOrder() {
if (this.status == OrderStatus.CANCELLED) {
return;
}
this.status = OrderStatus.CANCELLED;
}

}
1 change: 1 addition & 0 deletions nowait-event/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ repositories {
dependencies {
implementation project(':nowait-common')
implementation project(':nowait-domain:domain-core-rdb')
implementation project(':nowait-domain:domain-admin-rdb')

api 'org.springframework.boot:spring-boot-starter-data-jpa'
api 'jakarta.persistence:jakarta.persistence-api:3.1.0'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.nowait.nowaitevent.order.event;

import java.time.Instant;

import com.nowait.domainadminrdb.cancelOrder.entity.CancelReason;

import lombok.Value;

@Value
public class OrderCancelledEvent {
Long orderId;
Long storeId;
String orderSignature;
CancelReason reason;
Instant cancelAt;
}