장바구니 상품 주문하기

jihan kong·2023년 4월 18일
0
post-thumbnail
post-custom-banner

장바구니 목록 중 체크박스가 선택된 상품을 주문하는 기능

장바구니의 기능을 거의 구현한 상태이다. 이제 장바구니에서 바로 주문을 할 수 있게끔 하는 기능을 만들어보았다. 장바구니에서 주문을 하게 되면 기존에 상품 페이지에서 주문을 하는 것과 다른 점은 여러 개의 상품을 하나의 주문에 담을 수 있는 장점이 있다.

먼저 장바구니 페이지에서 주문할 상품 데이터를 전달할 DTO를 생성했다.

1. CartOrderDto 생성

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;
}
  • 장바구니에서 여러 개의 상품을 주문하므로 CartOrderDto 클래스가 자기 자신을 List로 가지고 있도록 만들었다.

2. OrderService에 로직 추가

장바구니에서 주문할 상품 데이터를 전달 받아 주문을 생성하는 로직을 추가하였다.

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

3. CartService에 로직 추가

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

}
  1. 장바구니 페이지에서 전달 받은 주문 상품 번호를 이용해서 주문 로직으로 전달할 orderDto 객체를 만든다.
  2. 장바구니에 담은 상품을 주문하도록 주문 로직을 호출한다.
  3. for문을 돌면서 주문한 상품들을 장바구니에서 제거한다.

4. CartController에 로직 추가

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);
    }
}
  • 주문할 상품을 선택했는지 체크하고, 주문 권한을 체크한다.
  • 주문 로직 호출 결과 생성된 주문 번호를 반환 받는다. 생성된 주문 번호와 요청이 성공했다는 HTTP 응답 상태 코드를 반환 받는다.

5. 동작 화면 🕹️

기존에 만들어두었던 상품의 장바구니 담기 버튼을 클릭해 장바구니에 담는다.

그런 다음, 메뉴 바의 장바구니 목록을 클릭하면 다음과 같이 장바구니 리스트가 만들어지게 된다.

전체 선택을 누르거나 체크박스에 체크해서 주문하기 버튼을 누르면 다음과 같이 주문이 완료되었다는 알람이 뜨게된다.

구매 이력 페이지에 가보면 다음과 같이 주문한 리스트를 볼 수 있다.


1차 목표 COMPLETE 🎉

드디어 장바구니까지 구현함으로써 1차적으로 처음 구현하고 싶었던 기능들은 다 구현했다. 물론 책과 여러 관련 Document들의 도움을 많이 받았지만 스프링 부트와 JPA로 쇼핑몰 프로젝트를 만들었다는 자체가 상당히 뿌듯했다. Back 뿐만 아니라, 게시물로 포스팅하지는 않았지만 Thymeleaf 를 사용해서 프론트를 구성하는 것도 꽤 어려운 일이었다. 그러나, 아직 하고 싶은 기능들이 많다. 차차 생각해보고 하나씩 프로젝트에 도입해볼 계획이다. 일단은 여기까지 오느라 수고한 내 자신에게 박수를 보내고 싶다. 👍

profile
학습하며 도전하는 것을 즐기는 개발자
post-custom-banner

0개의 댓글