web/Bakery Shop Project

쇼핑몰 구현 13 - 주문 기능

su0a 2024. 2. 23. 21:53

Order

 

1. OrderRepository

@Repository
public interface OrderRepository extends JpaRepository<Order,Long> {

    //특정 회원의 주문을 최신순으로 조회
    @Query("select o from Order o "+
            "where o.member.email = :email "+
            "order by o.createdAt desc"
    )
    Page<Order> findAllByMemberEmail(String email, PageRequest pageRequest);

    //특정 회원의 주문을 가져올 때 배송지 정보도 페치조인으로 가져옴
    @Query("select o from Order o join fetch o.delivery d where o.member.email = :email")
    List<Order> findAllWithDelivery(@Param("email") String email);

    //특정 회원의 주문건 수 반환
    @Query("select count(o) from Order o "+
            "where o.member.email = :email")
    Long countOrder(@Param("email") String email);

}

 

2. OrderService

@Service
@RequiredArgsConstructor
public class OrderService {
    private final OrderRepository orderRepository;
    private final ItemRepository itemRepository;
    private final MemberRepository memberRepository;
    private final DeliveryService deliveryService;

    //상품 페이지에서 바로 주문할 때 사용
    @Transactional
    public Long order(OrderDto orderDto, String email){
        Item item = itemRepository.findById(orderDto.getItemId())
                .orElseThrow(EntityNotFoundException::new);
        Member member = memberRepository.findByEmail(email).get();
        List<OrderItem> orderItemList = new ArrayList<>();
        OrderItem orderItem = OrderItem.createOrderItem(item, orderDto.getCount());
        orderItemList.add(orderItem);
        Delivery delivery = member.getDelivery();
        Delivery orderDelivery = deliveryService.orderDelivery(delivery);
        Order order = Order.createOrder(member, orderItemList,orderDelivery);
        orderRepository.save(order);
        return order.getId();
    }

    //장바구니에 담긴 상품들을 주문할 때 사용
    @Transactional
    public Long cartOrder(List<OrderDto> orderDtoList, String email){
        Member member = memberRepository.findByEmail(email).get();
        List<OrderItem> orderItemList = new ArrayList<>();
        for(OrderDto orderDto:orderDtoList){
            Item item = itemRepository.findById(orderDto.getItemId())
                    .orElseThrow(EntityNotFoundException::new);
            OrderItem orderItem = OrderItem.createOrderItem(item, orderDto.getCount());
            orderItemList.add(orderItem);
        }
        Delivery delivery = member.getDelivery();
        Delivery orderDelivery = deliveryService.orderDelivery(delivery);
        Order order = Order.createOrder(member, orderItemList,orderDelivery);
        orderRepository.save(order);
        return order.getId();
    }

    //특정 회원의 주문 리스트 조회할 때 사용
    public Page<OrderHistDto> getOrderList(String email, PageRequest pageRequest){
        Page<Order> orders = orderRepository.findAllByMemberEmail(email, pageRequest);
        Long totalCount = orderRepository.countOrder(email);

        List<OrderHistDto> orderHistDtos = new ArrayList<>();

        for(Order order: orders){
            OrderHistDto orderHistDto = new OrderHistDto(order);
            //System.out.println(order.getId());
            orderHistDtos.add(orderHistDto);
        }
        return new PageImpl<>(orderHistDtos,pageRequest,totalCount);
    }

    //모든 주문 리스트 조회할 때 사용 - 관리자가 모든 주문 확인하기 위해
    public Page<OrderHistDto> getAllOrderList(PageRequest pageRequest){
        Page<Order> allOrders = orderRepository.findAll(pageRequest);
        long totalCount = orderRepository.count();
        List<OrderHistDto> orderHistDtos = new ArrayList<>();
        for(Order order:allOrders){
            OrderHistDto orderHistDto = new OrderHistDto(order);
            orderHistDtos.add(orderHistDto);
        }
        return new PageImpl<>(orderHistDtos,pageRequest,totalCount);
    }

    //주문 상세 정보 출력하기 위해 사용
    public List<OrderItemDto> getOrderDetail(String email, Long orderId){
        Order order = orderRepository.findById(orderId).orElseThrow(EntityNotFoundException::new);
        List<OrderItemDto> orderItemDtoList=new ArrayList<>();
        List<OrderItem> orderItems = order.getOrderItems();
        for(OrderItem orderItem:orderItems){
            UploadImage uploadImage = orderItem.getItem().getUploadImages().get(0);
            OrderItemDto orderItemDto = new OrderItemDto(orderItem, uploadImage);
            orderItemDtoList.add(orderItemDto);
        }
        return orderItemDtoList;
    }

    //주문 날짜 반환
    public LocalDateTime getOrderDate(Long orderId){
        Order order = orderRepository.findById(orderId).get();
        return order.getCreatedAt();
    }

    //주문 취소
    @Transactional
    public boolean cancelOrder(Long orderId){
        Order order = orderRepository.findById(orderId).orElseThrow(EntityNotFoundException::new);
        if(order.cancel()){
            return true;
        }
        else{
            return false;
        }
    }

