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: 최소 출금 포인트 설정, 첫 가입시 무료 포인트 적립 #205

Merged
merged 9 commits into from
Nov 9, 2024
262 changes: 131 additions & 131 deletions src/main/java/com/example/sinitto/common/dummy/InitialData.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import com.example.sinitto.member.entity.Member;
import com.example.sinitto.member.repository.MemberRepository;
import com.example.sinitto.point.entity.Point;
import com.example.sinitto.point.entity.PointLog;
import com.example.sinitto.point.repository.PointLogRepository;
import com.example.sinitto.point.repository.PointRepository;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.data.redis.core.RedisTemplate;
Expand All @@ -24,24 +26,28 @@
@Service
public class MemberService{

private static final int WELCOME_POINT = 10000;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

회원가입시 포인트 10000원으로 했는데 너무 많으려나요?!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수수료가 20프로니까 ㅎㅎ


private final MemberRepository memberRepository;
private final TokenService tokenService;
private final KakaoApiService kakaoApiService;
private final KakaoTokenService kakaoTokenService;
private final PointRepository pointRepository;
private final RedisTemplate<String, Object> redisTemplate;
private final CallbackService callbackService;
private final HelloCallService helloCallService;
private final PointRepository pointRepository;
private final PointLogRepository pointLogRepository;

public MemberService(MemberRepository memberRepository, TokenService tokenService, KakaoApiService kakaoApiService, KakaoTokenService kakaoTokenService, PointRepository pointRepository, RedisTemplate<String, Object> redisTemplate, CallbackService callbackService, HelloCallService helloCallService) {
public MemberService(MemberRepository memberRepository, TokenService tokenService, KakaoApiService kakaoApiService, KakaoTokenService kakaoTokenService, RedisTemplate<String, Object> redisTemplate, CallbackService callbackService, HelloCallService helloCallService, PointRepository pointRepository, PointLogRepository pointLogRepository) {
this.memberRepository = memberRepository;
this.tokenService = tokenService;
this.kakaoApiService = kakaoApiService;
this.kakaoTokenService = kakaoTokenService;
this.pointRepository = pointRepository;
this.redisTemplate = redisTemplate;
this.callbackService = callbackService;
this.helloCallService = helloCallService;
this.pointRepository = pointRepository;
this.pointLogRepository = pointLogRepository;
}

public LoginResponse kakaoLogin(String authorizationCode, HttpServletRequest httpServletRequest) {
Expand Down Expand Up @@ -74,7 +80,8 @@ public RegisterResponse registerNewMember(String name, String phoneNumber, Strin
Member newMember = new Member(name, phoneNumber, email, isSinitto);
memberRepository.save(newMember);

pointRepository.save(new Point(0, newMember));
pointRepository.save(new Point(WELCOME_POINT, newMember));
pointLogRepository.save(new PointLog(PointLog.Content.WELCOME_POINT, newMember, WELCOME_POINT, PointLog.Status.EARN));

String accessToken = tokenService.generateAccessToken(email);
String refreshToken = tokenService.generateRefreshToken(email);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

public record PointLogResponse(
LocalDateTime postTime,
String content,
PointLog.Content content,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

int price,
PointLog.Status status
) {
Expand Down
12 changes: 7 additions & 5 deletions src/main/java/com/example/sinitto/point/entity/PointLog.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@
@EntityListeners(AuditingEntityListener.class)
public class PointLog {

public static final double WITHDRAWAL_FEE_RATE = 0.8;
private static final double WITHDRAWAL_FEE_RATE = 0.8;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotNull
private String content;
@Enumerated(EnumType.STRING)
private PointLog.Content content;
@NotNull
private int price;
@CreatedDate
Expand All @@ -36,7 +37,7 @@ public class PointLog {
private Member member;


public PointLog(String content, Member member, int price, Status status) {
public PointLog(Content content, Member member, int price, Status status) {
this.content = content;
this.member = member;
this.price = price;
Expand Down Expand Up @@ -120,7 +121,7 @@ public Status getStatus() {
return status;
}

public String getContent() {
public Content getContent() {
return content;
}

Expand All @@ -145,7 +146,8 @@ public enum Content {
SPEND_COMPLETE_HELLO_CALL("안부전화 신청"),
SPEND_CANCEL_HELLO_CALL("안부전화 신청 취소"),
CHARGE_REQUEST("포인트 충전"),
WITHDRAW_REQUEST("포인트 출금");
WITHDRAW_REQUEST("포인트 출금"),
WELCOME_POINT("환영 포인트");

private final String message;

Expand Down
16 changes: 11 additions & 5 deletions src/main/java/com/example/sinitto/point/service/PointService.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
@Service
public class PointService {

private static final int MINIMUM_WITHDRAW_POINT = 5000;

private final MemberRepository memberRepository;
private final PointRepository pointRepository;
private final PointLogRepository pointLogRepository;
Expand Down Expand Up @@ -80,7 +82,7 @@ public PointChargeResponse savePointChargeRequest(Long memberId, int price) {
throw new ConflictException("이미 진행중인 포인트 충전 요청이 존재합니다.");
}

pointLogRepository.save(new PointLog(PointLog.Content.CHARGE_REQUEST.getMessage(), member, price, PointLog.Status.CHARGE_REQUEST));
pointLogRepository.save(new PointLog(PointLog.Content.CHARGE_REQUEST, member, price, PointLog.Status.CHARGE_REQUEST));

kakaoMessageService.sendPointChargeRequestReceivedMessage(member.getEmail(), price, member.getName(), member.getDepositMessage());

Expand All @@ -94,6 +96,10 @@ public PointChargeResponse savePointChargeRequest(Long memberId, int price) {
@Transactional
public void savePointWithdrawRequest(Long memberId, int price) {

if (price < MINIMUM_WITHDRAW_POINT) {
throw new BadRequestException(String.format("출금시 최소 %d 이상 요청하셔야합니다.", MINIMUM_WITHDRAW_POINT));
}

Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new NotFoundException("요청한 멤버를 찾을 수 없습니다"));

Expand All @@ -118,7 +124,7 @@ public void savePointWithdrawRequest(Long memberId, int price) {

point.deduct(price);

pointLogRepository.save(new PointLog(PointLog.Content.WITHDRAW_REQUEST.getMessage(), member, price, PointLog.Status.WITHDRAW_REQUEST));
pointLogRepository.save(new PointLog(PointLog.Content.WITHDRAW_REQUEST, member, price, PointLog.Status.WITHDRAW_REQUEST));

SinittoBankInfo sinittoBankInfo = sinittoBankInfoRepository.findByMemberId(memberId).orElseThrow(() -> new NotFoundException("시니또의 은행 계좌 정보가 없습니다."));
kakaoMessageService.sendPointWithdrawRequestReceivedMessage(member.getEmail(), price, member.getName(), sinittoBankInfo.getBankName(), sinittoBankInfo.getAccountNumber());
Expand All @@ -139,7 +145,7 @@ public void earnPoint(Long memberId, int price, PointLog.Content contentForPoint

pointLogRepository.save(
new PointLog(
contentForPointLog.getMessage(),
contentForPointLog,
point.getMember(),
price,
PointLog.Status.EARN)
Expand All @@ -160,7 +166,7 @@ public void deductPoint(Long memberId, int price, PointLog.Content contentForPoi

pointLogRepository.save(
new PointLog(
contentForPointLog.getMessage(),
contentForPointLog,
point.getMember(),
price,
PointLog.Status.SPEND_COMPLETE
Expand All @@ -181,7 +187,7 @@ public void refundPointByDelete(Long memberId, int price, PointLog.Content conte

pointLogRepository.save(
new PointLog(
contentForPointLog.getMessage(),
contentForPointLog,
point.getMember(),
price,
PointLog.Status.SPEND_CANCEL
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import com.example.sinitto.member.dto.RegisterResponse;
import com.example.sinitto.member.entity.Member;
import com.example.sinitto.member.repository.MemberRepository;
import com.example.sinitto.point.entity.Point;
import com.example.sinitto.point.repository.PointLogRepository;
import com.example.sinitto.point.repository.PointRepository;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
Expand All @@ -30,8 +30,6 @@ public class MemberServiceTest {
@Mock
MemberRepository memberRepository;
@Mock
PointRepository pointRepository;
@Mock
TokenService tokenService;
@Mock
RedisTemplate<String, Object> redisTemplate;
Expand All @@ -45,6 +43,10 @@ public class MemberServiceTest {
CallbackService callbackService;
@Mock
HelloCallService helloCallService;
@Mock
PointRepository pointRepository;
@Mock
PointLogRepository pointLogRepository;

@Test
@DisplayName("registerNewMember 메소드 테스트")
Expand All @@ -62,7 +64,8 @@ void registerNewMemberTest() {

//then
verify(memberRepository, times(1)).save(any(Member.class));
verify(pointRepository, times(1)).save(any(Point.class));
verify(pointRepository, times(1)).save(any());
verify(pointLogRepository, times(1)).save(any());
assertEquals(isSinitto, result.isSinitto());
}

Expand Down
24 changes: 12 additions & 12 deletions src/test/java/com/example/sinitto/point/entity/PointLogTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class PointLogTest {
@DisplayName("포인트 로그 ChargeWaiting 상태로 전환 성공")
void changeStatusToChargeWaiting() {
//given
PointLog pointLog = new PointLog("content", member, 1000, PointLog.Status.CHARGE_REQUEST);
PointLog pointLog = new PointLog(PointLog.Content.CHARGE_REQUEST, member, 1000, PointLog.Status.CHARGE_REQUEST);

//when
pointLog.changeStatusToChargeWaiting();
Expand All @@ -34,7 +34,7 @@ void changeStatusToChargeWaiting() {
void changeStatusToChargeWaiting_fail(String initialStatus) {
//given
PointLog.Status status = PointLog.Status.valueOf(initialStatus);
PointLog pointLog = new PointLog("content", member, 1000, status);
PointLog pointLog = new PointLog(PointLog.Content.CHARGE_REQUEST, member, 1000, status);

//when then
assertThrows(ConflictException.class, pointLog::changeStatusToChargeWaiting);
Expand All @@ -44,7 +44,7 @@ void changeStatusToChargeWaiting_fail(String initialStatus) {
@DisplayName("포인트 로그 ChargeComplete 상태로 전환 성공")
void changeStatusToChargeComplete() {
//given
PointLog pointLog = new PointLog("content", member, 1000, PointLog.Status.CHARGE_WAITING);
PointLog pointLog = new PointLog(PointLog.Content.CHARGE_REQUEST, member, 1000, PointLog.Status.CHARGE_WAITING);

//when
pointLog.changeStatusToChargeComplete();
Expand All @@ -59,7 +59,7 @@ void changeStatusToChargeComplete() {
void changeStatusToChargeComplete_fail(String initialStatus) {
//given
PointLog.Status status = PointLog.Status.valueOf(initialStatus);
PointLog pointLog = new PointLog("content", member, 1000, status);
PointLog pointLog = new PointLog(PointLog.Content.CHARGE_REQUEST, member, 1000, status);

//when then
assertThrows(ConflictException.class, pointLog::changeStatusToChargeComplete);
Expand All @@ -69,7 +69,7 @@ void changeStatusToChargeComplete_fail(String initialStatus) {
@DisplayName("포인트 로그 ChargeFail 상태로 전환 성공")
void changeStatusToChargeFail() {
//given
PointLog pointLog = new PointLog("content", member, 1000, PointLog.Status.CHARGE_WAITING);
PointLog pointLog = new PointLog(PointLog.Content.CHARGE_REQUEST, member, 1000, PointLog.Status.CHARGE_WAITING);

//when
pointLog.changeStatusToChargeFail();
Expand All @@ -84,7 +84,7 @@ void changeStatusToChargeFail() {
void changeStatusToChargeFail_fail(String initialStatus) {
//given
PointLog.Status status = PointLog.Status.valueOf(initialStatus);
PointLog pointLog = new PointLog("content", member, 1000, status);
PointLog pointLog = new PointLog(PointLog.Content.CHARGE_REQUEST, member, 1000, status);

//when then
assertThrows(ConflictException.class, pointLog::changeStatusToChargeFail);
Expand All @@ -94,7 +94,7 @@ void changeStatusToChargeFail_fail(String initialStatus) {
@DisplayName("포인트 로그 WithdrawWaiting 상태로 전환 성공")
void changeStatusToWithdrawWaiting() {
//given
PointLog pointLog = new PointLog("content", member, 1000, PointLog.Status.WITHDRAW_REQUEST);
PointLog pointLog = new PointLog(PointLog.Content.CHARGE_REQUEST, member, 1000, PointLog.Status.WITHDRAW_REQUEST);

//when
pointLog.changeStatusToWithdrawWaiting();
Expand All @@ -109,7 +109,7 @@ void changeStatusToWithdrawWaiting() {
void changeStatusToWithdrawWaiting_fail(String initialStatus) {
//given
PointLog.Status status = PointLog.Status.valueOf(initialStatus);
PointLog pointLog = new PointLog("content", member, 1000, status);
PointLog pointLog = new PointLog(PointLog.Content.CHARGE_REQUEST, member, 1000, status);

//when then
assertThrows(ConflictException.class, pointLog::changeStatusToWithdrawWaiting);
Expand All @@ -119,7 +119,7 @@ void changeStatusToWithdrawWaiting_fail(String initialStatus) {
@DisplayName("포인트 로그 WithdrawComplete 상태로 전환 성공")
void changeStatusToWithdrawComplete() {
//given
PointLog pointLog = new PointLog("content", member, 1000, PointLog.Status.WITHDRAW_WAITING);
PointLog pointLog = new PointLog(PointLog.Content.CHARGE_REQUEST, member, 1000, PointLog.Status.WITHDRAW_WAITING);

//when
pointLog.changeStatusToWithdrawComplete();
Expand All @@ -134,7 +134,7 @@ void changeStatusToWithdrawComplete() {
void changeStatusToWithdrawComplete_fail(String initialStatus) {
//given
PointLog.Status status = PointLog.Status.valueOf(initialStatus);
PointLog pointLog = new PointLog("content", member, 1000, status);
PointLog pointLog = new PointLog(PointLog.Content.CHARGE_REQUEST, member, 1000, status);

//when then
assertThrows(ConflictException.class, pointLog::changeStatusToWithdrawComplete);
Expand All @@ -144,7 +144,7 @@ void changeStatusToWithdrawComplete_fail(String initialStatus) {
@DisplayName("포인트 로그 WithdrawFail 상태로 전환 성공")
void changeStatusToWithdrawFail() {
//given
PointLog pointLog = new PointLog("content", member, 1000, PointLog.Status.WITHDRAW_WAITING);
PointLog pointLog = new PointLog(PointLog.Content.CHARGE_REQUEST, member, 1000, PointLog.Status.WITHDRAW_WAITING);

//when
pointLog.changeStatusToWithdrawFail();
Expand All @@ -159,7 +159,7 @@ void changeStatusToWithdrawFail() {
void changeStatusToWithdrawFail_fail(String initialStatus) {
//given
PointLog.Status status = PointLog.Status.valueOf(initialStatus);
PointLog pointLog = new PointLog("content", member, 1000, status);
PointLog pointLog = new PointLog(PointLog.Content.CHARGE_REQUEST, member, 1000, status);

//when then
assertThrows(ConflictException.class, pointLog::changeStatusToWithdrawFail);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class PointServiceTest {
@Mock
KakaoMessageService kakaoMessageService;
@Mock
private SlackMessageService slackMessageService;
SlackMessageService slackMessageService;

@Nested
@DisplayName("포인트 조회 테스트")
Expand Down Expand Up @@ -108,7 +108,7 @@ void getPointLogs1() {
when(memberRepository.findById(1L)).thenReturn(Optional.of(member));

PointLog pointLog = mock(PointLog.class);
when(pointLog.getContent()).thenReturn("content");
when(pointLog.getContent()).thenReturn(PointLog.Content.WELCOME_POINT);
when(pointLog.getPrice()).thenReturn(10000);
when(pointLog.getStatus()).thenReturn(PointLog.Status.EARN);

Expand Down Expand Up @@ -247,6 +247,16 @@ void savePointWithdrawRequest4() {
//when then
assertThrows(BadRequestException.class, () -> pointService.savePointWithdrawRequest(1L, 10000));
}

@Test
@DisplayName("최소 출금 포인트보다 모자라면 예외를 발생시켜야한다.")
void savePointWithdrawRequest5() {
//given
int withdrawPoint = 4999;

//when then
assertThrows(BadRequestException.class, () -> pointService.savePointWithdrawRequest(1L, withdrawPoint));
}
}

@Nested
Expand Down