feat(agent-calculate): 에이전트별 정산 조회 기능을 추가한다
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
package kr.co.vividnext.sodalive.partner.agent.calculate
|
||||
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RequestParam
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RestController
|
||||
@PreAuthorize("hasRole('AGENT')")
|
||||
@RequestMapping("/agent/calculate")
|
||||
class AgentCalculateController(private val service: AgentCalculateService) {
|
||||
@GetMapping("/creator/list")
|
||||
fun getAssignedCreators(
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
val agent = member ?: throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
ApiResponse.ok(
|
||||
service.getAssignedCreators(
|
||||
agentId = agent.id!!,
|
||||
offset = pageable.offset,
|
||||
limit = pageable.pageSize.toLong()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@GetMapping("/live-by-creator")
|
||||
fun getCalculateLiveByCreator(
|
||||
@RequestParam startDateStr: String,
|
||||
@RequestParam endDateStr: String,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
val agent = member ?: throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
ApiResponse.ok(
|
||||
service.getCalculateLiveByCreator(
|
||||
startDateStr = startDateStr,
|
||||
endDateStr = endDateStr,
|
||||
agentId = agent.id!!,
|
||||
offset = pageable.offset,
|
||||
limit = pageable.pageSize.toLong()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@GetMapping("/content-by-creator")
|
||||
fun getCalculateContentByCreator(
|
||||
@RequestParam startDateStr: String,
|
||||
@RequestParam endDateStr: String,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
val agent = member ?: throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
ApiResponse.ok(
|
||||
service.getCalculateContentByCreator(
|
||||
startDateStr = startDateStr,
|
||||
endDateStr = endDateStr,
|
||||
agentId = agent.id!!,
|
||||
offset = pageable.offset,
|
||||
limit = pageable.pageSize.toLong()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@GetMapping("/community-by-creator")
|
||||
fun getCalculateCommunityByCreator(
|
||||
@RequestParam startDateStr: String,
|
||||
@RequestParam endDateStr: String,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
val agent = member ?: throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
ApiResponse.ok(
|
||||
service.getCalculateCommunityByCreator(
|
||||
startDateStr = startDateStr,
|
||||
endDateStr = endDateStr,
|
||||
agentId = agent.id!!,
|
||||
offset = pageable.offset,
|
||||
limit = pageable.pageSize.toLong()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@GetMapping("/channel-donation-by-creator")
|
||||
fun getChannelDonationByCreator(
|
||||
@RequestParam startDateStr: String,
|
||||
@RequestParam endDateStr: String,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
val agent = member ?: throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
ApiResponse.ok(
|
||||
service.getChannelDonationByCreator(
|
||||
startDateStr = startDateStr,
|
||||
endDateStr = endDateStr,
|
||||
agentId = agent.id!!,
|
||||
offset = pageable.offset,
|
||||
limit = pageable.pageSize.toLong()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@GetMapping("/content-donation-by-creator")
|
||||
fun getCalculateContentDonationByCreator(
|
||||
@RequestParam startDateStr: String,
|
||||
@RequestParam endDateStr: String,
|
||||
@AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?,
|
||||
pageable: Pageable
|
||||
) = run {
|
||||
val agent = member ?: throw SodaException(messageKey = "common.error.bad_credentials")
|
||||
ApiResponse.ok(
|
||||
service.getCalculateContentDonationByCreator(
|
||||
startDateStr = startDateStr,
|
||||
endDateStr = endDateStr,
|
||||
agentId = agent.id!!,
|
||||
offset = pageable.offset,
|
||||
limit = pageable.pageSize.toLong()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,666 @@
|
||||
package kr.co.vividnext.sodalive.partner.agent.calculate
|
||||
|
||||
import com.querydsl.core.types.dsl.DateTimeExpression
|
||||
import com.querydsl.core.types.dsl.Expressions
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||
import kr.co.vividnext.sodalive.admin.calculate.ratio.QCreatorSettlementRatio.creatorSettlementRatio
|
||||
import kr.co.vividnext.sodalive.can.use.CanUsage
|
||||
import kr.co.vividnext.sodalive.can.use.QUseCan.useCan
|
||||
import kr.co.vividnext.sodalive.can.use.QUseCanCalculate.useCanCalculate
|
||||
import kr.co.vividnext.sodalive.can.use.UseCanCalculateStatus
|
||||
import kr.co.vividnext.sodalive.content.QAudioContent.audioContent
|
||||
import kr.co.vividnext.sodalive.content.order.QOrder.order
|
||||
import kr.co.vividnext.sodalive.explorer.profile.creatorCommunity.QCreatorCommunity.creatorCommunity
|
||||
import kr.co.vividnext.sodalive.live.room.QLiveRoom.liveRoom
|
||||
import kr.co.vividnext.sodalive.member.QMember.member
|
||||
import kr.co.vividnext.sodalive.partner.agent.assignment.QAgentCreatorRelation.agentCreatorRelation
|
||||
import kr.co.vividnext.sodalive.partner.agent.ratio.QAgentSettlementRatio.agentSettlementRatio
|
||||
import org.springframework.stereotype.Repository
|
||||
import java.time.LocalDateTime
|
||||
|
||||
@Repository
|
||||
class AgentCalculateQueryRepository(private val queryFactory: JPAQueryFactory) {
|
||||
fun getAssignedCreatorTotalCount(agentId: Long, currentTime: LocalDateTime): Int {
|
||||
return queryFactory
|
||||
.select(agentCreatorRelation.id.count())
|
||||
.from(agentCreatorRelation)
|
||||
.where(
|
||||
assignedToAgentAtCurrentTime(agentId = agentId, currentTime = currentTime)
|
||||
)
|
||||
.fetchOne()
|
||||
?.toInt()
|
||||
?: 0
|
||||
}
|
||||
|
||||
fun getAssignedCreators(
|
||||
agentId: Long,
|
||||
offset: Long,
|
||||
limit: Long,
|
||||
currentTime: LocalDateTime
|
||||
): List<GetAgentAssignedCreatorItem> {
|
||||
return queryFactory
|
||||
.select(
|
||||
QGetAgentAssignedCreatorItem(
|
||||
agentCreatorRelation.creator.id,
|
||||
agentCreatorRelation.creator.nickname
|
||||
)
|
||||
)
|
||||
.from(agentCreatorRelation)
|
||||
.where(
|
||||
assignedToAgentAtCurrentTime(agentId = agentId, currentTime = currentTime)
|
||||
)
|
||||
.orderBy(agentCreatorRelation.creator.id.desc())
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
.fetch()
|
||||
}
|
||||
|
||||
fun getCalculateLiveByCreatorTotalCount(startDate: LocalDateTime, endDate: LocalDateTime, agentId: Long): Int {
|
||||
return queryFactory
|
||||
.select(member.id.countDistinct())
|
||||
.from(useCan)
|
||||
.innerJoin(useCan.room, liveRoom)
|
||||
.innerJoin(liveRoom.member, member)
|
||||
.innerJoin(agentCreatorRelation)
|
||||
.on(
|
||||
agentCreatorRelation.creator.id.eq(member.id)
|
||||
.and(assignedToAgentAtEventTime(agentId, useCan.createdAt))
|
||||
)
|
||||
.where(
|
||||
useCan.isRefund.isFalse
|
||||
.and(useCan.createdAt.goe(startDate))
|
||||
.and(useCan.createdAt.loe(endDate))
|
||||
)
|
||||
.fetchOne()
|
||||
?.toInt()
|
||||
?: 0
|
||||
}
|
||||
|
||||
fun getCalculateLiveByCreator(
|
||||
startDate: LocalDateTime,
|
||||
endDate: LocalDateTime,
|
||||
agentId: Long
|
||||
): List<GetAgentCreatorSettlementSummaryQueryData> {
|
||||
return getCalculateLiveByCreatorRows(startDate, endDate, agentId, creatorIds = null)
|
||||
}
|
||||
|
||||
fun getCalculateLiveByCreator(
|
||||
startDate: LocalDateTime,
|
||||
endDate: LocalDateTime,
|
||||
agentId: Long,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): List<GetAgentCreatorSettlementSummaryQueryData> {
|
||||
val creatorIds = queryFactory
|
||||
.select(member.id)
|
||||
.from(useCan)
|
||||
.innerJoin(useCan.room, liveRoom)
|
||||
.innerJoin(liveRoom.member, member)
|
||||
.innerJoin(agentCreatorRelation)
|
||||
.on(
|
||||
agentCreatorRelation.creator.id.eq(member.id)
|
||||
.and(assignedToAgentAtEventTime(agentId, useCan.createdAt))
|
||||
)
|
||||
.where(
|
||||
useCan.isRefund.isFalse
|
||||
.and(useCan.createdAt.goe(startDate))
|
||||
.and(useCan.createdAt.loe(endDate))
|
||||
)
|
||||
.groupBy(member.id)
|
||||
.orderBy(member.id.desc())
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
.fetch()
|
||||
|
||||
if (creatorIds.isEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
return getCalculateLiveByCreatorRows(startDate, endDate, agentId, creatorIds)
|
||||
}
|
||||
|
||||
fun getCalculateContentByCreatorTotalCount(startDate: LocalDateTime, endDate: LocalDateTime, agentId: Long): Int {
|
||||
return queryFactory
|
||||
.select(member.id.countDistinct())
|
||||
.from(order)
|
||||
.innerJoin(order.audioContent, audioContent)
|
||||
.innerJoin(audioContent.member, member)
|
||||
.innerJoin(agentCreatorRelation)
|
||||
.on(
|
||||
agentCreatorRelation.creator.id.eq(member.id)
|
||||
.and(assignedToAgentAtEventTime(agentId, order.createdAt))
|
||||
)
|
||||
.where(
|
||||
order.createdAt.goe(startDate)
|
||||
.and(order.createdAt.loe(endDate))
|
||||
.and(order.isActive.isTrue)
|
||||
)
|
||||
.fetchOne()
|
||||
?.toInt()
|
||||
?: 0
|
||||
}
|
||||
|
||||
fun getCalculateContentByCreator(
|
||||
startDate: LocalDateTime,
|
||||
endDate: LocalDateTime,
|
||||
agentId: Long
|
||||
): List<GetAgentCreatorSettlementSummaryQueryData> {
|
||||
return getCalculateContentByCreatorRows(startDate, endDate, agentId, creatorIds = null)
|
||||
}
|
||||
|
||||
fun getCalculateContentByCreator(
|
||||
startDate: LocalDateTime,
|
||||
endDate: LocalDateTime,
|
||||
agentId: Long,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): List<GetAgentCreatorSettlementSummaryQueryData> {
|
||||
val creatorIds = queryFactory
|
||||
.select(member.id)
|
||||
.from(order)
|
||||
.innerJoin(order.audioContent, audioContent)
|
||||
.innerJoin(audioContent.member, member)
|
||||
.innerJoin(agentCreatorRelation)
|
||||
.on(
|
||||
agentCreatorRelation.creator.id.eq(member.id)
|
||||
.and(assignedToAgentAtEventTime(agentId, order.createdAt))
|
||||
)
|
||||
.where(
|
||||
order.createdAt.goe(startDate)
|
||||
.and(order.createdAt.loe(endDate))
|
||||
.and(order.isActive.isTrue)
|
||||
)
|
||||
.groupBy(member.id)
|
||||
.orderBy(member.id.desc())
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
.fetch()
|
||||
|
||||
if (creatorIds.isEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
return getCalculateContentByCreatorRows(startDate, endDate, agentId, creatorIds)
|
||||
}
|
||||
|
||||
fun getCalculateCommunityByCreatorTotalCount(startDate: LocalDateTime, endDate: LocalDateTime, agentId: Long): Int {
|
||||
return queryFactory
|
||||
.select(member.id.countDistinct())
|
||||
.from(useCan)
|
||||
.innerJoin(useCan.communityPost, creatorCommunity)
|
||||
.innerJoin(creatorCommunity.member, member)
|
||||
.innerJoin(agentCreatorRelation)
|
||||
.on(
|
||||
agentCreatorRelation.creator.id.eq(member.id)
|
||||
.and(assignedToAgentAtEventTime(agentId, useCan.createdAt))
|
||||
)
|
||||
.where(
|
||||
useCan.isRefund.isFalse
|
||||
.and(useCan.canUsage.eq(CanUsage.PAID_COMMUNITY_POST))
|
||||
.and(useCan.createdAt.goe(startDate))
|
||||
.and(useCan.createdAt.loe(endDate))
|
||||
)
|
||||
.fetchOne()
|
||||
?.toInt()
|
||||
?: 0
|
||||
}
|
||||
|
||||
fun getCalculateCommunityByCreator(
|
||||
startDate: LocalDateTime,
|
||||
endDate: LocalDateTime,
|
||||
agentId: Long
|
||||
): List<GetAgentCreatorSettlementSummaryQueryData> {
|
||||
return getCalculateCommunityByCreatorRows(startDate, endDate, agentId, creatorIds = null)
|
||||
}
|
||||
|
||||
fun getCalculateCommunityByCreator(
|
||||
startDate: LocalDateTime,
|
||||
endDate: LocalDateTime,
|
||||
agentId: Long,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): List<GetAgentCreatorSettlementSummaryQueryData> {
|
||||
val creatorIds = queryFactory
|
||||
.select(member.id)
|
||||
.from(useCan)
|
||||
.innerJoin(useCan.communityPost, creatorCommunity)
|
||||
.innerJoin(creatorCommunity.member, member)
|
||||
.innerJoin(agentCreatorRelation)
|
||||
.on(
|
||||
agentCreatorRelation.creator.id.eq(member.id)
|
||||
.and(assignedToAgentAtEventTime(agentId, useCan.createdAt))
|
||||
)
|
||||
.where(
|
||||
useCan.isRefund.isFalse
|
||||
.and(useCan.canUsage.eq(CanUsage.PAID_COMMUNITY_POST))
|
||||
.and(useCan.createdAt.goe(startDate))
|
||||
.and(useCan.createdAt.loe(endDate))
|
||||
)
|
||||
.groupBy(member.id)
|
||||
.orderBy(member.id.desc())
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
.fetch()
|
||||
|
||||
if (creatorIds.isEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
return getCalculateCommunityByCreatorRows(startDate, endDate, agentId, creatorIds)
|
||||
}
|
||||
|
||||
fun getCalculateContentDonationByCreatorTotalCount(
|
||||
startDate: LocalDateTime,
|
||||
endDate: LocalDateTime,
|
||||
agentId: Long
|
||||
): Int {
|
||||
return queryFactory
|
||||
.select(member.id.countDistinct())
|
||||
.from(useCan)
|
||||
.innerJoin(useCan.audioContent, audioContent)
|
||||
.innerJoin(audioContent.member, member)
|
||||
.innerJoin(agentCreatorRelation)
|
||||
.on(
|
||||
agentCreatorRelation.creator.id.eq(member.id)
|
||||
.and(assignedToAgentAtEventTime(agentId, useCan.createdAt))
|
||||
)
|
||||
.where(
|
||||
useCan.isRefund.isFalse
|
||||
.and(useCan.canUsage.eq(CanUsage.DONATION))
|
||||
.and(useCan.createdAt.goe(startDate))
|
||||
.and(useCan.createdAt.loe(endDate))
|
||||
)
|
||||
.fetchOne()
|
||||
?.toInt()
|
||||
?: 0
|
||||
}
|
||||
|
||||
fun getCalculateContentDonationByCreator(
|
||||
startDate: LocalDateTime,
|
||||
endDate: LocalDateTime,
|
||||
agentId: Long
|
||||
): List<GetAgentCreatorSettlementSummaryQueryData> {
|
||||
return getCalculateContentDonationByCreatorRows(startDate, endDate, agentId, creatorIds = null)
|
||||
}
|
||||
|
||||
fun getCalculateContentDonationByCreator(
|
||||
startDate: LocalDateTime,
|
||||
endDate: LocalDateTime,
|
||||
agentId: Long,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): List<GetAgentCreatorSettlementSummaryQueryData> {
|
||||
val creatorIds = queryFactory
|
||||
.select(member.id)
|
||||
.from(useCan)
|
||||
.innerJoin(useCan.audioContent, audioContent)
|
||||
.innerJoin(audioContent.member, member)
|
||||
.innerJoin(agentCreatorRelation)
|
||||
.on(
|
||||
agentCreatorRelation.creator.id.eq(member.id)
|
||||
.and(assignedToAgentAtEventTime(agentId, useCan.createdAt))
|
||||
)
|
||||
.where(
|
||||
useCan.isRefund.isFalse
|
||||
.and(useCan.canUsage.eq(CanUsage.DONATION))
|
||||
.and(useCan.createdAt.goe(startDate))
|
||||
.and(useCan.createdAt.loe(endDate))
|
||||
)
|
||||
.groupBy(member.id)
|
||||
.orderBy(member.id.desc())
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
.fetch()
|
||||
|
||||
if (creatorIds.isEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
return getCalculateContentDonationByCreatorRows(startDate, endDate, agentId, creatorIds)
|
||||
}
|
||||
|
||||
fun getChannelDonationByCreatorTotalCount(startDate: LocalDateTime, endDate: LocalDateTime, agentId: Long): Int {
|
||||
return queryFactory
|
||||
.select(member.id.countDistinct())
|
||||
.from(useCanCalculate)
|
||||
.innerJoin(useCanCalculate.useCan, useCan)
|
||||
.innerJoin(member)
|
||||
.on(member.id.eq(useCanCalculate.recipientCreatorId))
|
||||
.innerJoin(agentCreatorRelation)
|
||||
.on(
|
||||
agentCreatorRelation.creator.id.eq(member.id)
|
||||
.and(assignedToAgentAtEventTime(agentId, useCan.createdAt))
|
||||
)
|
||||
.where(
|
||||
useCan.canUsage.eq(CanUsage.CHANNEL_DONATION)
|
||||
.and(useCan.isRefund.isFalse)
|
||||
.and(useCanCalculate.status.eq(UseCanCalculateStatus.RECEIVED))
|
||||
.and(useCan.createdAt.goe(startDate))
|
||||
.and(useCan.createdAt.loe(endDate))
|
||||
)
|
||||
.fetchOne()
|
||||
?.toInt()
|
||||
?: 0
|
||||
}
|
||||
|
||||
fun getChannelDonationByCreator(
|
||||
startDate: LocalDateTime,
|
||||
endDate: LocalDateTime,
|
||||
agentId: Long
|
||||
): List<GetAgentChannelDonationSettlementByCreatorQueryData> {
|
||||
return getChannelDonationByCreatorRows(startDate, endDate, agentId, creatorIds = null)
|
||||
}
|
||||
|
||||
fun getChannelDonationByCreator(
|
||||
startDate: LocalDateTime,
|
||||
endDate: LocalDateTime,
|
||||
agentId: Long,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): List<GetAgentChannelDonationSettlementByCreatorQueryData> {
|
||||
val creatorIds = queryFactory
|
||||
.select(member.id)
|
||||
.from(useCanCalculate)
|
||||
.innerJoin(useCanCalculate.useCan, useCan)
|
||||
.innerJoin(member)
|
||||
.on(member.id.eq(useCanCalculate.recipientCreatorId))
|
||||
.innerJoin(agentCreatorRelation)
|
||||
.on(
|
||||
agentCreatorRelation.creator.id.eq(member.id)
|
||||
.and(assignedToAgentAtEventTime(agentId, useCan.createdAt))
|
||||
)
|
||||
.where(
|
||||
useCan.canUsage.eq(CanUsage.CHANNEL_DONATION)
|
||||
.and(useCan.isRefund.isFalse)
|
||||
.and(useCanCalculate.status.eq(UseCanCalculateStatus.RECEIVED))
|
||||
.and(useCan.createdAt.goe(startDate))
|
||||
.and(useCan.createdAt.loe(endDate))
|
||||
)
|
||||
.groupBy(member.id)
|
||||
.orderBy(member.id.desc())
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
.fetch()
|
||||
|
||||
if (creatorIds.isEmpty()) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
return getChannelDonationByCreatorRows(startDate, endDate, agentId, creatorIds)
|
||||
}
|
||||
|
||||
private fun getCalculateLiveByCreatorRows(
|
||||
startDate: LocalDateTime,
|
||||
endDate: LocalDateTime,
|
||||
agentId: Long,
|
||||
creatorIds: List<Long>?
|
||||
): List<GetAgentCreatorSettlementSummaryQueryData> {
|
||||
return queryFactory
|
||||
.select(
|
||||
QGetAgentCreatorSettlementSummaryQueryData(
|
||||
member.id,
|
||||
member.nickname,
|
||||
agentCreatorRelation.id,
|
||||
agentSettlementRatio.id,
|
||||
useCan.id.count(),
|
||||
useCan.can.add(useCan.rewardCan).sum(),
|
||||
creatorSettlementRatio.liveSettlementRatio,
|
||||
agentSettlementRatio.settlementRatio
|
||||
)
|
||||
)
|
||||
.from(useCan)
|
||||
.innerJoin(useCan.room, liveRoom)
|
||||
.innerJoin(liveRoom.member, member)
|
||||
.innerJoin(agentCreatorRelation)
|
||||
.on(
|
||||
agentCreatorRelation.creator.id.eq(member.id)
|
||||
.and(assignedToAgentAtEventTime(agentId, useCan.createdAt))
|
||||
)
|
||||
.leftJoin(creatorSettlementRatio)
|
||||
.on(
|
||||
member.id.eq(creatorSettlementRatio.member.id)
|
||||
.and(creatorSettlementRatio.deletedAt.isNull)
|
||||
)
|
||||
.leftJoin(agentSettlementRatio)
|
||||
.on(appliedAgentSettlementRatioAtEventTime(agentId, useCan.createdAt))
|
||||
.where(
|
||||
useCan.isRefund.isFalse
|
||||
.and(useCan.createdAt.goe(startDate))
|
||||
.and(useCan.createdAt.loe(endDate))
|
||||
.and(if (!creatorIds.isNullOrEmpty()) member.id.`in`(creatorIds) else null)
|
||||
)
|
||||
.groupBy(
|
||||
member.id,
|
||||
member.nickname,
|
||||
agentCreatorRelation.id,
|
||||
agentSettlementRatio.id,
|
||||
creatorSettlementRatio.liveSettlementRatio,
|
||||
agentSettlementRatio.settlementRatio
|
||||
)
|
||||
.orderBy(member.id.desc())
|
||||
.fetch()
|
||||
}
|
||||
|
||||
private fun getCalculateContentByCreatorRows(
|
||||
startDate: LocalDateTime,
|
||||
endDate: LocalDateTime,
|
||||
agentId: Long,
|
||||
creatorIds: List<Long>?
|
||||
): List<GetAgentCreatorSettlementSummaryQueryData> {
|
||||
val contentSettlementRatio = audioContent.settlementRatio.coalesce(creatorSettlementRatio.contentSettlementRatio)
|
||||
|
||||
return queryFactory
|
||||
.select(
|
||||
QGetAgentCreatorSettlementSummaryQueryData(
|
||||
member.id,
|
||||
member.nickname,
|
||||
agentCreatorRelation.id,
|
||||
agentSettlementRatio.id,
|
||||
order.id.count(),
|
||||
order.can.sum(),
|
||||
contentSettlementRatio,
|
||||
agentSettlementRatio.settlementRatio
|
||||
)
|
||||
)
|
||||
.from(order)
|
||||
.innerJoin(order.audioContent, audioContent)
|
||||
.innerJoin(audioContent.member, member)
|
||||
.innerJoin(agentCreatorRelation)
|
||||
.on(
|
||||
agentCreatorRelation.creator.id.eq(member.id)
|
||||
.and(assignedToAgentAtEventTime(agentId, order.createdAt))
|
||||
)
|
||||
.leftJoin(creatorSettlementRatio)
|
||||
.on(
|
||||
member.id.eq(creatorSettlementRatio.member.id)
|
||||
.and(creatorSettlementRatio.deletedAt.isNull)
|
||||
)
|
||||
.leftJoin(agentSettlementRatio)
|
||||
.on(appliedAgentSettlementRatioAtEventTime(agentId, order.createdAt))
|
||||
.where(
|
||||
order.createdAt.goe(startDate)
|
||||
.and(order.createdAt.loe(endDate))
|
||||
.and(order.isActive.isTrue)
|
||||
.and(if (creatorIds != null && creatorIds.isNotEmpty()) member.id.`in`(creatorIds) else null)
|
||||
)
|
||||
.groupBy(
|
||||
member.id,
|
||||
member.nickname,
|
||||
agentCreatorRelation.id,
|
||||
agentSettlementRatio.id,
|
||||
contentSettlementRatio,
|
||||
agentSettlementRatio.settlementRatio
|
||||
)
|
||||
.orderBy(member.id.desc())
|
||||
.fetch()
|
||||
}
|
||||
|
||||
private fun getCalculateCommunityByCreatorRows(
|
||||
startDate: LocalDateTime,
|
||||
endDate: LocalDateTime,
|
||||
agentId: Long,
|
||||
creatorIds: List<Long>?
|
||||
): List<GetAgentCreatorSettlementSummaryQueryData> {
|
||||
return queryFactory
|
||||
.select(
|
||||
QGetAgentCreatorSettlementSummaryQueryData(
|
||||
member.id,
|
||||
member.nickname,
|
||||
agentCreatorRelation.id,
|
||||
agentSettlementRatio.id,
|
||||
useCan.id.count(),
|
||||
useCan.can.add(useCan.rewardCan).sum(),
|
||||
creatorSettlementRatio.communitySettlementRatio,
|
||||
agentSettlementRatio.settlementRatio
|
||||
)
|
||||
)
|
||||
.from(useCan)
|
||||
.innerJoin(useCan.communityPost, creatorCommunity)
|
||||
.innerJoin(creatorCommunity.member, member)
|
||||
.innerJoin(agentCreatorRelation)
|
||||
.on(
|
||||
agentCreatorRelation.creator.id.eq(member.id)
|
||||
.and(assignedToAgentAtEventTime(agentId, useCan.createdAt))
|
||||
)
|
||||
.leftJoin(creatorSettlementRatio)
|
||||
.on(
|
||||
member.id.eq(creatorSettlementRatio.member.id)
|
||||
.and(creatorSettlementRatio.deletedAt.isNull)
|
||||
)
|
||||
.leftJoin(agentSettlementRatio)
|
||||
.on(appliedAgentSettlementRatioAtEventTime(agentId, useCan.createdAt))
|
||||
.where(
|
||||
useCan.isRefund.isFalse
|
||||
.and(useCan.canUsage.eq(CanUsage.PAID_COMMUNITY_POST))
|
||||
.and(useCan.createdAt.goe(startDate))
|
||||
.and(useCan.createdAt.loe(endDate))
|
||||
.and(if (creatorIds != null && creatorIds.isNotEmpty()) member.id.`in`(creatorIds) else null)
|
||||
)
|
||||
.groupBy(
|
||||
member.id,
|
||||
member.nickname,
|
||||
agentCreatorRelation.id,
|
||||
agentSettlementRatio.id,
|
||||
creatorSettlementRatio.communitySettlementRatio,
|
||||
agentSettlementRatio.settlementRatio
|
||||
)
|
||||
.orderBy(member.id.desc())
|
||||
.fetch()
|
||||
}
|
||||
|
||||
private fun getCalculateContentDonationByCreatorRows(
|
||||
startDate: LocalDateTime,
|
||||
endDate: LocalDateTime,
|
||||
agentId: Long,
|
||||
creatorIds: List<Long>?
|
||||
): List<GetAgentCreatorSettlementSummaryQueryData> {
|
||||
return queryFactory
|
||||
.select(
|
||||
QGetAgentCreatorSettlementSummaryQueryData(
|
||||
member.id,
|
||||
member.nickname,
|
||||
agentCreatorRelation.id,
|
||||
agentSettlementRatio.id,
|
||||
useCan.id.count(),
|
||||
useCan.can.add(useCan.rewardCan).sum(),
|
||||
Expressions.numberTemplate(Int::class.java, "70"),
|
||||
agentSettlementRatio.settlementRatio
|
||||
)
|
||||
)
|
||||
.from(useCan)
|
||||
.innerJoin(useCan.audioContent, audioContent)
|
||||
.innerJoin(audioContent.member, member)
|
||||
.innerJoin(agentCreatorRelation)
|
||||
.on(
|
||||
agentCreatorRelation.creator.id.eq(member.id)
|
||||
.and(assignedToAgentAtEventTime(agentId, useCan.createdAt))
|
||||
)
|
||||
.leftJoin(agentSettlementRatio)
|
||||
.on(appliedAgentSettlementRatioAtEventTime(agentId, useCan.createdAt))
|
||||
.where(
|
||||
useCan.isRefund.isFalse
|
||||
.and(useCan.canUsage.eq(CanUsage.DONATION))
|
||||
.and(useCan.createdAt.goe(startDate))
|
||||
.and(useCan.createdAt.loe(endDate))
|
||||
.and(if (creatorIds != null && creatorIds.isNotEmpty()) member.id.`in`(creatorIds) else null)
|
||||
)
|
||||
.groupBy(
|
||||
member.id,
|
||||
member.nickname,
|
||||
agentCreatorRelation.id,
|
||||
agentSettlementRatio.id,
|
||||
agentSettlementRatio.settlementRatio
|
||||
)
|
||||
.orderBy(member.id.desc())
|
||||
.fetch()
|
||||
}
|
||||
|
||||
private fun getChannelDonationByCreatorRows(
|
||||
startDate: LocalDateTime,
|
||||
endDate: LocalDateTime,
|
||||
agentId: Long,
|
||||
creatorIds: List<Long>?
|
||||
): List<GetAgentChannelDonationSettlementByCreatorQueryData> {
|
||||
return queryFactory
|
||||
.select(
|
||||
QGetAgentChannelDonationSettlementByCreatorQueryData(
|
||||
member.id,
|
||||
member.nickname,
|
||||
agentCreatorRelation.id,
|
||||
agentSettlementRatio.id,
|
||||
useCan.id.countDistinct(),
|
||||
useCanCalculate.can.sum(),
|
||||
agentSettlementRatio.settlementRatio
|
||||
)
|
||||
)
|
||||
.from(useCanCalculate)
|
||||
.innerJoin(useCanCalculate.useCan, useCan)
|
||||
.innerJoin(member)
|
||||
.on(member.id.eq(useCanCalculate.recipientCreatorId))
|
||||
.innerJoin(agentCreatorRelation)
|
||||
.on(
|
||||
agentCreatorRelation.creator.id.eq(member.id)
|
||||
.and(assignedToAgentAtEventTime(agentId, useCan.createdAt))
|
||||
)
|
||||
.leftJoin(agentSettlementRatio)
|
||||
.on(appliedAgentSettlementRatioAtEventTime(agentId, useCan.createdAt))
|
||||
.where(
|
||||
useCan.canUsage.eq(CanUsage.CHANNEL_DONATION)
|
||||
.and(useCan.isRefund.isFalse)
|
||||
.and(useCanCalculate.status.eq(UseCanCalculateStatus.RECEIVED))
|
||||
.and(useCan.createdAt.goe(startDate))
|
||||
.and(useCan.createdAt.loe(endDate))
|
||||
.and(if (creatorIds != null && creatorIds.isNotEmpty()) member.id.`in`(creatorIds) else null)
|
||||
)
|
||||
.groupBy(
|
||||
member.id,
|
||||
member.nickname,
|
||||
agentCreatorRelation.id,
|
||||
agentSettlementRatio.id,
|
||||
agentSettlementRatio.settlementRatio
|
||||
)
|
||||
.orderBy(member.id.desc())
|
||||
.fetch()
|
||||
}
|
||||
|
||||
private fun assignedToAgentAtEventTime(
|
||||
agentId: Long,
|
||||
eventTime: DateTimeExpression<LocalDateTime>
|
||||
) = agentCreatorRelation.agent.id.eq(agentId)
|
||||
.and(agentCreatorRelation.assignedAt.loe(eventTime))
|
||||
.and(agentCreatorRelation.unassignedAt.isNull.or(agentCreatorRelation.unassignedAt.gt(eventTime)))
|
||||
|
||||
private fun assignedToAgentAtCurrentTime(
|
||||
agentId: Long,
|
||||
currentTime: LocalDateTime
|
||||
) = agentCreatorRelation.agent.id.eq(agentId)
|
||||
.and(agentCreatorRelation.assignedAt.loe(currentTime))
|
||||
.and(agentCreatorRelation.unassignedAt.isNull.or(agentCreatorRelation.unassignedAt.gt(currentTime)))
|
||||
|
||||
private fun appliedAgentSettlementRatioAtEventTime(
|
||||
agentId: Long,
|
||||
eventTime: DateTimeExpression<LocalDateTime>
|
||||
) = agentSettlementRatio.member.id.eq(agentId)
|
||||
.and(agentSettlementRatio.effectiveFrom.loe(eventTime))
|
||||
.and(agentSettlementRatio.effectiveTo.isNull.or(agentSettlementRatio.effectiveTo.gt(eventTime)))
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
package kr.co.vividnext.sodalive.partner.agent.calculate
|
||||
|
||||
import kr.co.vividnext.sodalive.extensions.convertLocalDateTime
|
||||
import kr.co.vividnext.sodalive.partner.agent.settlement.snapshot.AgentSettlementSnapshotRepository
|
||||
import kr.co.vividnext.sodalive.partner.agent.settlement.snapshot.AgentSettlementSnapshotType
|
||||
import kr.co.vividnext.sodalive.partner.agent.settlement.snapshot.toChannelDonationSettlementByCreatorItems
|
||||
import kr.co.vividnext.sodalive.partner.agent.settlement.snapshot.toSettlementByCreatorItems
|
||||
import org.springframework.stereotype.Service
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
import java.time.LocalDateTime
|
||||
|
||||
@Service
|
||||
class AgentCalculateService(
|
||||
private val repository: AgentCalculateQueryRepository,
|
||||
private val snapshotRepository: AgentSettlementSnapshotRepository
|
||||
) {
|
||||
@Transactional(readOnly = true)
|
||||
fun getAssignedCreators(agentId: Long, offset: Long, limit: Long): GetAgentAssignedCreatorResponse {
|
||||
val currentTime = LocalDateTime.now()
|
||||
val totalCount = repository.getAssignedCreatorTotalCount(agentId = agentId, currentTime = currentTime)
|
||||
val items = repository.getAssignedCreators(agentId = agentId, offset = offset, limit = limit, currentTime = currentTime)
|
||||
return GetAgentAssignedCreatorResponse(totalCount = totalCount, items = items)
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
fun getCalculateLiveByCreator(
|
||||
startDateStr: String,
|
||||
endDateStr: String,
|
||||
agentId: Long,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): GetAgentSettlementByCreatorResponse {
|
||||
return buildSettlementByCreatorResponse(
|
||||
startDateStr = startDateStr,
|
||||
endDateStr = endDateStr,
|
||||
settlementType = AgentSettlementSnapshotType.LIVE,
|
||||
agentId = agentId,
|
||||
offset = offset,
|
||||
limit = limit,
|
||||
totalCountLoader = { startDate, endDate ->
|
||||
repository.getCalculateLiveByCreatorTotalCount(startDate, endDate, agentId)
|
||||
},
|
||||
totalRowsLoader = { startDate, endDate ->
|
||||
repository.getCalculateLiveByCreator(startDate, endDate, agentId)
|
||||
},
|
||||
pagedRowsLoader = { startDate, endDate ->
|
||||
repository.getCalculateLiveByCreator(startDate, endDate, agentId, offset, limit)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
fun getCalculateContentByCreator(
|
||||
startDateStr: String,
|
||||
endDateStr: String,
|
||||
agentId: Long,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): GetAgentSettlementByCreatorResponse {
|
||||
return buildSettlementByCreatorResponse(
|
||||
startDateStr = startDateStr,
|
||||
endDateStr = endDateStr,
|
||||
settlementType = AgentSettlementSnapshotType.CONTENT,
|
||||
agentId = agentId,
|
||||
offset = offset,
|
||||
limit = limit,
|
||||
totalCountLoader = { startDate, endDate ->
|
||||
repository.getCalculateContentByCreatorTotalCount(startDate, endDate, agentId)
|
||||
},
|
||||
totalRowsLoader = { startDate, endDate ->
|
||||
repository.getCalculateContentByCreator(startDate, endDate, agentId)
|
||||
},
|
||||
pagedRowsLoader = { startDate, endDate ->
|
||||
repository.getCalculateContentByCreator(startDate, endDate, agentId, offset, limit)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
fun getCalculateCommunityByCreator(
|
||||
startDateStr: String,
|
||||
endDateStr: String,
|
||||
agentId: Long,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): GetAgentSettlementByCreatorResponse {
|
||||
return buildSettlementByCreatorResponse(
|
||||
startDateStr = startDateStr,
|
||||
endDateStr = endDateStr,
|
||||
settlementType = AgentSettlementSnapshotType.COMMUNITY,
|
||||
agentId = agentId,
|
||||
offset = offset,
|
||||
limit = limit,
|
||||
totalCountLoader = { startDate, endDate ->
|
||||
repository.getCalculateCommunityByCreatorTotalCount(startDate, endDate, agentId)
|
||||
},
|
||||
totalRowsLoader = { startDate, endDate ->
|
||||
repository.getCalculateCommunityByCreator(startDate, endDate, agentId)
|
||||
},
|
||||
pagedRowsLoader = { startDate, endDate ->
|
||||
repository.getCalculateCommunityByCreator(startDate, endDate, agentId, offset, limit)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
fun getCalculateContentDonationByCreator(
|
||||
startDateStr: String,
|
||||
endDateStr: String,
|
||||
agentId: Long,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): GetAgentSettlementByCreatorResponse {
|
||||
return buildSettlementByCreatorResponse(
|
||||
startDateStr = startDateStr,
|
||||
endDateStr = endDateStr,
|
||||
settlementType = AgentSettlementSnapshotType.CONTENT_DONATION,
|
||||
agentId = agentId,
|
||||
offset = offset,
|
||||
limit = limit,
|
||||
totalCountLoader = { startDate, endDate ->
|
||||
repository.getCalculateContentDonationByCreatorTotalCount(startDate, endDate, agentId)
|
||||
},
|
||||
totalRowsLoader = { startDate, endDate ->
|
||||
repository.getCalculateContentDonationByCreator(startDate, endDate, agentId)
|
||||
},
|
||||
pagedRowsLoader = { startDate, endDate ->
|
||||
repository.getCalculateContentDonationByCreator(startDate, endDate, agentId, offset, limit)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
fun getChannelDonationByCreator(
|
||||
startDateStr: String,
|
||||
endDateStr: String,
|
||||
agentId: Long,
|
||||
offset: Long,
|
||||
limit: Long
|
||||
): GetAgentChannelDonationSettlementByCreatorResponse {
|
||||
val (startDate, endDate) = toDateRange(startDateStr, endDateStr)
|
||||
val snapshots = snapshotRepository.findAllByPeriodStartAndPeriodEndAndSettlementTypeAndAgentIdOrderByCreatorIdDesc(
|
||||
periodStart = startDate,
|
||||
periodEnd = endDate,
|
||||
settlementType = AgentSettlementSnapshotType.CHANNEL_DONATION,
|
||||
agentId = agentId
|
||||
)
|
||||
if (snapshots.isNotEmpty()) {
|
||||
val total = snapshots.toChannelDonationSettlementByCreatorItems().toResponseTotal()
|
||||
val items = snapshots.drop(offset.toInt()).take(limit.toInt()).toChannelDonationSettlementByCreatorItems()
|
||||
return GetAgentChannelDonationSettlementByCreatorResponse(
|
||||
totalCount = snapshots.size,
|
||||
total = total,
|
||||
items = items
|
||||
)
|
||||
}
|
||||
|
||||
val totalCount = repository.getChannelDonationByCreatorTotalCount(startDate, endDate, agentId)
|
||||
val total = repository.getChannelDonationByCreator(startDate, endDate, agentId)
|
||||
.toMergedResponseItems()
|
||||
.toResponseTotal()
|
||||
val items = repository.getChannelDonationByCreator(startDate, endDate, agentId, offset, limit)
|
||||
.toMergedResponseItems()
|
||||
|
||||
return GetAgentChannelDonationSettlementByCreatorResponse(
|
||||
totalCount = totalCount,
|
||||
total = total,
|
||||
items = items
|
||||
)
|
||||
}
|
||||
|
||||
private fun buildSettlementByCreatorResponse(
|
||||
startDateStr: String,
|
||||
endDateStr: String,
|
||||
settlementType: AgentSettlementSnapshotType,
|
||||
agentId: Long,
|
||||
offset: Long,
|
||||
limit: Long,
|
||||
totalCountLoader: (LocalDateTime, LocalDateTime) -> Int,
|
||||
totalRowsLoader: (LocalDateTime, LocalDateTime) -> List<GetAgentCreatorSettlementSummaryQueryData>,
|
||||
pagedRowsLoader: (LocalDateTime, LocalDateTime) -> List<GetAgentCreatorSettlementSummaryQueryData>
|
||||
): GetAgentSettlementByCreatorResponse {
|
||||
val (startDate, endDate) = toDateRange(startDateStr, endDateStr)
|
||||
val snapshots = snapshotRepository.findAllByPeriodStartAndPeriodEndAndSettlementTypeAndAgentIdOrderByCreatorIdDesc(
|
||||
periodStart = startDate,
|
||||
periodEnd = endDate,
|
||||
settlementType = settlementType,
|
||||
agentId = agentId
|
||||
)
|
||||
if (snapshots.isNotEmpty()) {
|
||||
val total = snapshots.toSettlementByCreatorItems().toResponseTotal()
|
||||
val items = snapshots.drop(offset.toInt()).take(limit.toInt()).toSettlementByCreatorItems()
|
||||
return GetAgentSettlementByCreatorResponse(
|
||||
totalCount = snapshots.size,
|
||||
total = total,
|
||||
items = items
|
||||
)
|
||||
}
|
||||
|
||||
val totalCount = totalCountLoader(startDate, endDate)
|
||||
val total = totalRowsLoader(startDate, endDate)
|
||||
.toMergedResponseItems()
|
||||
.toResponseTotal()
|
||||
val items = pagedRowsLoader(startDate, endDate)
|
||||
.toMergedResponseItems()
|
||||
|
||||
return GetAgentSettlementByCreatorResponse(
|
||||
totalCount = totalCount,
|
||||
total = total,
|
||||
items = items
|
||||
)
|
||||
}
|
||||
|
||||
private fun toDateRange(startDateStr: String, endDateStr: String): Pair<LocalDateTime, LocalDateTime> {
|
||||
val startDate = startDateStr.convertLocalDateTime()
|
||||
val endDate = endDateStr.convertLocalDateTime(hour = 23, minute = 59, second = 59)
|
||||
return startDate to endDate
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package kr.co.vividnext.sodalive.partner.agent.calculate
|
||||
|
||||
import com.querydsl.core.annotations.QueryProjection
|
||||
|
||||
data class GetAgentAssignedCreatorResponse(
|
||||
val totalCount: Int,
|
||||
val items: List<GetAgentAssignedCreatorItem>
|
||||
)
|
||||
|
||||
data class GetAgentAssignedCreatorItem @QueryProjection constructor(
|
||||
val creatorId: Long,
|
||||
val creatorNickname: String
|
||||
)
|
||||
@@ -0,0 +1,102 @@
|
||||
package kr.co.vividnext.sodalive.partner.agent.calculate
|
||||
|
||||
import com.querydsl.core.annotations.QueryProjection
|
||||
import kr.co.vividnext.sodalive.calculate.channelDonation.ChannelDonationSettlementCalculator
|
||||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
|
||||
data class GetAgentChannelDonationSettlementByCreatorResponse(
|
||||
val totalCount: Int,
|
||||
val total: GetAgentChannelDonationSettlementTotal,
|
||||
val items: List<GetAgentChannelDonationSettlementByCreatorItem>
|
||||
)
|
||||
|
||||
data class GetAgentChannelDonationSettlementTotal(
|
||||
val count: Int,
|
||||
val totalCan: Int,
|
||||
val krw: Int,
|
||||
val fee: Int,
|
||||
val settlementAmount: Int,
|
||||
val withholdingTax: Int,
|
||||
val depositAmount: Int,
|
||||
val agentSettlementAmount: Int
|
||||
)
|
||||
|
||||
data class GetAgentChannelDonationSettlementByCreatorItem(
|
||||
val creatorId: Long,
|
||||
val creatorNickname: String,
|
||||
val count: Int,
|
||||
val totalCan: Int,
|
||||
val krw: Int,
|
||||
val fee: Int,
|
||||
val settlementAmount: Int,
|
||||
val withholdingTax: Int,
|
||||
val depositAmount: Int,
|
||||
val agentSettlementAmount: Int
|
||||
)
|
||||
|
||||
data class GetAgentChannelDonationSettlementByCreatorQueryData @QueryProjection constructor(
|
||||
val creatorId: Long,
|
||||
val creatorNickname: String,
|
||||
val assignmentId: Long? = null,
|
||||
val agentSettlementRatioId: Long? = null,
|
||||
val count: Long,
|
||||
val totalCan: Int,
|
||||
val agentSettlementRatio: Int? = null
|
||||
) {
|
||||
fun toResponseItem(): GetAgentChannelDonationSettlementByCreatorItem {
|
||||
val amount = ChannelDonationSettlementCalculator.calculate(totalCan)
|
||||
return GetAgentChannelDonationSettlementByCreatorItem(
|
||||
creatorId = creatorId,
|
||||
creatorNickname = creatorNickname,
|
||||
count = count.toInt(),
|
||||
totalCan = totalCan,
|
||||
krw = amount.krw,
|
||||
fee = amount.fee,
|
||||
settlementAmount = amount.settlementAmount,
|
||||
withholdingTax = amount.withholdingTax,
|
||||
depositAmount = amount.depositAmount,
|
||||
agentSettlementAmount = BigDecimal(amount.settlementAmount)
|
||||
.multiply(BigDecimal(agentSettlementRatio ?: DEFAULT_AGENT_SETTLEMENT_RATIO).divide(BigDecimal("100")))
|
||||
.setScale(0, RoundingMode.HALF_UP)
|
||||
.toInt()
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val DEFAULT_AGENT_SETTLEMENT_RATIO = 10
|
||||
}
|
||||
}
|
||||
|
||||
fun List<GetAgentChannelDonationSettlementByCreatorQueryData>.toMergedResponseItems():
|
||||
List<GetAgentChannelDonationSettlementByCreatorItem> {
|
||||
return map { it.toResponseItem() }
|
||||
.groupBy { it.creatorId }
|
||||
.map { (_, items) ->
|
||||
items.reduce { acc, item ->
|
||||
acc.copy(
|
||||
count = acc.count + item.count,
|
||||
totalCan = acc.totalCan + item.totalCan,
|
||||
krw = acc.krw + item.krw,
|
||||
fee = acc.fee + item.fee,
|
||||
settlementAmount = acc.settlementAmount + item.settlementAmount,
|
||||
withholdingTax = acc.withholdingTax + item.withholdingTax,
|
||||
depositAmount = acc.depositAmount + item.depositAmount,
|
||||
agentSettlementAmount = acc.agentSettlementAmount + item.agentSettlementAmount
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun List<GetAgentChannelDonationSettlementByCreatorItem>.toResponseTotal(): GetAgentChannelDonationSettlementTotal {
|
||||
return GetAgentChannelDonationSettlementTotal(
|
||||
count = sumOf { it.count },
|
||||
totalCan = sumOf { it.totalCan },
|
||||
krw = sumOf { it.krw },
|
||||
fee = sumOf { it.fee },
|
||||
settlementAmount = sumOf { it.settlementAmount },
|
||||
withholdingTax = sumOf { it.withholdingTax },
|
||||
depositAmount = sumOf { it.depositAmount },
|
||||
agentSettlementAmount = sumOf { it.agentSettlementAmount }
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package kr.co.vividnext.sodalive.partner.agent.calculate
|
||||
|
||||
import com.querydsl.core.annotations.QueryProjection
|
||||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
|
||||
data class GetAgentCreatorSettlementSummaryQueryData @QueryProjection constructor(
|
||||
val creatorId: Long,
|
||||
val creatorNickname: String,
|
||||
val assignmentId: Long? = null,
|
||||
val agentSettlementRatioId: Long? = null,
|
||||
val count: Long,
|
||||
val totalCan: Int,
|
||||
val settlementRatio: Int?,
|
||||
val agentSettlementRatio: Int? = null
|
||||
) {
|
||||
fun toResponseItem(): GetAgentSettlementByCreatorItem {
|
||||
val totalKrw = BigDecimal(totalCan).multiply(KRW_PER_CAN)
|
||||
val fee = totalKrw.multiply(PAYMENT_FEE_RATE)
|
||||
val settlementAmount = totalKrw.subtract(fee)
|
||||
.multiply(BigDecimal(settlementRatio ?: DEFAULT_SETTLEMENT_RATIO).divide(PERCENT_DIVISOR))
|
||||
val tax = settlementAmount.multiply(TAX_RATE)
|
||||
val depositAmount = settlementAmount.subtract(tax)
|
||||
val roundedSettlementAmount = settlementAmount.setScale(0, RoundingMode.HALF_UP).toInt()
|
||||
|
||||
return GetAgentSettlementByCreatorItem(
|
||||
creatorId = creatorId,
|
||||
creatorNickname = creatorNickname,
|
||||
count = count.toInt(),
|
||||
totalCan = totalCan,
|
||||
krw = totalKrw.toInt(),
|
||||
fee = fee.setScale(0, RoundingMode.HALF_UP).toInt(),
|
||||
settlementAmount = roundedSettlementAmount,
|
||||
tax = tax.setScale(0, RoundingMode.HALF_UP).toInt(),
|
||||
depositAmount = depositAmount.setScale(0, RoundingMode.HALF_UP).toInt(),
|
||||
agentSettlementAmount = calculateAgentSettlementAmount(
|
||||
settlementAmount = roundedSettlementAmount,
|
||||
agentSettlementRatio = agentSettlementRatio ?: DEFAULT_AGENT_SETTLEMENT_RATIO
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val KRW_PER_CAN = BigDecimal("100")
|
||||
private val PAYMENT_FEE_RATE = BigDecimal("0.066")
|
||||
private val TAX_RATE = BigDecimal("0.033")
|
||||
private val PERCENT_DIVISOR = BigDecimal("100")
|
||||
private const val DEFAULT_SETTLEMENT_RATIO = 70
|
||||
private const val DEFAULT_AGENT_SETTLEMENT_RATIO = 10
|
||||
|
||||
private fun calculateAgentSettlementAmount(settlementAmount: Int, agentSettlementRatio: Int): Int {
|
||||
return BigDecimal(settlementAmount)
|
||||
.multiply(BigDecimal(agentSettlementRatio).divide(PERCENT_DIVISOR))
|
||||
.setScale(0, RoundingMode.HALF_UP)
|
||||
.toInt()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun List<GetAgentCreatorSettlementSummaryQueryData>.toMergedResponseItems(): List<GetAgentSettlementByCreatorItem> {
|
||||
return map { it.toResponseItem() }
|
||||
.groupBy { it.creatorId }
|
||||
.map { (_, items) ->
|
||||
items.reduce { acc, item ->
|
||||
acc.copy(
|
||||
count = acc.count + item.count,
|
||||
totalCan = acc.totalCan + item.totalCan,
|
||||
krw = acc.krw + item.krw,
|
||||
fee = acc.fee + item.fee,
|
||||
settlementAmount = acc.settlementAmount + item.settlementAmount,
|
||||
tax = acc.tax + item.tax,
|
||||
depositAmount = acc.depositAmount + item.depositAmount,
|
||||
agentSettlementAmount = acc.agentSettlementAmount + item.agentSettlementAmount
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package kr.co.vividnext.sodalive.partner.agent.calculate
|
||||
|
||||
data class GetAgentSettlementByCreatorResponse(
|
||||
val totalCount: Int,
|
||||
val total: GetAgentSettlementByCreatorTotal,
|
||||
val items: List<GetAgentSettlementByCreatorItem>
|
||||
)
|
||||
|
||||
data class GetAgentSettlementByCreatorTotal(
|
||||
val count: Int,
|
||||
val totalCan: Int,
|
||||
val krw: Int,
|
||||
val fee: Int,
|
||||
val settlementAmount: Int,
|
||||
val tax: Int,
|
||||
val depositAmount: Int,
|
||||
val agentSettlementAmount: Int
|
||||
)
|
||||
|
||||
data class GetAgentSettlementByCreatorItem(
|
||||
val creatorId: Long,
|
||||
val creatorNickname: String,
|
||||
val count: Int,
|
||||
val totalCan: Int,
|
||||
val krw: Int,
|
||||
val fee: Int,
|
||||
val settlementAmount: Int,
|
||||
val tax: Int,
|
||||
val depositAmount: Int,
|
||||
val agentSettlementAmount: Int
|
||||
)
|
||||
|
||||
fun List<GetAgentSettlementByCreatorItem>.toResponseTotal(): GetAgentSettlementByCreatorTotal {
|
||||
return GetAgentSettlementByCreatorTotal(
|
||||
count = sumOf { it.count },
|
||||
totalCan = sumOf { it.totalCan },
|
||||
krw = sumOf { it.krw },
|
||||
fee = sumOf { it.fee },
|
||||
settlementAmount = sumOf { it.settlementAmount },
|
||||
tax = sumOf { it.tax },
|
||||
depositAmount = sumOf { it.depositAmount },
|
||||
agentSettlementAmount = sumOf { it.agentSettlementAmount }
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user