Skip to content
This repository has been archived by the owner on Aug 13, 2022. It is now read-only.

Commit

Permalink
[#25] 결제관련 수정
Browse files Browse the repository at this point in the history
- Order <-> Payment 일대일 매핑
- PaymentService factory 생성
- PaymentService 공통 로직 추가
  • Loading branch information
jjeda committed Dec 19, 2019
1 parent 11dc401 commit 6b9f7ea
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
package me.jjeda.mall.orders.controller;

import lombok.RequiredArgsConstructor;
import me.jjeda.mall.orders.domain.PaymentFactory;
import me.jjeda.mall.orders.domain.PaymentType;
import me.jjeda.mall.orders.dto.PaymentDto;
import me.jjeda.mall.orders.service.PaymentService;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/api/orders/payment")
@RequiredArgsConstructor
public class PaymentController {

@PostMapping
public ResponseEntity payForOrder() {
private final PaymentFactory paymentFactory;

//TODO : factory 패턴을 통해 client 에서 받아온 메시지의 PaymentType 에 따라 PaymentService 를 주입받는다.
// final PaymentService paymentService = PaymentFactory.getType();
return null;
@PostMapping(value = "/{orderId}")
public ResponseEntity payForOrder(@RequestBody PaymentDto paymentDto, @PathVariable Long orderId) {

final PaymentService paymentService = paymentFactory.getType(paymentDto.getPaymentType());

return ResponseEntity.ok(paymentService.payForOrder(paymentDto, orderId));
}

}
6 changes: 5 additions & 1 deletion src/main/java/me/jjeda/mall/orders/domain/Order.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package me.jjeda.mall.orders.domain;

import com.fasterxml.jackson.annotation.JsonManagedReference;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
Expand Down Expand Up @@ -54,6 +53,11 @@ public class Order {
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List<OrderItem> orderItems;

private int totalPrice;

@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Payment payment;

private LocalDateTime orderAt;

@Enumerated(EnumType.STRING)
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/me/jjeda/mall/orders/domain/Payment.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.time.LocalDateTime;

@Entity
@Getter
Expand All @@ -35,5 +36,7 @@ public class Payment {
@Enumerated(EnumType.STRING)
private PaymentType paymentType;

private LocalDateTime createdAt;


}
36 changes: 36 additions & 0 deletions src/main/java/me/jjeda/mall/orders/domain/PaymentFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package me.jjeda.mall.orders.domain;

import lombok.RequiredArgsConstructor;
import me.jjeda.mall.orders.service.CashPaymentService;
import me.jjeda.mall.orders.service.CreditPaymentService;
import me.jjeda.mall.orders.service.MobilePaymentService;
import me.jjeda.mall.orders.service.PaymentService;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class PaymentFactory {

private final CashPaymentService cashPaymentService;
private final CreditPaymentService creditPaymentService;
private final MobilePaymentService mobilePaymentService;

public PaymentService getType(PaymentType paymentType) {
final PaymentService paymentService;

switch (paymentType) {
case CASH:
paymentService = cashPaymentService;
break;
case CREDIT:
paymentService = creditPaymentService;
break;
case MOBILE:
paymentService = mobilePaymentService;
break;
default:
throw new IllegalArgumentException();
}
return paymentService;
}
}
3 changes: 2 additions & 1 deletion src/main/java/me/jjeda/mall/orders/dto/OrderDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ public class OrderDto {

public Order toEntity() {
List<OrderItem> tempOrderItems = new ArrayList<>();
orderItemDtoList.forEach((dto)->tempOrderItems.add(dto.toEntity()));
orderItemDtoList.forEach((dto) -> tempOrderItems.add(dto.toEntity()));

return Order.builder()
.delivery(this.deliveryDto.toEntity())
.orderItems(tempOrderItems)
.payment(PaymentDto.toReadyEntity())
.status(OrderStatus.ORDER)
.orderAt(LocalDateTime.now())
.build();
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/me/jjeda/mall/orders/dto/PaymentDto.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
package me.jjeda.mall.orders.dto;

import lombok.Builder;
import lombok.Getter;
import me.jjeda.mall.orders.domain.Payment;
import me.jjeda.mall.orders.domain.PaymentStatus;
import me.jjeda.mall.orders.domain.PaymentType;

@Builder
@Getter
public class PaymentDto {

private Long id;

private int price;

private PaymentStatus paymentStatus;

private PaymentType paymentType;

public static Payment toReadyEntity() {
return Payment.builder()
.paymentStatus(PaymentStatus.READY)
.build();
}
}
40 changes: 36 additions & 4 deletions src/main/java/me/jjeda/mall/orders/service/CashPaymentService.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,50 @@
package me.jjeda.mall.orders.service;

import lombok.RequiredArgsConstructor;
import me.jjeda.mall.items.service.ItemService;
import me.jjeda.mall.orders.domain.Order;
import me.jjeda.mall.orders.domain.OrderItem;
import me.jjeda.mall.orders.domain.Payment;
import me.jjeda.mall.orders.domain.PaymentStatus;
import me.jjeda.mall.orders.domain.PaymentType;
import me.jjeda.mall.orders.dto.PaymentDto;
import me.jjeda.mall.orders.repository.CashPaymentRepository;
import me.jjeda.mall.orders.repository.PaymentRepository;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

@RequiredArgsConstructor
public class CashPaymentService implements PaymentService {

private final PaymentRepository paymentRepository;
private final CashPaymentRepository cashPaymentRepository;
private final OrderService orderService;
private final ItemService itemService;

@Override
public PaymentDto payForOrder(PaymentDto paymentDto, Long orderId) {
return null;
@Transactional
public Payment payForOrder(PaymentDto paymentDto, Long orderId) {
//TODO : [#40] 탬플릿-콜백 패턴으로 공통부분 재사용코드로 만들기(각 결제 정보 저장로직만 다름)
Order order = orderService.getOrder(orderId);
Payment payment = order.getPayment();
List<OrderItem> orderItems = order.getOrderItems();

payment = Payment.builder()
.paymentStatus(PaymentStatus.COMP)
.id(payment.getId())
.price(order.getTotalPrice())
.createdAt(LocalDateTime.now())
.paymentType(PaymentType.CASH)
.build();

/* 주문이 완료되면 아이템의 전체 재고에서 주문수량만큼 빼주어야한다. */
//TODO : N+1문제 -> 벌크호출
orderItems.forEach((orderItem) ->
itemService.decrementStock(orderItem.getItem().getId(), orderItem.getQuantity())
);

// TODO : cashPaymentRepository 를 통해 현금결제 정보를 저장해야함

return payment;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package me.jjeda.mall.orders.service;

import lombok.RequiredArgsConstructor;
import me.jjeda.mall.orders.domain.Payment;
import me.jjeda.mall.orders.dto.PaymentDto;
import me.jjeda.mall.orders.repository.CreditPaymentRepository;
import me.jjeda.mall.orders.repository.PaymentRepository;
Expand All @@ -12,7 +13,8 @@ public class CreditPaymentService implements PaymentService {
private final CreditPaymentRepository creditPaymentRepository;

@Override
public PaymentDto payForOrder(PaymentDto paymentDto, Long orderId) {
public Payment payForOrder(PaymentDto paymentDto, Long orderId) {
return null;
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package me.jjeda.mall.orders.service;

import lombok.RequiredArgsConstructor;
import me.jjeda.mall.orders.domain.Payment;
import me.jjeda.mall.orders.dto.PaymentDto;
import me.jjeda.mall.orders.repository.MobilePaymentRepository;
import me.jjeda.mall.orders.repository.PaymentRepository;
Expand All @@ -12,7 +13,7 @@ public class MobilePaymentService implements PaymentService {
private final MobilePaymentRepository mobilePaymentRepository;

@Override
public PaymentDto payForOrder(PaymentDto paymentDto, Long orderId) {
public Payment payForOrder(PaymentDto paymentDto, Long orderId) {
return null;
}
}
24 changes: 9 additions & 15 deletions src/main/java/me/jjeda/mall/orders/service/OrderService.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import me.jjeda.mall.orders.domain.OrderStatus;
import me.jjeda.mall.orders.dto.OrderDto;
import me.jjeda.mall.orders.repository.OrderRepository;
import me.jjeda.mall.orders.repository.PaymentRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -30,16 +29,17 @@ public Order createOrder(OrderDto orderDto, AccountDto accountDto) {

// 연관관계 메서드
order.setAccount(AccountAndDtoAdapter.dtoToEntity(accountDto));
//TODO : account.insertOrder(order);
//TODO : [#33] Account <-> Order 연관관계 메서드 처리
// order.getAccount().insertOrder(order);
order.getDelivery().setOrder(order);
List<OrderItem> orderItems = order.getOrderItems();
orderItems.forEach((orderItem) -> orderItem.setOrder(order));

/* 주문이 완료되면 아이템의 전체 재고에서 주문수량만큼 빼주어야한다. */
//TODO : 벌크호출 + 결제가 완료되면 결제쪽에서 해주어야함
orderItems.forEach((orderItem) ->
itemService.decrementStock(orderItem.getItem().getId(), orderItem.getQuantity())
);
int totalPrice = 0;
for (OrderItem item : orderItems) {
item.setOrder(order);
totalPrice += item.getOrderPrice() * item.getQuantity();
}
order.setTotalPrice(totalPrice);

return orderRepository.save(order);
}
Expand All @@ -48,13 +48,6 @@ public Order getOrder(Long orderId) {
return orderRepository.findById(orderId).orElseThrow(EntityNotFoundException::new);
}

//TODO [#25] : 주문생성 -> 결제 -> 배송 에서 결제단계
public Order payForOrder() {

return null;
}


@Transactional
public Order changeDeliveryStatus(Long orderId, DeliveryStatus deliveryStatus) {
Order order = orderRepository.findById(orderId).orElseThrow(EntityNotFoundException::new);
Expand All @@ -76,6 +69,7 @@ public Order cancelOrder(Long orderId) {
}
order.setStatus(OrderStatus.CANCEL);

//TODO : 주문 취소 ->결제 취소 할때로 변경
/* 주문을 취소하면 주문했던 수량만큼 다시 재고에 추가해주어야한다 */
List<OrderItem> orderItems = order.getOrderItems();
orderItems.forEach((orderItem) ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package me.jjeda.mall.orders.service;

import me.jjeda.mall.orders.domain.Payment;
import me.jjeda.mall.orders.dto.PaymentDto;
import org.springframework.stereotype.Service;

@Service
public interface PaymentService {

PaymentDto payForOrder(PaymentDto paymentDto, Long orderId);
Payment payForOrder(PaymentDto paymentDto, Long orderId);

}

0 comments on commit 6b9f7ea

Please sign in to comment.