Skip to content

Commit

Permalink
#18 - Feat: 주문 생성 기능 구현(장바구니에서 선택 방식 지원), Style: CartItem member->buy…
Browse files Browse the repository at this point in the history
…er 변수명 수정
  • Loading branch information
ahah525 committed Oct 25, 2022
1 parent 9c561f1 commit e635c62
Show file tree
Hide file tree
Showing 11 changed files with 278 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ public class CartController {
@PreAuthorize("isAuthenticated()")
@PostMapping("/add/{productId}")
public String addCartItem(@PathVariable long productId, @AuthenticationPrincipal MemberContext memberContext) {
Member member = memberContext.getMember();
Member buyer = memberContext.getMember();
Product product = productService.findById(productId);

cartService.addCartItem(member, product);
cartService.addCartItem(buyer, product);

return "redirect:/cart/list";
}
Expand All @@ -41,7 +41,7 @@ public String addCartItem(@PathVariable long productId, @AuthenticationPrincipal
@PreAuthorize("isAuthenticated()")
@GetMapping("/list")
public String list(@AuthenticationPrincipal MemberContext memberContext, Model model) {
List<CartItem> cartItems = cartService.findAllByMemberIdOrderByIdDesc(memberContext.getId());
List<CartItem> cartItems = cartService.findAllByBuyerIdOrderByIdDesc(memberContext.getId());

model.addAttribute("cartItems", cartItems);

Expand All @@ -52,10 +52,10 @@ public String list(@AuthenticationPrincipal MemberContext memberContext, Model m
@PreAuthorize("isAuthenticated()")
@PostMapping("/delete/{productId}")
public String deleteCartItem(@PathVariable long productId, @AuthenticationPrincipal MemberContext memberContext) {
Member member = memberContext.getMember();
Member buyer = memberContext.getMember();
Product product = productService.findById(productId);

cartService.deleteCartItem(member, product);
cartService.deleteCartItem(buyer, product);

return "redirect:/cart/list";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
@ToString(callSuper = true)
public class CartItem extends BaseEntity {
@ManyToOne(fetch= FetchType.LAZY)
private Member member;
private Member buyer;

@ManyToOne(fetch = FetchType.LAZY)
private Product product;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import java.util.Optional;

public interface CartItemRepository extends JpaRepository<CartItem, Long> {
Optional<CartItem> findByMemberIdAndProductId(Long memberId, Long productId);
Optional<CartItem> findByBuyerIdAndProductId(Long buyerId, Long productId);

List<CartItem> findAllByMemberIdOrderByIdDesc(Long memberId);
List<CartItem> findAllByBuyerIdOrderByIdDesc(Long buyerId);

List<CartItem> findByBuyerIdAndIdInOrderByIdDesc(Long buyerId, List<Long> cartItemIds);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ public class CartService {
private final CartItemRepository cartItemRepository;

@Transactional
public CartItem addCartItem(Member member, Product product) {
public CartItem addCartItem(Member buyer, Product product) {
// 이미 장바구니에 담겼는지 검사
CartItem oldCartItem = cartItemRepository.findByMemberIdAndProductId(member.getId(), product.getId())
CartItem oldCartItem = cartItemRepository.findByBuyerIdAndProductId(buyer.getId(), product.getId())
.orElse(null);

if(oldCartItem != null) {
return oldCartItem;
}

CartItem cartItem = CartItem.builder()
.member(member)
.buyer(buyer)
.product(product)
.build();

Expand All @@ -37,21 +37,29 @@ public CartItem addCartItem(Member member, Product product) {
return cartItem;
}

public List<CartItem> findAllByMemberIdOrderByIdDesc(Long memberId) {
return cartItemRepository.findAllByMemberIdOrderByIdDesc(memberId);
public List<CartItem> findAllByBuyerIdOrderByIdDesc(Long buyerId) {
return cartItemRepository.findAllByBuyerIdOrderByIdDesc(buyerId);
}

@Transactional
public void deleteCartItem(Member member, Product product) {
CartItem cartItem = findByMemberIdAndProductId(member.getId(), product.getId());
public void deleteCartItem(Member buyer, Product product) {
CartItem cartItem = findByBuyerIdAndProductId(buyer.getId(), product.getId());

cartItemRepository.delete(cartItem);
}

public CartItem findByMemberIdAndProductId(Long memberId, Long productId) {
return cartItemRepository.findByMemberIdAndProductId(memberId, productId).orElseThrow(
public CartItem findByBuyerIdAndProductId(Long buyerId, Long productId) {
return cartItemRepository.findByBuyerIdAndProductId(buyerId, productId).orElseThrow(
() -> {
throw new CartItemNotFoundException("장바구니 품목이 존재하지 않습니다.");
});
}

public CartItem findById(long id) {
return cartItemRepository.findById(id).orElse(null);
}

public List<CartItem> findByBuyerAndIdInOrderByIdDesc(Member buyer, List<Long> cartItemIds) {
return cartItemRepository.findByBuyerIdAndIdInOrderByIdDesc(buyer.getId(), cartItemIds);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.example.mutbooks.app.order.controller;

import com.example.mutbooks.app.base.security.dto.MemberContext;
import com.example.mutbooks.app.member.entity.Member;
import com.example.mutbooks.app.order.service.OrderService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequiredArgsConstructor
@RequestMapping("/order")
public class OrderController {
private final OrderService orderService;

// 주문 생성
@PreAuthorize("isAuthenticated()")
@PostMapping("/create")
@ResponseBody
public String createOrder(@AuthenticationPrincipal MemberContext memberContext, String ids) {
Member buyer = memberContext.getMember();

orderService.createOrder(buyer, ids);

return "성공";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,21 @@ public class Order extends BaseEntity {
@Builder.Default
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderItem> orderItems = new ArrayList<>(); // 주문 품목 리스트

// 해당 주문에 주문 품목 추가
public void addOrderItem(OrderItem orderItem) {
// 주문 품목이 속해있는 주문 지정
orderItem.setOrder(this);
orderItems.add(orderItem);
}

// 주문명 네이밍
public void makeName() {
String name = orderItems.get(0).getProduct().getSubject();
// 2건 이상일 경우 1번 주문 품목 제목 외 ?건 형식으로
if(orderItems.size() > 1) {
name += " 외 %d건".formatted(orderItems.size() - 1);
}
this.name = name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,9 @@ public class OrderItem extends BaseEntity {
private int payPrice; // 결제 금액
private int refundPrice; // 환불 금액
private Boolean isPaid; // 결제 여부

public OrderItem(Product product) {
this.product = product;
this.price = product.getPrice();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.mutbooks.app.order.repository;

import com.example.mutbooks.app.order.entity.OrderItem;
import org.springframework.data.jpa.repository.JpaRepository;

public interface OrderItemRepository extends JpaRepository<OrderItem, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.mutbooks.app.order.repository;

import com.example.mutbooks.app.order.entity.Order;
import org.springframework.data.jpa.repository.JpaRepository;

public interface OrderRepository extends JpaRepository<Order, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.example.mutbooks.app.order.service;

import com.example.mutbooks.app.cart.entity.CartItem;
import com.example.mutbooks.app.cart.service.CartService;
import com.example.mutbooks.app.member.entity.Member;
import com.example.mutbooks.app.order.entity.Order;
import com.example.mutbooks.app.order.entity.OrderItem;
import com.example.mutbooks.app.order.repository.OrderItemRepository;
import com.example.mutbooks.app.order.repository.OrderRepository;
import com.example.mutbooks.app.product.entity.Product;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class OrderService {
private final CartService cartService;
private final OrderItemRepository orderItemRepository;
private final OrderRepository orderRepository;

// 선택한 장바구니 품목으로부터 주문 생성
@Transactional
public Order createOrder(Member buyer, String ids) {
// 주문 생성해야하는 cartItem id 리스트
String[] idsArr = ids.split(",");
// Array -> List
List<Long> cartItemIds = Arrays.stream(idsArr)
.mapToLong(Long::parseLong)
.boxed()
.collect(Collectors.toList());
// 1. 주문 생성해야하는 CartItem 조회
List<CartItem> cartItems = cartService.findByBuyerAndIdInOrderByIdDesc(buyer, cartItemIds);

// 2. 주문 품목 리스트 생성
List<OrderItem> orderItems = new ArrayList<>();
for(CartItem cartItem : cartItems) {
// 2-1. 상품으로부터 주문 품목 생성
Product product = cartItem.getProduct();
orderItems.add(new OrderItem(product)); // Order 정보는 비어있는 상태에서 먼저 생성
// 2-2. 장바구니 품목 삭제
cartService.deleteCartItem(buyer, product);
}

// 3. 주문 생성
return create(buyer, orderItems);
}

@Transactional
public Order create(Member buyer, List<OrderItem> orderItems) {
Order order = Order.builder()
.buyer(buyer)
.build();

for(OrderItem orderItem : orderItems) {
order.addOrderItem(orderItem);
}
order.makeName();
orderRepository.save(order);

return order;
}
}
Loading

0 comments on commit e635c62

Please sign in to comment.