Skip to content

Commit

Permalink
Merge pull request #173 from KUIT-Space/refactor/#172/정산-생성-api
Browse files Browse the repository at this point in the history
Refactor/#172/정산 생성 api
  • Loading branch information
seongjunnoh authored Jan 9, 2025
2 parents e177891 + 4825698 commit 4247ca6
Show file tree
Hide file tree
Showing 29 changed files with 838 additions and 97 deletions.
5 changes: 4 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,15 @@ dependencies {
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'

//S3
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

//LiveKit
implementation 'io.livekit:livekit-server:0.6.1'


//Spring Security Test 의존성
testImplementation 'org.springframework.security:spring-security-test'
}

test {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public BaseResponse<ReadPostDetailResponse> getPost(
}

// 게시글 수정
@PostMapping("/board/post/postId}")
@PostMapping("/board/post/{postId}")
@CheckUserSpace(required = false)
public BaseResponse<String> updatePost(
@JwtLoginAuth Long userId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,15 @@
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import space.space_spring.argumentResolver.jwtLogin.JwtLoginAuth;
import space.space_spring.argumentResolver.userSpace.CheckUserSpace;
import space.space_spring.domain.pay.model.dto.PayTargetInfoDto;
import space.space_spring.domain.pay.model.dto.PayRequestInfoDto;
import space.space_spring.domain.pay.model.dto.TotalPayInfoDto;
import space.space_spring.domain.pay.model.request.PostPayCompleteRequest;
import space.space_spring.domain.pay.model.request.PostPayCreateRequest;
import space.space_spring.domain.pay.model.request.PayCreateRequest;
import space.space_spring.domain.pay.model.response.*;
import space.space_spring.domain.pay.model.entity.PayRequestTarget;
import space.space_spring.domain.user.model.entity.User;
import space.space_spring.exception.CustomException;
import space.space_spring.response.BaseResponse;
import space.space_spring.domain.pay.service.PayService;
import space.space_spring.util.pay.PayUtils;
import space.space_spring.util.user.UserUtils;
import space.space_spring.util.userSpace.UserSpaceUtils;

import java.util.List;

import static space.space_spring.response.status.BaseExceptionResponseStatus.*;
import static space.space_spring.util.bindingResult.BindingResultUtils.getErrorMessage;

Expand All @@ -33,9 +24,9 @@
public class PayController {

private final PayService payService;
private final UserSpaceUtils userSpaceUtils;
private final UserUtils userUtils;
private final PayUtils payUtils;
// private final UserSpaceUtils userSpaceUtils;
// private final UserUtils userUtils;
// private final PayUtils payUtils;

/**
* 정산 홈 view
Expand Down Expand Up @@ -98,12 +89,24 @@ public BaseResponse<PayHomeViewResponse> showPayHome(@JwtLoginAuth Long userId,
// return new BaseResponse<>(payService.getRecentPayRequestBankInfoForUser(userId));
// }
//
// /**
// * 정산 생성
// * response 추가 협의 필요 -> 굳이 PayRequestId를 response 안해도 될꺼같음
// */

/**
* 정산 생성
* response 추가 협의 필요 -> 굳이 PayRequestId를 response 안해도 될꺼같음
*/
@PostMapping("/space/{spaceId}/pay")
public BaseResponse<Long> createPay(@JwtLoginAuth Long userId, @PathVariable Long spaceId, @Validated @RequestBody PayCreateRequest payCreateRequest, BindingResult bindingResult) {
// request 입력 모델 유효성 검증
if (bindingResult.hasErrors()) {
throw new CustomException(INVALID_PAY_CREATE, getErrorMessage(bindingResult));
}

return new BaseResponse<>(payService.createPay(userId, spaceId, payCreateRequest.toServiceRequest()));
}


// @PostMapping("/space/{spaceId}/pay")
// public BaseResponse<String> createPay(@JwtLoginAuth Long userId, @PathVariable Long spaceId, @Validated @RequestBody PostPayCreateRequest postPayCreateRequest, BindingResult bindingResult) {
// public BaseResponse<String> createPay(@JwtLoginAuth Long userId, @PathVariable Long spaceId, @Validated @RequestBody PayCreateRequest payCreateRequest, BindingResult bindingResult) {
//
// // TODO 1. request dto validation
// if (bindingResult.hasErrors()) {
Expand All @@ -117,7 +120,7 @@ public BaseResponse<PayHomeViewResponse> showPayHome(@JwtLoginAuth Long userId,
// // 현재 검증 시 에러가 발생하면 그냥 "스페이스에 속하는 유저가 아닙니다" 라는 에러메시지만 나오고,
// // 어떤 유저가 스페이스에 속하지 않는지에 대한 정보가 없음
// // => 추후 에러메시지의 수정이 필요할듯??
// for (PostPayCreateRequest.TargetInfo targetInfo : postPayCreateRequest.getTargetInfoList()) {
// for (PayCreateRequest.TargetInfo targetInfo : payCreateRequest.getTargetInfoList()) {
// validateIsUserInSpace(targetInfo.getTargetUserId(), spaceId);
// }
//
Expand All @@ -126,10 +129,10 @@ public BaseResponse<PayHomeViewResponse> showPayHome(@JwtLoginAuth Long userId,
//
// // TODO 5. 정산 요청 금액의 유효성 검사
// // return 값 : 미정산 금액
// int unRequestedAmount = validatePayAmount(postPayCreateRequest);
// int unRequestedAmount = validatePayAmount(payCreateRequest);
//
// // TODO 6. 정산 생성
// payService.createPay(userId, spaceId, postPayCreateRequest, unRequestedAmount);
// payService.createPay(userId, spaceId, payCreateRequest, unRequestedAmount);
//
// return new BaseResponse<>("정산 생성 성공");
// }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package space.space_spring.domain.pay.model;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import space.space_spring.exception.CustomException;

import java.util.List;

import static space.space_spring.response.status.BaseExceptionResponseStatus.INVALID_EQUAL_SPLIT_AMOUNT;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class EqualSplitPayAmountPolicy implements PayAmountPolicy {

@Override
public void validatePayAmount(int totalAmount, List<Integer> targetAmounts) {
int numberOfTarget = targetAmounts.size();
int expectedAmountPerTarget = totalAmount / numberOfTarget;

for (Integer targetAmount : targetAmounts) {
if (targetAmount != expectedAmountPerTarget) {
throw new CustomException(INVALID_EQUAL_SPLIT_AMOUNT);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package space.space_spring.domain.pay.model;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import space.space_spring.exception.CustomException;

import java.util.List;

import static space.space_spring.response.status.BaseExceptionResponseStatus.INVALID_INDIVIDUAL_AMOUNT;


@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class IndividualPayAmountPolicy implements PayAmountPolicy {

@Override
public void validatePayAmount(int totalAmount, List<Integer> targetAmounts) {
int sumOfTargetAmounts = targetAmounts.stream().mapToInt(Integer::intValue).sum();

if (sumOfTargetAmounts != totalAmount) {
throw new CustomException(INVALID_INDIVIDUAL_AMOUNT);
}
}
}
7 changes: 7 additions & 0 deletions src/main/java/space/space_spring/domain/pay/model/Money.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package space.space_spring.domain.pay.model;

public class Money {



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package space.space_spring.domain.pay.model;

import java.util.List;

public interface PayAmountPolicy {

void validatePayAmount(int totalAmount, List<Integer> targetAmounts);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package space.space_spring.domain.pay.model;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class PayCreateTargetInfo {

private Long targetUserId;

private int requestedAmount;

@Builder
private PayCreateTargetInfo(Long targetUserId, int requestedAmount) {
this.targetUserId = targetUserId;
this.requestedAmount = requestedAmount;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package space.space_spring.domain.pay.model;

import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class PayCreateValidator {

public void validatePayAmount(PayType payType, int totalAmount, List<Integer> targetAmounts) {
payType.getPayAmountPolicy().validatePayAmount(totalAmount, targetAmounts);
}


}
21 changes: 21 additions & 0 deletions src/main/java/space/space_spring/domain/pay/model/PayType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package space.space_spring.domain.pay.model;

import lombok.Builder;
import lombok.Getter;

@Getter
public enum PayType {
/**
* INDIVIDUAL : 정산 요청 금액을 직접 입력
* EQUAL_SPLIT : 정산 요청 금액을 1/n 분배
*/

INDIVIDUAL(new IndividualPayAmountPolicy()),
EQUAL_SPLIT(new EqualSplitPayAmountPolicy());

private final PayAmountPolicy payAmountPolicy;

PayType (PayAmountPolicy payAmountPolicy) {
this.payAmountPolicy = payAmountPolicy;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import space.space_spring.domain.pay.model.PayType;
import space.space_spring.domain.pay.model.dto.PayRequestInfoDto;
import space.space_spring.domain.pay.model.firstCollection.PayRequestTargets;
import space.space_spring.domain.user.model.entity.User;
Expand Down Expand Up @@ -44,6 +45,9 @@ public class PayRequest extends BaseEntity {
@Column(name = "receive_amount")
private int receiveAmount; // 정산 받은 금액

@Enumerated(EnumType.STRING)
private PayType payType;

@Column(name = "is_complete")
private boolean isComplete;

Expand All @@ -64,23 +68,25 @@ public void addPayRequestTarget(PayRequestTarget payRequestTarget) {
}

@Builder
private PayRequest(User payCreateUser, Space space, int totalAmount, String bankName, String bankAccountNum) {
private PayRequest(User payCreateUser, Space space, int totalAmount, String bankName, String bankAccountNum, PayType payType) {
this.payCreateUser = payCreateUser;
this.space = space;
this.totalAmount = totalAmount;
this.bankName = bankName;
this.bankAccountNum = bankAccountNum;
this.receiveAmount = 0;
this.isComplete = false;
this.payType = payType;
}

public static PayRequest create(User payCreateUser, Space space, int totalAmount, String bankName, String bankAccountNum) {
public static PayRequest create(User payCreateUser, Space space, int totalAmount, String bankName, String bankAccountNum, PayType payType) {
PayRequest build = PayRequest.builder()
.payCreateUser(payCreateUser)
.space(space)
.totalAmount(totalAmount)
.bankName(bankName)
.bankAccountNum(bankAccountNum)
.payType(payType)
.build();

build.payRequestTargets = PayRequestTargets.create(new ArrayList<>());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package space.space_spring.domain.pay.model.request;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import space.space_spring.domain.pay.model.PayCreateTargetInfo;
import space.space_spring.domain.pay.model.PayType;
import space.space_spring.global.common.EnumValidator;

import java.util.List;

@Getter
@NoArgsConstructor
public class PayCreateRequest {

/**
* PayRequest 엔티티 생성 시 필요한 정보
*/

@NotNull(message = "총 정산 요청 금액은 공백일 수 없습니다.")
@Positive(message = "총 정산 요청 금액은 양수이어야 합니다.")
private int totalAmount;

@NotBlank(message = "은행 이름은 공백일 수 없습니다.")
private String bankName;

@NotBlank(message = "은행 계좌 번호는 공백일 수 없습니다.")
private String bankAccountNum;

@Valid
private List<TargetInfoRequest> targetInfoRequests;

@EnumValidator(enumClass = PayType.class, message = "payType은 INDIVIDUAL 또는 EQUAL_SPLIT 이어야 합니다.")
private String payType;


@Builder
private PayCreateRequest(int totalAmount, String bankName, String bankAccountNum, List<TargetInfoRequest> targetInfoRequests, String payType) {
this.totalAmount = totalAmount;
this.bankName = bankName;
this.bankAccountNum = bankAccountNum;
this.targetInfoRequests = targetInfoRequests;
this.payType = payType;
}

public PayCreateServiceRequest toServiceRequest() {
return PayCreateServiceRequest.builder()
.totalAmount(totalAmount)
.bankName(bankName)
.bankAccountNum(bankAccountNum)
.payCreateTargetInfos(targetInfoRequests.stream()
.map(TargetInfoRequest::toPayCreateTargetInfo)
.toList())
.payType(PayType.valueOf(payType))
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package space.space_spring.domain.pay.model.request;

import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import space.space_spring.domain.pay.model.PayCreateTargetInfo;
import space.space_spring.domain.pay.model.PayType;

import java.util.List;

@Getter
@NoArgsConstructor
public class PayCreateServiceRequest {

private int totalAmount;

private String bankName;

private String bankAccountNum;

private List<PayCreateTargetInfo> payCreateTargetInfos;

private PayType payType;

@Builder
private PayCreateServiceRequest(int totalAmount, String bankName, String bankAccountNum, List<PayCreateTargetInfo> payCreateTargetInfos, PayType payType) {
this.totalAmount = totalAmount;
this.bankName = bankName;
this.bankAccountNum = bankAccountNum;
this.payCreateTargetInfos = payCreateTargetInfos;
this.payType = payType;
}

}
Loading

0 comments on commit 4247ca6

Please sign in to comment.