diff --git a/src/main/java/org/festimate/team/api/facade/PointFacade.java b/src/main/java/org/festimate/team/api/facade/PointFacade.java index d6d5f33..65da378 100644 --- a/src/main/java/org/festimate/team/api/facade/PointFacade.java +++ b/src/main/java/org/festimate/team/api/facade/PointFacade.java @@ -7,6 +7,7 @@ import org.festimate.team.domain.festival.service.FestivalService; import org.festimate.team.domain.participant.entity.Participant; import org.festimate.team.domain.participant.service.ParticipantService; +import org.festimate.team.domain.point.entity.TransactionType; import org.festimate.team.domain.point.service.PointService; import org.festimate.team.domain.user.entity.User; import org.festimate.team.domain.user.service.UserService; @@ -51,7 +52,12 @@ public void rechargePoints(Long userId, Long festivalId, RechargePointRequest re if (participant.getFestival() != festival) { throw new FestimateException(ResponseError.FORBIDDEN_RESOURCE); } - pointService.rechargePoint(participant, request.point()); + + if(request.type().equals(TransactionType.CREDIT)) { + pointService.rechargePoint(participant, request.point()); + }else if (request.type().equals(TransactionType.DEBIT)) { + pointService.dischargePoint(participant, request.point()); + } } private void isHost(User user, Festival festival) { diff --git a/src/main/java/org/festimate/team/api/point/dto/RechargePointRequest.java b/src/main/java/org/festimate/team/api/point/dto/RechargePointRequest.java index 5290a5b..a97e11e 100644 --- a/src/main/java/org/festimate/team/api/point/dto/RechargePointRequest.java +++ b/src/main/java/org/festimate/team/api/point/dto/RechargePointRequest.java @@ -1,6 +1,9 @@ package org.festimate.team.api.point.dto; +import org.festimate.team.domain.point.entity.TransactionType; + public record RechargePointRequest( + TransactionType type, long participantId, int point ) { diff --git a/src/main/java/org/festimate/team/domain/point/service/PointService.java b/src/main/java/org/festimate/team/domain/point/service/PointService.java index c84fbf3..cf6246e 100644 --- a/src/main/java/org/festimate/team/domain/point/service/PointService.java +++ b/src/main/java/org/festimate/team/domain/point/service/PointService.java @@ -14,4 +14,8 @@ public interface PointService { @Transactional void rechargePoint(Participant participant, int amount); + + @Transactional + void dischargePoint(Participant participant, int amount); + } diff --git a/src/main/java/org/festimate/team/domain/point/service/impl/PointServiceImpl.java b/src/main/java/org/festimate/team/domain/point/service/impl/PointServiceImpl.java index a44bec9..ed88662 100644 --- a/src/main/java/org/festimate/team/domain/point/service/impl/PointServiceImpl.java +++ b/src/main/java/org/festimate/team/domain/point/service/impl/PointServiceImpl.java @@ -4,13 +4,13 @@ import lombok.extern.slf4j.Slf4j; import org.festimate.team.api.point.dto.PointHistory; import org.festimate.team.api.point.dto.PointHistoryResponse; +import org.festimate.team.domain.participant.entity.Participant; import org.festimate.team.domain.point.entity.Point; import org.festimate.team.domain.point.entity.TransactionType; import org.festimate.team.domain.point.repository.PointRepository; import org.festimate.team.domain.point.service.PointService; -import org.festimate.team.global.response.ResponseError; import org.festimate.team.global.exception.FestimateException; -import org.festimate.team.domain.participant.entity.Participant; +import org.festimate.team.global.response.ResponseError; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -54,6 +54,17 @@ public void rechargePoint(Participant participant, int amount) { pointRepository.save(pointUsage); } + @Transactional + @Override + public void dischargePoint(Participant participant, int amount) { + int totalPoint = getTotalPointByParticipant(participant); + if (totalPoint < amount) { + throw new FestimateException(ResponseError.INSUFFICIENT_POINTS); + } + Point pointUsage = createPointTransaction(participant, amount, TransactionType.DEBIT); + pointRepository.save(pointUsage); + } + private Point createPointTransaction(Participant participant, int amount, TransactionType type) { return Point.builder() .participant(participant) diff --git a/src/test/java/org/festimate/team/api/facade/PointFacadeTest.java b/src/test/java/org/festimate/team/api/facade/PointFacadeTest.java index 165e1c3..27e32a4 100644 --- a/src/test/java/org/festimate/team/api/facade/PointFacadeTest.java +++ b/src/test/java/org/festimate/team/api/facade/PointFacadeTest.java @@ -7,6 +7,7 @@ import org.festimate.team.domain.festival.service.FestivalService; import org.festimate.team.domain.participant.entity.Participant; import org.festimate.team.domain.participant.service.ParticipantService; +import org.festimate.team.domain.point.entity.TransactionType; import org.festimate.team.domain.point.service.PointService; import org.festimate.team.domain.user.entity.Gender; import org.festimate.team.domain.user.entity.User; @@ -97,7 +98,7 @@ void getParticipantPointHistory_success() { @DisplayName("포인트 충전 성공 (호스트 권한)") void rechargePoints_success() { // given - RechargePointRequest request = new RechargePointRequest(200L, 5); + RechargePointRequest request = new RechargePointRequest(TransactionType.CREDIT, 200L, 5); when(userService.getUserByIdOrThrow(1L)).thenReturn(host); when(festivalService.getFestivalByIdOrThrow(100L)).thenReturn(festival); @@ -115,7 +116,7 @@ void rechargePoints_success() { @DisplayName("포인트 충전 실패 - 호스트가 아님") void rechargePoints_notHost_throws() { User attacker = MockFactory.mockUser("악당", Gender.MAN, 999L); - RechargePointRequest request = new RechargePointRequest(200L, 5); + RechargePointRequest request = new RechargePointRequest(TransactionType.CREDIT, 200L, 5); when(userService.getUserByIdOrThrow(999L)).thenReturn(attacker); when(festivalService.getFestivalByIdOrThrow(100L)).thenReturn(festival); @@ -133,7 +134,7 @@ void rechargePoints_participantMismatch_throws() { Festival otherFestival = MockFactory.mockFestival(host, 999L, LocalDate.now(), LocalDate.now().plusDays(1)); Participant otherParticipant = MockFactory.mockParticipant(participantUser, otherFestival, null, 300L); - RechargePointRequest request = new RechargePointRequest(300L, 5); + RechargePointRequest request = new RechargePointRequest(TransactionType.CREDIT, 300L, 5); when(userService.getUserByIdOrThrow(1L)).thenReturn(host); when(festivalService.getFestivalByIdOrThrow(100L)).thenReturn(festival);