feat: 포인트 사용 로직 구현 (만료일 순 + 10포인트 단위 차감)
This commit is contained in:
@@ -1,5 +1,29 @@
|
||||
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 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>
|
Reference in New Issue
Block a user