Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] 판매 금액 정산 - 모든 점주 및 OrderPayment 목록 조회, OrderPayment 상태 일괄 갱신 #93

Merged
merged 16 commits into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
9afc509
[refactor] 메뉴 가격 데이터 타입을 Long 으로 통일
june-777 Aug 16, 2024
88a1ac2
[refactor] 메뉴 가격 데이터 타입을 Long 으로 통일
june-777 Aug 16, 2024
2f5494b
[feat] 모든 점주를 조회하는 기능
june-777 Aug 16, 2024
ddfd06f
[feat] 각 점주의 정산해야할 OrderPayment 목록을 조회하는 기능
june-777 Aug 16, 2024
7bbacc6
[feat] PointPayment -> OrderPayment 이름 변경 및 생성자 추가
june-777 Aug 16, 2024
8e4af08
[feat] 정산해야할 OrderPayment 가 올바른지 검증하는 기능
june-777 Aug 16, 2024
30b60e8
[feat] OrderPayment 목록의 OrderPaymentStatus 상태를 ADJUSTMENT_SUCCESS 로 갱…
june-777 Aug 16, 2024
7b0ed7e
[style] 주문 금액 정산 기능 뼈대 코드 TODO 작성
june-777 Aug 16, 2024
94293b3
[feat] VendorId와 OrderPaymentStatus 기준으로 OrderPayment 목록을 조회하는 기능
june-777 Aug 16, 2024
0388fad
[feat] OrderPaymentStatus 를 일괄 업데이트하는 기능
june-777 Aug 16, 2024
9eff555
[feat] OrderPaymentStatus 상태 Enum
june-777 Aug 16, 2024
87885dc
[feat] @Getter Lombok 추가
june-777 Aug 16, 2024
b6549fa
[style] 에러 코드 수정
june-777 Aug 16, 2024
44b87bc
Merge remote-tracking branch 'origin/main' into feature/78_june-777_판…
june-777 Aug 17, 2024
203ee11
[fix] 주문 가격 타입을 long 으로 변경하여 컴파일 오류 수정
june-777 Aug 17, 2024
71a0349
[fix] OrderItem 패키지 이동 변경사항 반영하여 컴파일 오류 수정
june-777 Aug 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/java/camp/woowak/lab/menu/domain/Menu.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class Menu {
private String name;

@Column(nullable = false)
private Integer price;
private Long price;

@Column(nullable = false)
private Long stockCount;
Expand All @@ -44,7 +44,7 @@ public class Menu {
private String imageUrl;

public Menu(Store store, MenuCategory menuCategory, String name,
Integer price, Long stockCount, String imageUrl
Long price, Long stockCount, String imageUrl
) {
MenuValidator.validate(store, menuCategory, name, price, stockCount, imageUrl);
this.store = store;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/camp/woowak/lab/menu/domain/MenuValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class MenuValidator {
private static final int MAX_NAME_LENGTH = 10;

public static void validate(final Store store, final MenuCategory menuCategory, final String name,
final Integer price, final Long stockCount, final String imageUrl) {
final Long price, final Long stockCount, final String imageUrl) {
validateNotNull(store, menuCategory, name, price, stockCount, imageUrl);
validateNotBlank(name, imageUrl);
validateNameLength(name);
Expand Down Expand Up @@ -40,7 +40,7 @@ private static void validateNameLength(final String name) {
}
}

private static void validatePriceNegative(final Integer price) {
private static void validatePriceNegative(final Long price) {
if (price <= 0) {
throw new InvalidMenuCreationException(INVALID_PRICE, "메뉴의 가격은 양수만 가능합니다. cur: " + price);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ public enum MenuErrorCode implements ErrorCode {
INVALID_PRICE(HttpStatus.BAD_REQUEST, "m_6", "메뉴의 가격 범위를 벗어났습니다."),
INVALID_STOCK_COUNT(HttpStatus.BAD_REQUEST, "m_7", "메뉴의 재고 개수는 1개 이상이어야 합니다."),

NOT_FOUND_MENU_CATEGORY(HttpStatus.BAD_REQUEST, "M3", "메뉴 카테고리를 찾을 수 없습니다."),
NOT_FOUND_MENU(HttpStatus.BAD_REQUEST, "m_8", "메뉴를 찾을 수 없습니다."),
NOT_FOUND_MENU_CATEGORY(HttpStatus.BAD_REQUEST, "m_9", "메뉴 카테고리를 찾을 수 없습니다."),
NOT_ENOUGH_STOCK(HttpStatus.BAD_REQUEST, "M4", "재고가 부족합니다.");

private final int status;
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/camp/woowak/lab/order/domain/vo/OrderItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@
@Embeddable
public class OrderItem {
private Long menuId;
private int price;
private long price;
private int quantity;
private int totalPrice;
private long totalPrice;

protected OrderItem() {
}

public OrderItem(Long menuId, int price, int quantity) {
public OrderItem(Long menuId, long price, int quantity) {
this.menuId = menuId;
this.price = price;
this.quantity = quantity;
this.totalPrice = price * quantity;
}

public int getTotalPrice() {
public long getTotalPrice() {
return totalPrice;
}
}
70 changes: 70 additions & 0 deletions src/main/java/camp/woowak/lab/payment/domain/OrderPayment.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package camp.woowak.lab.payment.domain;

import java.time.LocalDateTime;

import camp.woowak.lab.customer.domain.Customer;
import camp.woowak.lab.order.domain.Order;
import camp.woowak.lab.vendor.domain.Vendor;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class OrderPayment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
private Order order;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "sendor_id", nullable = false)
private Customer sender;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "recipient_id", nullable = false)
private Vendor recipient;

@Enumerated(value = EnumType.STRING)
private OrderPaymentStatus orderPaymentStatus;

private LocalDateTime createdAt;

public OrderPayment(Order order, Customer sender, Vendor recipient,
OrderPaymentStatus orderPaymentStatus, LocalDateTime createdAt
) {
this.order = order;
this.sender = sender;
this.recipient = recipient;
this.orderPaymentStatus = orderPaymentStatus;
this.createdAt = createdAt;
}

public void validateReadyToAdjustment(final Vendor adjustmentTarget) {
if (isEqualsRecipient(adjustmentTarget) && orderPaymentStatusIsSuccess()) {
return;
}
throw new IllegalArgumentException();
}

private boolean isEqualsRecipient(Vendor recipient) {
return this.recipient.equals(recipient);
}

private boolean orderPaymentStatusIsSuccess() {
return this.orderPaymentStatus.equals(OrderPaymentStatus.ORDER_SUCCESS);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package camp.woowak.lab.payment.domain;

public enum OrderPaymentStatus {
ORDER_SUCCESS,
ADJUSTMENT_SUCCESS,
}
24 changes: 0 additions & 24 deletions src/main/java/camp/woowak/lab/payment/domain/PointPayment.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package camp.woowak.lab.payment.repository;

import java.util.List;
import java.util.UUID;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import camp.woowak.lab.payment.domain.OrderPayment;
import camp.woowak.lab.payment.domain.OrderPaymentStatus;

public interface OrderPaymentRepository extends JpaRepository<OrderPayment, Long> {

@Query("SELECT op FROM OrderPayment op "
+ "WHERE op.recipient.id = :recipientId "
+ "AND op.orderPaymentStatus = :orderPaymentStatus")
List<OrderPayment> findByRecipientIdAndOrderPaymentStatus(@Param("recipientId") UUID recipientId,
@Param("orderPaymentStatus") OrderPaymentStatus orderPaymentStatus);

@Modifying(clearAutomatically = true)
@Query("UPDATE OrderPayment op "
+ "SET op.orderPaymentStatus = :newStatus "
+ "WHERE op.id IN :ids")
int updateOrderPaymentStatus(@Param("ids") List<Long> ids, @Param("newStatus") OrderPaymentStatus newStatus);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package camp.woowak.lab.payment.service;

import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import camp.woowak.lab.menu.repository.MenuRepository;
import camp.woowak.lab.order.domain.vo.OrderItem;
import camp.woowak.lab.payment.domain.OrderPayment;
import camp.woowak.lab.payment.domain.OrderPaymentStatus;
import camp.woowak.lab.payment.repository.OrderPaymentRepository;
import camp.woowak.lab.vendor.domain.Vendor;
import camp.woowak.lab.vendor.exception.NotFoundVendorException;
import camp.woowak.lab.vendor.repository.VendorRepository;
import lombok.RequiredArgsConstructor;

/**
* 정산을 담당하는 서비스
*/
@Service
@RequiredArgsConstructor
public class OrderPaymentAdjustmentService {

private final VendorRepository vendorRepository;
private final MenuRepository menuRepository;
private final OrderPaymentRepository orderPaymentRepository;

/**
* @throws NotFoundVendorException vendorId에 해당하는 점주를 찾을 수 없을 떄
*/
@Transactional
june-777 marked this conversation as resolved.
Show resolved Hide resolved
public void adjustment() {
// 1. 모든 점주 조회
List<Vendor> vendors = findAllVendors();
for (Vendor vendor : vendors) {
// 2. 각 점주의 정산해야할 OrderPayment 목록을 조회
List<OrderPayment> orderPayments = findOrderPaymentsToAdjustment(vendor);

// 3. 각 OrderPayment 의 Order 주문 금액을 계산
Long totalOrderPrice = calculateTotalOrderPrice(orderPayments);

// 4. 총 주문 금액에서 수수료 5%를 계산
Double commission = calculateCommission(totalOrderPrice);

// 5. 수수료를 제외한 금액을 점주에게 송금

// 6. 송금을 성공하면, OrderPayment 목록의 OrderPaymentStatus 상태를 ADJUSTMENT_SUCCESS 로 갱신
updateOrderPaymentStatus(orderPayments);
}
}

// 모든 점주 조회
private List<Vendor> findAllVendors() {
return vendorRepository.findAll();
}

// 각 점주의 정산해야할 OrderPayment 목록을 조회
private List<OrderPayment> findOrderPaymentsToAdjustment(final Vendor vendor) {
List<OrderPayment> orderPayments = orderPaymentRepository.findByRecipientIdAndOrderPaymentStatus(
vendor.getId(), OrderPaymentStatus.ORDER_SUCCESS);

for (OrderPayment orderPayment : orderPayments) {
// 정산해야할 OrderPayment 가 맞는지 검증
orderPayment.validateReadyToAdjustment(vendor);
}

return orderPayments;
}

// TODO: OrderPayment 목록의 Order 총 주문 금액을 계산한다.
// 메뉴의 가격은 계속 바뀔 수 있어서, 정산 시점에 주문 - 메뉴 정보로 금액을 다시 계산하는 부분이 제약이 있음
private long calculateTotalOrderPrice(final List<OrderPayment> orderPayments) {
Long totalOrderPrice = 0L;

return totalOrderPrice;
}

// TODO: 각 OrderPayment 의 Order 주문 금액을 계산한다.
private Long calculateOrderPrice(List<OrderItem> orderItems) {
long totalOrderPrice = 0L;

return totalOrderPrice;
}

// 총 주문 금액에서 수수료 5%를 계산한다.
private Double calculateCommission(Long totalOrderPrice) {

return 0.0;
}

// OrderPayment 목록의 OrderPaymentStatus 상태를 ADJUSTMENT_SUCCESS 로 갱신
private void updateOrderPaymentStatus(List<OrderPayment> orderPayments) {
orderPaymentRepository.updateOrderPaymentStatus(
orderPayments.stream().map(OrderPayment::getId).toList(),
OrderPaymentStatus.ADJUSTMENT_SUCCESS);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public record MenuLineItem(
String categoryName,

@NotNull(message = "음식 상품 가격은 필수값입니다.")
Integer price
Long price

) {
}
6 changes: 3 additions & 3 deletions src/test/java/camp/woowak/lab/cart/domain/CartTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void setUp() {
store = createSavedStore(1L, vendor, "중화반점", minPrice,
LocalDateTime.now().minusMinutes(10).withSecond(0).withNano(0),
LocalDateTime.now().plusMinutes(10).withSecond(0).withNano(0));
menu = createSavedMenu(1L, store, new MenuCategory(store, "중식"), "짜장면", 9000);
menu = createSavedMenu(1L, store, new MenuCategory(store, "중식"), "짜장면", 9000L);
}

@Nested
Expand All @@ -70,7 +70,7 @@ void storeNotOpenExceptionTest() {
Store closedStore = createSavedStore(2L, vendor, "closed", minPrice,
LocalDateTime.now().minusMinutes(30).withSecond(0).withNano(0),
LocalDateTime.now().minusMinutes(10).withSecond(0).withNano(0));
Menu closedMenu = createSavedMenu(2L, closedStore, new MenuCategory(closedStore, "중식"), "짬뽕", 9000);
Menu closedMenu = createSavedMenu(2L, closedStore, new MenuCategory(closedStore, "중식"), "짬뽕", 9000L);

//when & then
assertThatThrownBy(() -> cart.addMenu(closedMenu))
Expand All @@ -87,7 +87,7 @@ void otherStoreMenuExceptionTest() {
Store otherStore = createSavedStore(2L, vendor, "otherStore", minPrice,
LocalDateTime.now().minusMinutes(30).withSecond(0).withNano(0),
LocalDateTime.now().plusMinutes(30).withSecond(0).withNano(0));
Menu otherStoreMenu = createSavedMenu(2L, otherStore, new MenuCategory(otherStore, "중식"), "짬뽕", 9000);
Menu otherStoreMenu = createSavedMenu(2L, otherStore, new MenuCategory(otherStore, "중식"), "짬뽕", 9000L);

//when & then
assertThatThrownBy(() -> cart.addMenu(otherStoreMenu))
Expand Down
14 changes: 7 additions & 7 deletions src/test/java/camp/woowak/lab/cart/service/CartServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ void setUp() {

menuCategory = createMenuCategory(store, "중식");

menu = createMenu(store, menuCategory, "짜장면", 90000);
menu = createMenu(store, menuCategory, "짜장면", 90000L);
}

@Nested
Expand Down Expand Up @@ -124,7 +124,7 @@ void throwExceptionWhenAddMenuInCartWithClosedStoresMenu() {
LocalDateTime endTime = LocalDateTime.now().minusMinutes(1).withSecond(0).withNano(0);
Store closedStore = createStore(vendor, "오픈 전의 중화반점", 8000, startTime, endTime);
MenuCategory closedMenuCategory = createMenuCategory(closedStore, "닫힌 카테고리");
Menu menu = createMenu(closedStore, closedMenuCategory, "닫힌 가게의 메뉴", 1000);
Menu menu = createMenu(closedStore, closedMenuCategory, "닫힌 가게의 메뉴", 1000L);

AddCartCommand command = new AddCartCommand(customer.getId().toString(), menu.getId());

Expand All @@ -139,7 +139,7 @@ void throwExceptionWhenAddMenuInCartWithOtherStoresMenu() {
//given
Store otherStore = createStore(vendor, "다른집", 8000, startTime, endTime);
MenuCategory otherMenuCategory = createMenuCategory(otherStore, "다른집 카테고리");
Menu otherStoresMenu = createMenu(otherStore, otherMenuCategory, "다른집 짜장면", 9000);
Menu otherStoresMenu = createMenu(otherStore, otherMenuCategory, "다른집 짜장면", 9000L);

AddCartCommand command1 = new AddCartCommand(customer.getId().toString(), menu.getId());
cartService.addMenu(command1);
Expand Down Expand Up @@ -174,15 +174,15 @@ void getTotalPriceWithEmptyList() {
@DisplayName("현재 장바구니에 담긴 모든 메뉴의 총 금액을 return 받는다.")
void getTotalPriceTest() {
//given
int price1 = 1000;
Long price1 = 1000L;
Menu menu1 = createMenu(store, menuCategory, "짜장면1", price1);
cartService.addMenu(new AddCartCommand(customer.getId().toString(), menu1.getId()));

int price2 = 2000;
Long price2 = 2000L;
Menu menu2 = createMenu(store, menuCategory, "짬뽕1", price2);
cartService.addMenu(new AddCartCommand(customer.getId().toString(), menu2.getId()));

int price3 = Integer.MAX_VALUE;
Long price3 = Long.MAX_VALUE;
Menu menu3 = createMenu(store, menuCategory, "황제정식", price3);
cartService.addMenu(new AddCartCommand(customer.getId().toString(), menu3.getId()));

Expand All @@ -202,7 +202,7 @@ private MenuCategory createMenuCategory(Store store, String name) {
return menuCategoryRepository.saveAndFlush(menuCategory1);
}

private Menu createMenu(Store store, MenuCategory menuCategory, String name, int price) {
private Menu createMenu(Store store, MenuCategory menuCategory, String name, Long price) {
Menu menu1 = new Menu(store, menuCategory, name, price, 1L, "imageUrl");
menuRepository.saveAndFlush(menu1);

Expand Down
Loading