feat: 포인트 사용 로직 구현 (만료일 순 + 10포인트 단위 차감)
This commit is contained in:
parent
e2c70de2e0
commit
51dae0f02c
|
@ -10,6 +10,7 @@ import kr.co.vividnext.sodalive.content.comment.AudioContentCommentRepository
|
||||||
import kr.co.vividnext.sodalive.content.like.AudioContentLikeRepository
|
import kr.co.vividnext.sodalive.content.like.AudioContentLikeRepository
|
||||||
import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
|
import kr.co.vividnext.sodalive.content.main.GetAudioContentMainItem
|
||||||
import kr.co.vividnext.sodalive.member.Member
|
import kr.co.vividnext.sodalive.member.Member
|
||||||
|
import kr.co.vividnext.sodalive.point.PointUsageService
|
||||||
import org.springframework.beans.factory.annotation.Value
|
import org.springframework.beans.factory.annotation.Value
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import org.springframework.transaction.annotation.Transactional
|
import org.springframework.transaction.annotation.Transactional
|
||||||
|
@ -19,6 +20,7 @@ import java.time.LocalDateTime
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
class OrderService(
|
class OrderService(
|
||||||
private val repository: OrderRepository,
|
private val repository: OrderRepository,
|
||||||
|
private val pointUsageService: PointUsageService,
|
||||||
private val canPaymentService: CanPaymentService,
|
private val canPaymentService: CanPaymentService,
|
||||||
private val audioContentRepository: AudioContentRepository,
|
private val audioContentRepository: AudioContentRepository,
|
||||||
private val audioContentCommentQueryRepository: AudioContentCommentRepository,
|
private val audioContentCommentQueryRepository: AudioContentCommentRepository,
|
||||||
|
@ -41,9 +43,16 @@ class OrderService(
|
||||||
orderContent(orderType, content, member)
|
orderContent(orderType, content, member)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val usedPoint = if (order.type == OrderType.RENTAL) {
|
||||||
|
pointUsageService.usePoint(member.id!!, order.can)
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
order.point = usedPoint
|
||||||
|
|
||||||
canPaymentService.spendCan(
|
canPaymentService.spendCan(
|
||||||
memberId = member.id!!,
|
memberId = member.id!!,
|
||||||
needCan = order.can,
|
needCan = order.can - (usedPoint / 10),
|
||||||
canUsage = CanUsage.ORDER_CONTENT,
|
canUsage = CanUsage.ORDER_CONTENT,
|
||||||
order = order,
|
order = order,
|
||||||
container = container
|
container = container
|
||||||
|
|
|
@ -1,5 +1,29 @@
|
||||||
package kr.co.vividnext.sodalive.point
|
package kr.co.vividnext.sodalive.point
|
||||||
|
|
||||||
|
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||||
|
import kr.co.vividnext.sodalive.point.QMemberPoint.memberPoint
|
||||||
import org.springframework.data.jpa.repository.JpaRepository
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
interface MemberPointRepository : JpaRepository<MemberPoint, Long>
|
interface MemberPointRepository : JpaRepository<MemberPoint, Long>, MemberPointQueryRepository
|
||||||
|
|
||||||
|
interface MemberPointQueryRepository {
|
||||||
|
fun findByMemberIdAndExpiresAtAfterOrderByExpiresAtAsc(memberId: Long, expiresAt: LocalDateTime): List<MemberPoint>
|
||||||
|
}
|
||||||
|
|
||||||
|
class MemberPointQueryRepositoryImpl(
|
||||||
|
private val queryFactory: JPAQueryFactory
|
||||||
|
) : MemberPointQueryRepository {
|
||||||
|
override fun findByMemberIdAndExpiresAtAfterOrderByExpiresAtAsc(
|
||||||
|
memberId: Long,
|
||||||
|
expiresAt: LocalDateTime
|
||||||
|
): List<MemberPoint> {
|
||||||
|
return queryFactory
|
||||||
|
.selectFrom(memberPoint)
|
||||||
|
.where(
|
||||||
|
memberPoint.memberId.eq(memberId),
|
||||||
|
memberPoint.expiresAt.goe(expiresAt)
|
||||||
|
)
|
||||||
|
.fetch()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package kr.co.vividnext.sodalive.point
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class PointUsageService(
|
||||||
|
private val memberPointRepository: MemberPointRepository,
|
||||||
|
private val usePointRepository: UsePointRepository
|
||||||
|
) {
|
||||||
|
fun usePoint(memberId: Long, contentPrice: Int): Int {
|
||||||
|
val now = LocalDateTime.now()
|
||||||
|
val maxUsablePoint = contentPrice * 10
|
||||||
|
|
||||||
|
val points = memberPointRepository.findByMemberIdAndExpiresAtAfterOrderByExpiresAtAsc(
|
||||||
|
memberId = memberId,
|
||||||
|
expiresAt = now
|
||||||
|
)
|
||||||
|
|
||||||
|
val totalAvailable = points.sumOf { it.point }
|
||||||
|
val usablePoint = minOf(totalAvailable, maxUsablePoint).floorToNearest10()
|
||||||
|
|
||||||
|
var remaining = usablePoint
|
||||||
|
var used = 0
|
||||||
|
|
||||||
|
for (p in points) {
|
||||||
|
if (remaining <= 0) break
|
||||||
|
val usable = minOf(p.point, remaining)
|
||||||
|
p.point -= usable
|
||||||
|
remaining -= usable
|
||||||
|
used += usable
|
||||||
|
}
|
||||||
|
|
||||||
|
if (used > 0) {
|
||||||
|
memberPointRepository.saveAll(points)
|
||||||
|
usePointRepository.save(UsePoint(memberId = memberId, amount = used))
|
||||||
|
}
|
||||||
|
|
||||||
|
return used
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Int.floorToNearest10(): Int = (this / 10) * 10
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package kr.co.vividnext.sodalive.point
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository
|
||||||
|
|
||||||
|
interface UsePointRepository : JpaRepository<UsePoint, Long>
|
Loading…
Reference in New Issue