라이브 - 시작, 취소, 입장, 수정, 예약 API 추가

This commit is contained in:
2023-07-31 17:09:45 +09:00
parent 197cca1f1b
commit f393c7630e
29 changed files with 1044 additions and 19 deletions

View File

@@ -0,0 +1,245 @@
package kr.co.vividnext.sodalive.can.payment
import kr.co.vividnext.sodalive.can.charge.ChargeRepository
import kr.co.vividnext.sodalive.can.use.CanUsage
import kr.co.vividnext.sodalive.can.use.SpentCan
import kr.co.vividnext.sodalive.can.use.TotalSpentCan
import kr.co.vividnext.sodalive.can.use.UseCan
import kr.co.vividnext.sodalive.can.use.UseCanCalculate
import kr.co.vividnext.sodalive.can.use.UseCanCalculateRepository
import kr.co.vividnext.sodalive.can.use.UseCanCalculateStatus
import kr.co.vividnext.sodalive.can.use.UseCanRepository
import kr.co.vividnext.sodalive.common.SodaException
import kr.co.vividnext.sodalive.live.room.LiveRoom
import kr.co.vividnext.sodalive.member.MemberRepository
import org.springframework.data.repository.findByIdOrNull
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
@Service
class CanPaymentService(
private val memberRepository: MemberRepository,
private val chargeRepository: ChargeRepository,
private val useCanRepository: UseCanRepository,
private val useCanCalculateRepository: UseCanCalculateRepository
) {
@Transactional
fun spendCan(
memberId: Long,
needCan: Int,
canUsage: CanUsage,
liveRoom: LiveRoom? = null,
container: String
) {
val member = memberRepository.findByIdOrNull(id = memberId)
?: throw SodaException("잘못된 요청입니다.\n다시 시도해 주세요.")
val useRewardCan = spendRewardCan(memberId, needCan, container)
val useChargeCan = if (needCan - useRewardCan.total > 0) {
spendChargeCan(memberId, needCan = needCan - useRewardCan.total, container = container)
} else {
null
}
if (needCan - useRewardCan.total - (useChargeCan?.total ?: 0) > 0) {
throw SodaException(
"${needCan - useRewardCan.total - (useChargeCan?.total ?: 0)} " +
"캔이 부족합니다. 충전 후 이용해 주세요."
)
}
if (!useRewardCan.verify() || useChargeCan?.verify() == false) {
throw SodaException("잘못된 요청입니다.\n다시 시도해 주세요.")
}
val useCan = UseCan(
canUsage = canUsage,
can = useChargeCan?.total ?: 0,
rewardCan = useRewardCan.total
)
var recipientId: Long? = null
if (canUsage == CanUsage.LIVE && liveRoom != null) {
recipientId = liveRoom.member!!.id!!
useCan.room = liveRoom
useCan.member = member
} else if (canUsage == CanUsage.CHANGE_NICKNAME) {
useCan.member = member
} else if (canUsage == CanUsage.DONATION && liveRoom != null) {
recipientId = liveRoom.member!!.id!!
useCan.room = liveRoom
useCan.member = member
} else {
throw SodaException("잘못된 요청입니다.")
}
useCanRepository.save(useCan)
setUseCoinCalculate(recipientId, useRewardCan, useChargeCan, useCan, paymentGateway = PaymentGateway.PG)
setUseCoinCalculate(
recipientId,
useRewardCan,
useChargeCan,
useCan,
paymentGateway = PaymentGateway.GOOGLE_IAP
)
setUseCoinCalculate(
recipientId,
useRewardCan,
useChargeCan,
useCan,
paymentGateway = PaymentGateway.APPLE_IAP
)
}
private fun setUseCoinCalculate(
recipientId: Long?,
useRewardCan: TotalSpentCan,
useChargeCan: TotalSpentCan?,
useCan: UseCan,
paymentGateway: PaymentGateway
) {
val totalSpentRewardCan = useRewardCan.spentCans
.filter { it.paymentGateway == paymentGateway }
.fold(0) { sum, spentCans -> sum + spentCans.can }
val useCanCalculate = if (useChargeCan != null) {
val totalSpentChargeCan = useChargeCan.spentCans
.filter { it.paymentGateway == paymentGateway }
.fold(0) { sum, spentCans -> sum + spentCans.can }
UseCanCalculate(
can = totalSpentChargeCan + totalSpentRewardCan,
paymentGateway = paymentGateway,
status = UseCanCalculateStatus.RECEIVED
)
} else {
UseCanCalculate(
can = totalSpentRewardCan,
paymentGateway = paymentGateway,
status = UseCanCalculateStatus.RECEIVED
)
}
if (useCanCalculate.can > 0) {
useCanCalculate.useCan = useCan
useCanCalculate.recipientCreatorId = recipientId
useCanCalculateRepository.save(useCanCalculate)
}
}
private fun spendRewardCan(memberId: Long, needCan: Int, container: String): TotalSpentCan {
return if (needCan > 0) {
val member = memberRepository.findByIdOrNull(id = memberId)
?: throw SodaException("잘못된 요청입니다.\n다시 시도해 주세요.")
val spentCans = mutableListOf<SpentCan>()
var chargeId = 0L
var total = 0
while (needCan - total > 0) {
val remainingNeedCan = needCan - total
val charge = chargeRepository.getOldestChargeWhereRewardCanGreaterThan0(chargeId, memberId, container)
?: break
if (charge.rewardCan >= remainingNeedCan) {
charge.rewardCan -= remainingNeedCan
when (charge.payment!!.paymentGateway) {
PaymentGateway.PG -> member.pgRewardCan -= remainingNeedCan
PaymentGateway.APPLE_IAP -> member.appleRewardCan -= remainingNeedCan
PaymentGateway.GOOGLE_IAP -> member.pgRewardCan -= remainingNeedCan
}
total += remainingNeedCan
spentCans.add(
SpentCan(
paymentGateway = charge.payment!!.paymentGateway,
can = remainingNeedCan
)
)
} else {
total += charge.rewardCan
spentCans.add(
SpentCan(
paymentGateway = charge.payment!!.paymentGateway,
can = charge.rewardCan
)
)
when (charge.payment!!.paymentGateway) {
PaymentGateway.PG -> member.pgRewardCan -= remainingNeedCan
PaymentGateway.APPLE_IAP -> member.appleRewardCan -= remainingNeedCan
PaymentGateway.GOOGLE_IAP -> member.pgRewardCan -= remainingNeedCan
}
charge.rewardCan = 0
}
chargeId = charge.id!!
}
TotalSpentCan(spentCans, total)
} else {
TotalSpentCan(total = 0)
}
}
private fun spendChargeCan(memberId: Long, needCan: Int, container: String): TotalSpentCan {
return if (needCan > 0) {
val member = memberRepository.findByIdOrNull(id = memberId)
?: throw SodaException("잘못된 요청입니다.\n다시 시도해 주세요.")
val spentCans = mutableListOf<SpentCan>()
var chargeId = 0L
var total = 0
while (needCan - total > 0) {
val remainingNeedCan = needCan - total
val charge = chargeRepository.getOldestChargeWhereChargeCanGreaterThan0(chargeId, memberId, container)
?: break
if (charge.rewardCan >= remainingNeedCan) {
charge.rewardCan -= remainingNeedCan
when (charge.payment!!.paymentGateway) {
PaymentGateway.PG -> member.pgRewardCan -= remainingNeedCan
PaymentGateway.APPLE_IAP -> member.appleRewardCan -= remainingNeedCan
PaymentGateway.GOOGLE_IAP -> member.pgRewardCan -= remainingNeedCan
}
total += remainingNeedCan
spentCans.add(
SpentCan(
paymentGateway = charge.payment!!.paymentGateway,
can = remainingNeedCan
)
)
} else {
total += charge.rewardCan
spentCans.add(
SpentCan(
paymentGateway = charge.payment!!.paymentGateway,
can = charge.rewardCan
)
)
when (charge.payment!!.paymentGateway) {
PaymentGateway.PG -> member.pgRewardCan -= remainingNeedCan
PaymentGateway.APPLE_IAP -> member.appleRewardCan -= remainingNeedCan
PaymentGateway.GOOGLE_IAP -> member.pgRewardCan -= remainingNeedCan
}
charge.rewardCan = 0
}
chargeId = charge.id!!
}
TotalSpentCan(spentCans, total)
} else {
TotalSpentCan(total = 0)
}
}
}