    //주문 상태 변경
    @Transactional
    public void changeDeliveryStatus(Long orderId){
        Order order = orderRepository.findById(orderId).orElseThrow(EntityNotFoundException::new);
        order.changeDeliveryStatus();
    }

    //총 주문금액 반환
    public int getOrderTotalPrice(List<OrderItemDto> orderItemDtoList) {
        int totalPrice=0;
        for(OrderItemDto orderItemDto:orderItemDtoList){
            totalPrice+=orderItemDto.getTotalPrice();
        }
        return totalPrice;
    }
}

 

3. OrderController

@Controller
@RequiredArgsConstructor
@RequestMapping("/orders")
public class OrderController {
    private final OrderService orderService;
    private final CartService cartService;
    @PostMapping("/create")
    public String immediateOrder(@RequestParam("itemId") Long itemId,
                                 @RequestParam("count") int count,
                                 Model model, Authentication auth){

        OrderDto orderDto = new OrderDto(itemId, count);
        orderService.order(orderDto, auth.getName());

        model.addAttribute("message","성공적으로 주문이 완료되었습니다.");
        model.addAttribute("nextUrl","/items/"+itemId+"/detail");
        return "printMessage";
    }

    @PostMapping("/{orderId}/cancel")
    public String deleteOrder(@PathVariable Long orderId,Authentication auth,Model model){
        boolean checkDelete = orderService.cancelOrder(orderId);
        if(checkDelete){
            model.addAttribute("message","주문이 취소되었습니다.");
        }
        else{
            model.addAttribute("message","배송이 시작되어 주문을 취소할 수 없습니다.");
        }
        model.addAttribute("nextUrl","/members/myPage/order");
        return "printMessage";
    }

    //배송 시작 버튼 클릭 시 
    @PostMapping("/{orderId}/deliveryStart")
    public String deliveryStart(@PathVariable Long orderId, Model model){
        orderService.changeDeliveryStatus(orderId);
        model.addAttribute("message","배송상태가 변경되었습니다.");
        model.addAttribute("nextUrl","/admins/orders");
        return "printMessage";
    }

    //주문 id 클릭 시 상세정보 출력하는데 사용
    @GetMapping("/{orderId}/detail")
    public String detailOrder(@PathVariable Long orderId, Authentication auth, Model model){
        List<OrderItemDto> orderItemDtoList = orderService.getOrderDetail(auth.getName(), orderId);
        int orderTotalPrice=orderService.getOrderTotalPrice(orderItemDtoList);
        LocalDateTime orderDate = orderService.getOrderDate(orderId);
        model.addAttribute("orderItemDtoList",orderItemDtoList);
        model.addAttribute("orderTotalPrice",orderTotalPrice);
        model.addAttribute("orderDate",orderDate);
        return "orders/detail";
    }

    //장바구니에서 주문하기 버튼 누를 때
    @PostMapping("/createByCart")
    public String createOrderByCart(@RequestParam("selectedCartIds") List<Long> selectedCartIds,
                                    Authentication auth,Model model){
        if(selectedCartIds==null){
            model.addAttribute("message","선택된 상품이 없습니다.");
            model.addAttribute("nextUrl","/members/myPage/cart");
        }
        else {
            List<OrderDto> orderDtoList=cartService.changeCartToOrderDto(selectedCartIds);
            orderService.cartOrder(orderDtoList, auth.getName());

            model.addAttribute("message", "성공적으로 주문이 완료되었습니다.");
            model.addAttribute("nextUrl", "/members/myPage/order");
        }
        return "printMessage";
    }

}

 

4. OrderHistDto

  • 모든 주문내역 조회할 때 사용
@Data
public class OrderHistDto {
    private Long orderId;
    private LocalDateTime orderDate;
    private OrderStatus orderStatus;
    private DeliveryStatus deliveryStatus;

    public OrderHistDto(Order order){
        this.orderId=order.getId();
        this.orderDate=order.getCreatedAt();
        this.deliveryStatus=order.getDeliveryStatus();
        orderStatus=order.getOrderStatus();
    }
}

 

OrderItem

 

1. OrderItemRepository

@Repository
public interface OrderItemRepository extends JpaRepository<OrderItem,Long> {
    //해당 상품 id를 가진 OrderItem이 있는지 확인하기 위해
    Boolean existsByItemId(Long itemId);
}

 

2. OrderItemDto

@Data
public class OrderItemDto {
    private String itemName;
    private int count;
    private int orderPrice;
    private UploadImage uploadImage;
    private int totalPrice;

    public OrderItemDto(OrderItem orderItem, UploadImage uploadImage){
        this.itemName=orderItem.getItem().getName();
        this.count=orderItem.getCount();
        this.orderPrice=orderItem.getOrderPrice();
        this.uploadImage=uploadImage;
        this.totalPrice=orderItem.getTotalPrice();
    }

}