// OrderDTO 준비
public void prepareOrderDTO(OrderDTO orderDTO, Amount amount, UserDetails userDetails) {
orderDTO.setTotalQuantity(amount.getQuantity());
orderDTO.setUid(userDetails.getUsername());
String receiverAddr1 = orderDTO.getReceiverAddr1();
String receiverAddr2 = orderDTO.getReceiverAddr2();
String fullAddr = ((receiverAddr1 != null) ? receiverAddr1.trim() : "") + " " +
((receiverAddr2 != null) ? receiverAddr2.trim() : "");
orderDTO.setOrderAddr(fullAddr.trim());
}
기능 설명
prepareOrderDTO: 클라이언트로부터 전달된OrderDTO와 페이로드(Amount,UserDetails)를 기반으로 주문 DTO를 초기화
amount.getQuantity()를OrderDTO.totalQuantity에 설정userDetails.getUsername()를OrderDTO.uid에 설정- 수령지 정보(
receiverAddr1,receiverAddr2)를 합쳐 하나의 문자열(orderAddr)로 만들어 설정
// 주문 등록
public int registerOrder(OrderDTO orderDTO) {
String uid = orderDTO.getUid();
Optional<User> userOpt = userRepository.findByUid(uid);
if (userOpt.isPresent()) {
User user = userOpt.get();
orderDTO.setOrderSender(user.getName());
orderDTO.setSenderHp(user.getHp());
// 카드 번호(임시)
String paymentContent = "1234 4567 7894 1234";
orderDTO.setPaymentContent(paymentContent);
Order order = modelMapper.map(orderDTO, Order.class);
order.setUser(user);
Order saveOrder = orderRepository.save(order);
return saveOrder.getOrderNo();
}
return 0;
}
기능 설명
registerOrder: 새로운Order엔티티를 생성하고 저장
uid로User조회
- 없으면
0반환(주문 등록 실패)- 조회된
User정보를 이용해
orderDTO.orderSender = user.getName()orderDTO.senderHp = user.getHp()- 임시 카드 번호(
"1234 4567 7894 1234")를orderDTO.paymentContent에 설정ModelMapper로OrderDTO→Order엔티티 매핑
order.setUser(user)orderRepository.save(order)호출하여 DB에 저장- 저장된 엔티티의
orderNo반환
// 상세 주문 등록하기
public void registerOrderItem(int orderNo, List<Integer> cartNos, List<Integer> itemPointList, HttpSession session) {
OrderDTO orderDTO = findAllByOrderNo(orderNo);
String status = "결제대기";
boolean isCartOrder = cartNos != null && !cartNos.isEmpty();
int loopCount = isCartOrder ? cartNos.size() : 1;
for (int i = 0; i < loopCount; i++) {
Integer itemPoint = itemPointList.get(i);
Cart cart;
Product product;
String category;
if (isCartOrder) {
// 장바구니 주문
Integer cartNo = cartNos.get(i);
cart = cartRepository.findById(cartNo).orElseThrow(() -> new RuntimeException("Cart not found"));
product = cart.getProduct();
category = product.getSubCategory().getMainCategory().getMainCategoryName();
} else {
// 바로 주문
CartDTO cartDTO = (CartDTO) session.getAttribute("cartDTO");
ProductDTO productDTO = cartDTO.getProduct();
category = productDTO.getMainCategoryName();
cart = modelMapper.map(cartDTO, Cart.class);
product = modelMapper.map(productDTO, Product.class);
}
Order order = Order.builder()
.orderNo(orderNo)
.payment(orderDTO.getPayment())
.build();
OrderItem orderItem = OrderItem.builder()
.order(order)
.product(product)
.opt1(cart.getOpt1()).opt2(cart.getOpt2())
.opt3(cart.getOpt3()).opt4(cart.getOpt4())
.opt5(cart.getOpt5()).opt6(cart.getOpt6())
.opt1Cont(cart.getOpt1Cont()).opt2Cont(cart.getOpt2Cont())
.opt3Cont(cart.getOpt3Cont()).opt4Cont(cart.getOpt4Cont())
.opt5Cont(cart.getOpt5Cont()).opt6Cont(cart.getOpt6Cont())
.itemCount(cart.getCartProdCount())
.itemPrice(product.getProdPrice())
.itemDiscount(product.getProdDiscount())
.itemPoint(itemPoint)
.category(category)
.orderStatus(status)
.build();
orderItemRepository.save(orderItem);
}
}
기능 설명
registerOrderItem:
- 주어진
orderNo를 기준으로 각 주문 항목(OrderItem)을 등록
findAllByOrderNo(orderNo)호출해OrderDTO조회cartNos가 비어 있으면 “바로 주문” 모드, 아니면 “장바구니 주문” 모드로 분기- 루프(
loopCount)
- 장바구니 주문일 때
cartRepository.findById(cartNo)로Cart엔티티 조회product = cart.getProduct()category = product.getSubCategory().getMainCategory().getMainCategoryName()- 바로 주문일 때
- 세션(
session.getAttribute("cartDTO"))에서CartDTO꺼내Cart엔티티로 매핑ProductDTO에서Product로 매핑category = productDTO.getMainCategoryName()Order.builder().orderNo(orderNo).payment(orderDTO.getPayment()).build()로 임시Order엔티티 생성OrderItem.builder()로 다음 필드 설정
order(부모 주문 참조)product- 옵션(
opt1opt6,opt1Contopt6Cont)itemCount = cart.getCartProdCount()itemPrice = product.getProdPrice()itemDiscount = product.getProdDiscount()itemPoint(파라미터로 전달된 포인트)categoryorderStatus = "결제대기"orderItemRepository.save(orderItem)로 저장
// 상품 재고, 판매량 계산
public void changeSoldAndStock (List<Integer> cartNos) throws Exception {
for (Integer cartNo : cartNos) {
Optional<Cart> optCart = cartRepository.findById(cartNo);
if (optCart.isPresent()) {
Cart cart = optCart.get();
String prodNo = cart.getProduct().getProdNo();
int cartProdCount = cart.getCartProdCount();
Optional<Product> optProduct = productRepository.findByProdNo(prodNo);
if (optProduct.isPresent()) {
Product product = optProduct.get();
product.setProdSold(product.getProdSold() + cartProdCount);
if (product.getProdStock() >= cartProdCount) {
product.setProdStock(product.getProdStock() - cartProdCount);
} else {
throw new Exception("Insufficient stock for product: " + prodNo);
}
productRepository.save(product);
}
}
}
}
기능 설명
changeSoldAndStock:
- 각
cartNo에 해당하는Cart엔티티를 조회하여 연결된 제품의 재고(prodStock)와 판매량(prodSold)을 갱신
cartRepository.findById(cartNo)→Cart조회prodNo = cart.getProduct().getProdNo()→Product조회- 판매량(
prodSold) 증가:product.setProdSold(product.getProdSold() + cartProdCount)- 재고(
prodStock) 감소:
- 재고가 충분(
>= cartProdCount)하면prodStock -= cartProdCount- 아니면
Exception("Insufficient stock ...")발생- 저장(
productRepository.save(product))
// 쿠폰 사용 상태로 바꾸기
public void changeState(Long issueNo) {
if (issueNo == null || issueNo == 0L)
return;
Optional<CouponIssue> optCouponIssue = couponIssueRepository.findById(issueNo);
if (optCouponIssue.isPresent()) {
CouponIssue couponIssue = optCouponIssue.get();
couponIssue.setState("사용");
couponIssue.setUsedDate(LocalDate.now());
couponIssueRepository.save(couponIssue);
} else {
log.error("Coupon not found for issueNo: {}", issueNo);
}
}
기능 설명
changeState: 쿠폰 발급 이력(CouponIssue)을 “사용됨” 상태로 업데이트
- 파라미터
issueNo가null또는0L이면 바로 종료couponIssueRepository.findById(issueNo)→CouponIssue조회- 존재하면
couponIssue.setState("사용")couponIssue.setUsedDate(LocalDate.now())couponIssueRepository.save(couponIssue)
// 포인트 사용 시 기록
public UserDetailsDTO changePoint(Integer usedPoint, UserDetails userDetails, int orderNo) {
if (usedPoint == null || usedPoint == 0)
return null;
String uid = userDetails.getUsername();
User user = User.builder()
.uid(uid)
.build();
Optional<kr.co.lotteon.entity.user.UserDetails> optUserDetails = userDetailsRepository.findByUser(user);
Point point = Point.builder()
.point(usedPoint * (-1))
.user(user)
.pointDesc("상품 주문(주문 번호: " + orderNo + ") 차감")
.expiryDate(null)
.build();
pointRepository.save(point);
if (optUserDetails.isPresent()) {
kr.co.lotteon.entity.user.UserDetails userDetail = optUserDetails.get();
userDetail.setUserPoint(userDetail.getUserPoint() - usedPoint);
userDetailsRepository.save(userDetail);
UserDetailsDTO userDetailsDTO = modelMapper.map(userDetail, UserDetailsDTO.class);
return userDetailsDTO;
}
return null;
}
기능 설명
changePoint:
usedPoint가null또는0이면null반환(포인트 미사용)uid = userDetails.getUsername()→User엔티티 생성(간이 객체)userDetailsRepository.findByUser(user)→UserDetails엔티티 조회Point엔티티 생성
point = usedPoint * (-1)(마이너스 값으로 차감 내역 기록)pointDesc = "상품 주문(주문 번호: X) 차감"expiryDate = nullpointRepository.save(point)호출해 포인트 트랜잭션 기록UserDetails엔티티가 존재하면
userDetail.setUserPoint(userDetail.getUserPoint() - usedPoint)로 잔여 포인트 차감userDetailsRepository.save(userDetail)modelMapper.map(userDetail, UserDetailsDTO.class)로 DTO 반환
// 카카오페이 주문용 DTO
public Amount getAmount(int orderNo, UserDetails userDetails, OrderDTO orderDTO) {
Amount amount = new Amount();
String customOrderNo = "상품" + orderNo;
amount.setItem_name(customOrderNo);
amount.setPartner_order_id(String.valueOf(orderNo));
amount.setPartner_user_id(userDetails.getUsername());
amount.setTotal(orderDTO.getOrderTotalPrice());
amount.setTax(orderDTO.getOrderTotalPrice() / 100 * 10);
return amount;
}