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();
}
}