장바구니 목록 중 체크박스가 선택된 상품을 주문하는 기능
장바구니의 기능을 거의 구현한 상태이다. 이제 장바구니에서 바로 주문을 할 수 있게끔 하는 기능을 만들어보았다. 장바구니에서 주문을 하게 되면 기존에 상품 페이지에서 주문을 하는 것과 다른 점은 여러 개의 상품을 하나의 주문에 담을 수 있는 장점이 있다.
먼저 장바구니 페이지에서 주문할 상품 데이터를 전달할 DTO를 생성했다.
CartOrderDto.java
package com.shop.dto;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class CartOrderDto {
private Long cartItemId;
private List<CartOrderDto> cartOrderDtoList;
}
장바구니에서 주문할 상품 데이터를 전달 받아 주문을 생성하는 로직을 추가하였다.
OrderService.java
package com.shop.service;
// ..기존 import 생략
@Service
@Transactional
@RequiredArgsConstructor
public class OrderService {
// ..코드 생략
public Long orders(List<OrderDto> orderDtoList, String email){
Member member = memberRepository.findByEmail(email);
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);
}
Order order = Order.createOrder(member, orderItemList);
orderRepository.save(order);
return order.getId();
}
}
CartService
클래스에서는 주문 로직으로 전달할 orderDto 리스트 생성과 주문 로직 호출, 주문한 상품은 장바구니에서 제거하는 로직을 구현한다.
CartService.java
package com.shop.service;
// ...기존 import 생략
import com.shop.dto.CartOrderDto;
import com.shop.dto.OrderDto;
@Service
@RequiredArgsConstructor
@Transactional
public class CartService {
private final ItemRepository itemRepository;
private final MemberRepository memberRepository;
private final CartRepository cartRepository;
private final CartItemRepository cartItemRepository;
private final OrderService orderService;
// 코드 생략
public Long orderCartItem(List<CartOrderDto> cartOrderDtoList, String email){
List<OrderDto> orderDtoList = new ArrayList<>();
for (CartOrderDto cartOrderDto : cartOrderDtoList) {
// --- 1.
CartItem cartItem = cartItemRepository
.findById(cartOrderDto.getCartItemId())
.orElseThrow(EntityNotFoundException::new);
OrderDto orderDto = new OrderDto();
orderDto.setItemId(cartItem.getItem().getId());
orderDto.setCount(cartItem.getCount());
orderDtoList.add(orderDto);
}
Long orderId = orderService.orders(orderDtoList, email);
// --- 2.
for (CartOrderDto cartOrderDto : cartOrderDtoList) {
// --- 3.
CartItem cartItem = cartItemRepository
.findById(cartOrderDto.getCartItemId())
.orElseThrow(EntityNotFoundException::new);
cartItemRepository.delete(cartItem);
}
return orderId;
}
}
CartController
클래스에 장바구니 상품의 수량을 업데이트하는 요청을 처리할 수 있도록 로직을 추가한다.
CartController.java
package com.shop.controller;
//..기존 import 생략
import com.shop.dto.CartOrderDto;
@Controller
@RequiredArgsConstructor
public class CartController {
// ...코드 생략
@PostMapping(value = "/cart/orders")
public @ResponseBody ResponseEntity orderCartItem(@RequestBody CartOrderDto cartOrderDto, Principal principal){
List<CartOrderDto> cartOrderDtoList = cartOrderDto.getCartOrderDtoList();
if(cartOrderDtoList == null || cartOrderDtoList.size() == 0){
return new ResponseEntity<String>("주문할 상품을 선택해주세요", HttpStatus.FORBIDDEN);
}
for (CartOrderDto cartOrder : cartOrderDtoList) {
if(!cartService.validateCartItem(cartOrder.getCartItemId(), principal.getName())){
return new ResponseEntity<String>("주문 권한이 없습니다.", HttpStatus.FORBIDDEN);
}
}
Long orderId = cartService.orderCartItem(cartOrderDtoList, principal.getName());
return new ResponseEntity<Long>(orderId, HttpStatus.OK);
}
}
기존에 만들어두었던 상품의 장바구니 담기 버튼을 클릭해 장바구니에 담는다.
그런 다음, 메뉴 바의 장바구니 목록을 클릭하면 다음과 같이 장바구니 리스트가 만들어지게 된다.
전체 선택을 누르거나 체크박스에 체크해서 주문하기 버튼을 누르면 다음과 같이 주문이 완료되었다는 알람이 뜨게된다.
구매 이력 페이지에 가보면 다음과 같이 주문한 리스트를 볼 수 있다.
드디어 장바구니까지 구현함으로써 1차적으로 처음 구현하고 싶었던 기능들은 다 구현했다. 물론 책과 여러 관련 Document들의 도움을 많이 받았지만 스프링 부트와 JPA로 쇼핑몰 프로젝트를 만들었다는 자체가 상당히 뿌듯했다. Back 뿐만 아니라, 게시물로 포스팅하지는 않았지만 Thymeleaf 를 사용해서 프론트를 구성하는 것도 꽤 어려운 일이었다. 그러나, 아직 하고 싶은 기능들이 많다. 차차 생각해보고 하나씩 프로젝트에 도입해볼 계획이다. 일단은 여기까지 오느라 수고한 내 자신에게 박수를 보내고 싶다. 👍