fix(calculate): 콘텐츠별 정산 요율을 정산 조회에 우선 반영한다
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -86,6 +86,7 @@ class AdminCalculateQueryRepository(private val queryFactory: JPAQueryFactory) {
|
|||||||
val pointGroup = CaseBuilder()
|
val pointGroup = CaseBuilder()
|
||||||
.`when`(order.point.loe(0)).then(0)
|
.`when`(order.point.loe(0)).then(0)
|
||||||
.otherwise(1)
|
.otherwise(1)
|
||||||
|
val contentSettlementRatio = audioContent.settlementRatio.coalesce(creatorSettlementRatio.contentSettlementRatio)
|
||||||
|
|
||||||
return queryFactory
|
return queryFactory
|
||||||
.select(audioContent.id)
|
.select(audioContent.id)
|
||||||
@@ -108,7 +109,7 @@ class AdminCalculateQueryRepository(private val queryFactory: JPAQueryFactory) {
|
|||||||
orderFormattedDate,
|
orderFormattedDate,
|
||||||
order.can,
|
order.can,
|
||||||
pointGroup,
|
pointGroup,
|
||||||
creatorSettlementRatio.contentSettlementRatio
|
contentSettlementRatio
|
||||||
)
|
)
|
||||||
.fetch()
|
.fetch()
|
||||||
.size
|
.size
|
||||||
@@ -124,6 +125,7 @@ class AdminCalculateQueryRepository(private val queryFactory: JPAQueryFactory) {
|
|||||||
val pointGroup = CaseBuilder()
|
val pointGroup = CaseBuilder()
|
||||||
.`when`(order.point.loe(0)).then(0)
|
.`when`(order.point.loe(0)).then(0)
|
||||||
.otherwise(1)
|
.otherwise(1)
|
||||||
|
val contentSettlementRatio = audioContent.settlementRatio.coalesce(creatorSettlementRatio.contentSettlementRatio)
|
||||||
|
|
||||||
return queryFactory
|
return queryFactory
|
||||||
.select(
|
.select(
|
||||||
@@ -137,7 +139,7 @@ class AdminCalculateQueryRepository(private val queryFactory: JPAQueryFactory) {
|
|||||||
order.id.count(),
|
order.id.count(),
|
||||||
order.can.sum(),
|
order.can.sum(),
|
||||||
order.point.sum(),
|
order.point.sum(),
|
||||||
creatorSettlementRatio.contentSettlementRatio
|
contentSettlementRatio
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.from(order)
|
.from(order)
|
||||||
@@ -159,7 +161,7 @@ class AdminCalculateQueryRepository(private val queryFactory: JPAQueryFactory) {
|
|||||||
orderFormattedDate,
|
orderFormattedDate,
|
||||||
order.can,
|
order.can,
|
||||||
pointGroup,
|
pointGroup,
|
||||||
creatorSettlementRatio.contentSettlementRatio
|
contentSettlementRatio
|
||||||
)
|
)
|
||||||
.orderBy(member.id.desc(), orderFormattedDate.desc(), audioContent.id.asc())
|
.orderBy(member.id.desc(), orderFormattedDate.desc(), audioContent.id.asc())
|
||||||
.offset(offset)
|
.offset(offset)
|
||||||
@@ -182,13 +184,23 @@ class AdminCalculateQueryRepository(private val queryFactory: JPAQueryFactory) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getCumulativeSalesByContentTotalCount(): Int {
|
fun getCumulativeSalesByContentTotalCount(): Int {
|
||||||
|
val pointGroup = CaseBuilder()
|
||||||
|
.`when`(order.point.loe(0)).then(0)
|
||||||
|
.otherwise(1)
|
||||||
|
val contentSettlementRatio = audioContent.settlementRatio.coalesce(creatorSettlementRatio.contentSettlementRatio)
|
||||||
|
|
||||||
return queryFactory
|
return queryFactory
|
||||||
.select(audioContent.id)
|
.select(audioContent.id)
|
||||||
.from(order)
|
.from(order)
|
||||||
.innerJoin(order.audioContent, audioContent)
|
.innerJoin(order.audioContent, audioContent)
|
||||||
.innerJoin(audioContent.member, member)
|
.innerJoin(audioContent.member, member)
|
||||||
|
.leftJoin(creatorSettlementRatio)
|
||||||
|
.on(
|
||||||
|
member.id.eq(creatorSettlementRatio.member.id)
|
||||||
|
.and(creatorSettlementRatio.deletedAt.isNull)
|
||||||
|
)
|
||||||
.where(order.isActive.isTrue)
|
.where(order.isActive.isTrue)
|
||||||
.groupBy(member.id, audioContent.id, order.can)
|
.groupBy(member.id, audioContent.id, order.type, order.can, pointGroup, contentSettlementRatio)
|
||||||
.fetch()
|
.fetch()
|
||||||
.size
|
.size
|
||||||
}
|
}
|
||||||
@@ -197,6 +209,7 @@ class AdminCalculateQueryRepository(private val queryFactory: JPAQueryFactory) {
|
|||||||
val pointGroup = CaseBuilder()
|
val pointGroup = CaseBuilder()
|
||||||
.`when`(order.point.loe(0)).then(0)
|
.`when`(order.point.loe(0)).then(0)
|
||||||
.otherwise(1)
|
.otherwise(1)
|
||||||
|
val contentSettlementRatio = audioContent.settlementRatio.coalesce(creatorSettlementRatio.contentSettlementRatio)
|
||||||
|
|
||||||
return queryFactory
|
return queryFactory
|
||||||
.select(
|
.select(
|
||||||
@@ -209,7 +222,7 @@ class AdminCalculateQueryRepository(private val queryFactory: JPAQueryFactory) {
|
|||||||
order.id.count(),
|
order.id.count(),
|
||||||
order.can.sum(),
|
order.can.sum(),
|
||||||
order.point.sum(),
|
order.point.sum(),
|
||||||
creatorSettlementRatio.contentSettlementRatio
|
contentSettlementRatio
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.from(order)
|
.from(order)
|
||||||
@@ -227,7 +240,7 @@ class AdminCalculateQueryRepository(private val queryFactory: JPAQueryFactory) {
|
|||||||
order.type,
|
order.type,
|
||||||
order.can,
|
order.can,
|
||||||
pointGroup,
|
pointGroup,
|
||||||
creatorSettlementRatio.contentSettlementRatio
|
contentSettlementRatio
|
||||||
)
|
)
|
||||||
.offset(offset)
|
.offset(offset)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
|
|||||||
@@ -74,18 +74,28 @@ class CreatorAdminCalculateQueryRepository(private val queryFactory: JPAQueryFac
|
|||||||
memberId: Long
|
memberId: Long
|
||||||
): Int {
|
): Int {
|
||||||
val orderFormattedDate = getFormattedDate(order.createdAt)
|
val orderFormattedDate = getFormattedDate(order.createdAt)
|
||||||
|
val pointGroup = CaseBuilder()
|
||||||
|
.`when`(order.point.loe(0)).then(0)
|
||||||
|
.otherwise(1)
|
||||||
|
val contentSettlementRatio = audioContent.settlementRatio.coalesce(creatorSettlementRatio.contentSettlementRatio)
|
||||||
|
|
||||||
return queryFactory
|
return queryFactory
|
||||||
.select(audioContent.id)
|
.select(audioContent.id)
|
||||||
.from(order)
|
.from(order)
|
||||||
.innerJoin(order.audioContent, audioContent)
|
.innerJoin(order.audioContent, audioContent)
|
||||||
.innerJoin(audioContent.member, member)
|
.innerJoin(audioContent.member, member)
|
||||||
|
.leftJoin(creatorSettlementRatio)
|
||||||
|
.on(
|
||||||
|
member.id.eq(creatorSettlementRatio.member.id)
|
||||||
|
.and(creatorSettlementRatio.deletedAt.isNull)
|
||||||
|
)
|
||||||
.where(
|
.where(
|
||||||
order.createdAt.goe(startDate)
|
order.createdAt.goe(startDate)
|
||||||
.and(order.createdAt.loe(endDate))
|
.and(order.createdAt.loe(endDate))
|
||||||
.and(order.isActive.isTrue)
|
.and(order.isActive.isTrue)
|
||||||
.and(order.creator.id.eq(memberId))
|
.and(order.creator.id.eq(memberId))
|
||||||
)
|
)
|
||||||
.groupBy(audioContent.id, order.type, orderFormattedDate, order.can)
|
.groupBy(audioContent.id, order.type, orderFormattedDate, order.can, pointGroup, contentSettlementRatio)
|
||||||
.orderBy(member.id.desc(), orderFormattedDate.desc(), audioContent.id.asc())
|
.orderBy(member.id.desc(), orderFormattedDate.desc(), audioContent.id.asc())
|
||||||
.fetch()
|
.fetch()
|
||||||
.size
|
.size
|
||||||
@@ -102,6 +112,7 @@ class CreatorAdminCalculateQueryRepository(private val queryFactory: JPAQueryFac
|
|||||||
val pointGroup = CaseBuilder()
|
val pointGroup = CaseBuilder()
|
||||||
.`when`(order.point.loe(0)).then(0)
|
.`when`(order.point.loe(0)).then(0)
|
||||||
.otherwise(1)
|
.otherwise(1)
|
||||||
|
val contentSettlementRatio = audioContent.settlementRatio.coalesce(creatorSettlementRatio.contentSettlementRatio)
|
||||||
|
|
||||||
return queryFactory
|
return queryFactory
|
||||||
.select(
|
.select(
|
||||||
@@ -115,7 +126,7 @@ class CreatorAdminCalculateQueryRepository(private val queryFactory: JPAQueryFac
|
|||||||
order.id.count(),
|
order.id.count(),
|
||||||
order.can.sum(),
|
order.can.sum(),
|
||||||
order.point.sum(),
|
order.point.sum(),
|
||||||
creatorSettlementRatio.contentSettlementRatio
|
contentSettlementRatio
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.from(order)
|
.from(order)
|
||||||
@@ -138,7 +149,7 @@ class CreatorAdminCalculateQueryRepository(private val queryFactory: JPAQueryFac
|
|||||||
orderFormattedDate,
|
orderFormattedDate,
|
||||||
order.can,
|
order.can,
|
||||||
pointGroup,
|
pointGroup,
|
||||||
creatorSettlementRatio.contentSettlementRatio
|
contentSettlementRatio
|
||||||
)
|
)
|
||||||
.offset(offset)
|
.offset(offset)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
@@ -161,16 +172,26 @@ class CreatorAdminCalculateQueryRepository(private val queryFactory: JPAQueryFac
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getCumulativeSalesByContentTotalCount(memberId: Long): Int {
|
fun getCumulativeSalesByContentTotalCount(memberId: Long): Int {
|
||||||
|
val pointGroup = CaseBuilder()
|
||||||
|
.`when`(order.point.loe(0)).then(0)
|
||||||
|
.otherwise(1)
|
||||||
|
val contentSettlementRatio = audioContent.settlementRatio.coalesce(creatorSettlementRatio.contentSettlementRatio)
|
||||||
|
|
||||||
return queryFactory
|
return queryFactory
|
||||||
.select(audioContent.id)
|
.select(audioContent.id)
|
||||||
.from(order)
|
.from(order)
|
||||||
.innerJoin(order.audioContent, audioContent)
|
.innerJoin(order.audioContent, audioContent)
|
||||||
.innerJoin(audioContent.member, member)
|
.innerJoin(audioContent.member, member)
|
||||||
|
.leftJoin(creatorSettlementRatio)
|
||||||
|
.on(
|
||||||
|
member.id.eq(creatorSettlementRatio.member.id)
|
||||||
|
.and(creatorSettlementRatio.deletedAt.isNull)
|
||||||
|
)
|
||||||
.where(
|
.where(
|
||||||
audioContent.member.id.eq(memberId)
|
audioContent.member.id.eq(memberId)
|
||||||
.and(order.isActive.isTrue)
|
.and(order.isActive.isTrue)
|
||||||
)
|
)
|
||||||
.groupBy(member.id, audioContent.id, order.can)
|
.groupBy(member.id, audioContent.id, order.type, order.can, pointGroup, contentSettlementRatio)
|
||||||
.fetch()
|
.fetch()
|
||||||
.size
|
.size
|
||||||
}
|
}
|
||||||
@@ -183,6 +204,7 @@ class CreatorAdminCalculateQueryRepository(private val queryFactory: JPAQueryFac
|
|||||||
val pointGroup = CaseBuilder()
|
val pointGroup = CaseBuilder()
|
||||||
.`when`(order.point.loe(0)).then(0)
|
.`when`(order.point.loe(0)).then(0)
|
||||||
.otherwise(1)
|
.otherwise(1)
|
||||||
|
val contentSettlementRatio = audioContent.settlementRatio.coalesce(creatorSettlementRatio.contentSettlementRatio)
|
||||||
|
|
||||||
return queryFactory
|
return queryFactory
|
||||||
.select(
|
.select(
|
||||||
@@ -195,7 +217,7 @@ class CreatorAdminCalculateQueryRepository(private val queryFactory: JPAQueryFac
|
|||||||
order.id.count(),
|
order.id.count(),
|
||||||
order.can.sum(),
|
order.can.sum(),
|
||||||
order.point.sum(),
|
order.point.sum(),
|
||||||
creatorSettlementRatio.contentSettlementRatio
|
contentSettlementRatio
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.from(order)
|
.from(order)
|
||||||
@@ -216,7 +238,7 @@ class CreatorAdminCalculateQueryRepository(private val queryFactory: JPAQueryFac
|
|||||||
order.type,
|
order.type,
|
||||||
order.can,
|
order.can,
|
||||||
pointGroup,
|
pointGroup,
|
||||||
creatorSettlementRatio.contentSettlementRatio
|
contentSettlementRatio
|
||||||
)
|
)
|
||||||
.offset(offset)
|
.offset(offset)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
package kr.co.vividnext.sodalive.admin.calculate
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.content.order.OrderType
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import org.junit.jupiter.api.DisplayName
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
|
class ContentSettlementCalculationTest {
|
||||||
|
@Test
|
||||||
|
@DisplayName("콘텐츠 정산 응답은 콘텐츠별 정산 요율을 우선 적용한다")
|
||||||
|
fun shouldApplyExplicitSettlementRatioForCalculateContentResponse() {
|
||||||
|
val result = GetCalculateContentQueryData(
|
||||||
|
nickname = "creator",
|
||||||
|
title = "content",
|
||||||
|
registrationDate = "2026-04-07",
|
||||||
|
saleDate = "2026-04-07",
|
||||||
|
orderType = OrderType.KEEP,
|
||||||
|
orderPrice = 100,
|
||||||
|
numberOfPeople = 2,
|
||||||
|
totalCan = 100,
|
||||||
|
totalPoint = 0,
|
||||||
|
settlementRatio = 80
|
||||||
|
).toGetCalculateContentResponse()
|
||||||
|
|
||||||
|
assertEquals("소장", result.orderType)
|
||||||
|
assertEquals(10_000, result.totalKrw)
|
||||||
|
assertEquals(660, result.paymentFee)
|
||||||
|
assertEquals(7_472, result.settlementAmount)
|
||||||
|
assertEquals(247, result.tax)
|
||||||
|
assertEquals(7_225, result.depositAmount)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("콘텐츠 정산 응답은 정산 요율이 없으면 70퍼센트 기본값으로 계산한다")
|
||||||
|
fun shouldFallbackToDefaultSettlementRatioForCalculateContentResponse() {
|
||||||
|
val result = GetCalculateContentQueryData(
|
||||||
|
nickname = "creator",
|
||||||
|
title = "content",
|
||||||
|
registrationDate = "2026-04-07",
|
||||||
|
saleDate = "2026-04-07",
|
||||||
|
orderType = OrderType.RENTAL,
|
||||||
|
orderPrice = 70,
|
||||||
|
numberOfPeople = 1,
|
||||||
|
totalCan = 100,
|
||||||
|
totalPoint = 0,
|
||||||
|
settlementRatio = null
|
||||||
|
).toGetCalculateContentResponse()
|
||||||
|
|
||||||
|
assertEquals("대여", result.orderType)
|
||||||
|
assertEquals(10_000, result.totalKrw)
|
||||||
|
assertEquals(660, result.paymentFee)
|
||||||
|
assertEquals(6_538, result.settlementAmount)
|
||||||
|
assertEquals(216, result.tax)
|
||||||
|
assertEquals(6_322, result.depositAmount)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("누적 콘텐츠 정산 응답은 콘텐츠별 정산 요율을 우선 적용한다")
|
||||||
|
fun shouldApplyExplicitSettlementRatioForCumulativeSalesResponse() {
|
||||||
|
val result = GetCumulativeSalesByContentQueryData(
|
||||||
|
nickname = "creator",
|
||||||
|
title = "content",
|
||||||
|
registrationDate = "2026-04-07",
|
||||||
|
orderType = OrderType.KEEP,
|
||||||
|
orderPrice = 100,
|
||||||
|
numberOfPeople = 2,
|
||||||
|
totalCan = 100,
|
||||||
|
totalPoint = 0,
|
||||||
|
settlementRatio = 80
|
||||||
|
).toCumulativeSalesByContentItem()
|
||||||
|
|
||||||
|
assertEquals("소장", result.orderType)
|
||||||
|
assertEquals(10_000, result.totalKrw)
|
||||||
|
assertEquals(660, result.paymentFee)
|
||||||
|
assertEquals(7_472, result.settlementAmount)
|
||||||
|
assertEquals(247, result.tax)
|
||||||
|
assertEquals(7_225, result.depositAmount)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("누적 콘텐츠 정산 응답은 정산 요율이 없으면 70퍼센트 기본값으로 계산한다")
|
||||||
|
fun shouldFallbackToDefaultSettlementRatioForCumulativeSalesResponse() {
|
||||||
|
val result = GetCumulativeSalesByContentQueryData(
|
||||||
|
nickname = "creator",
|
||||||
|
title = "content",
|
||||||
|
registrationDate = "2026-04-07",
|
||||||
|
orderType = OrderType.RENTAL,
|
||||||
|
orderPrice = 70,
|
||||||
|
numberOfPeople = 1,
|
||||||
|
totalCan = 100,
|
||||||
|
totalPoint = 0,
|
||||||
|
settlementRatio = null
|
||||||
|
).toCumulativeSalesByContentItem()
|
||||||
|
|
||||||
|
assertEquals("대여", result.orderType)
|
||||||
|
assertEquals(10_000, result.totalKrw)
|
||||||
|
assertEquals(660, result.paymentFee)
|
||||||
|
assertEquals(6_538, result.settlementAmount)
|
||||||
|
assertEquals(216, result.tax)
|
||||||
|
assertEquals(6_322, result.depositAmount)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user