1차적으로 주문과 사용자의 유효성 검증이 필요합니다. 등록한 주문과 동일한 사용자인지 확인하고 맞지 않다면 에러를 담아서 반환해줍니다.
@PostMapping("/order/{orderId}/cancel")
public @ResponseBody ResponseEntity cancelOrder(@PathVariable("orderId")Long orderId, Principal principal){
if(!orderService.validateOrder(orderId, principal.getName())){
return new ResponseEntity<String>("주문 취소 권한이 없습니다.", HttpStatus.FORBIDDEN);
}
orderService.cancelOrder(orderId);
return new ResponseEntity<Long>(orderId, HttpStatus.OK);
}
단순 검증을 위한 DB 조회이기 때문에 readOnly=true로 진행합니다.
orderId와 email을 활용해서 각각의 member를 가져옵니다.
유일성을 가진 정보가 각각의 email이기 때문에 email을 통해 비교합니다.
@Transactional(readOnly = true)
public boolean validateOrder(Long orderId, String email){
Member curMember = memberRepository.findByEmail(email);
Order order = orderRepository.findById(orderId).orElseThrow(EntityNotFoundException::new);
Member saveMember = order.getMember();
if(!StringUtils.equals(curMember.getEmail(), saveMember.getEmail())){
return false;
}
return true;
}
직접적인 삭제는 Order 내부에 위임하고 Order에는 삭제를 요청합니다.
더티체킹이 있기 때문에 캔슬 후에 Order를 따로 저장하지 않습니다.
public void cancelOrder(Long orderId){
Order order = orderRepository.findById(orderId).orElseThrow(EntityNotFoundException::new);
order.cancelOrder();
}
상태를 취소로 바꾸고 각 OrderItem들에게 취소 요청을 합니다.
public void cancelOrder(){
this.orderStatus = OrderStatus.CANCEL;
for(OrderItem orderItem : orderItems){
orderItem.cancel();
}
}
OrderItem은 Order와 Item의 연결점이 되어 Order는 위에서 취소했으니 Item에게 재고 증가를 요청합니다.
public void cancel(){
this.getItem().addStock(count);
}
public void addStock(int stockNumber){
this.stockNumber += stockNumber;
}