에이전트 기능 #416

Merged
klaus merged 26 commits from test into main 2026-04-14 06:29:22 +00:00
3 changed files with 190 additions and 1 deletions
Showing only changes of commit 0b61569522 - Show all commits

View File

@@ -199,7 +199,6 @@ class AgentCalculateService(
val totalCount = totalCountLoader(startDate, endDate)
val total = totalRowsLoader(startDate, endDate)
.toMergedResponseItems()
.toResponseTotal()
val items = pagedRowsLoader(startDate, endDate)
.toMergedResponseItems()

View File

@@ -75,3 +75,30 @@ fun List<GetAgentCreatorSettlementSummaryQueryData>.toMergedResponseItems(): Lis
}
}
}
fun List<GetAgentCreatorSettlementSummaryQueryData>.toResponseTotal(): GetAgentSettlementByCreatorTotal {
return fold(
GetAgentSettlementByCreatorTotal(
count = 0,
totalCan = 0,
krw = 0,
fee = 0,
settlementAmount = 0,
tax = 0,
depositAmount = 0,
agentSettlementAmount = 0
)
) { total, row ->
val item = row.toResponseItem()
total.copy(
count = total.count + item.count,
totalCan = total.totalCan + item.totalCan,
krw = total.krw + item.krw,
fee = total.fee + item.fee,
settlementAmount = total.settlementAmount + item.settlementAmount,
tax = total.tax + item.tax,
depositAmount = total.depositAmount + item.depositAmount,
agentSettlementAmount = total.agentSettlementAmount + item.agentSettlementAmount
)
}
}

View File

@@ -597,6 +597,169 @@ class AgentCalculateServiceTest {
Mockito.verifyNoInteractions(repository)
}
@Test
@DisplayName("에이전트 서비스는 generic 정산 결과가 없으면 total 0과 빈 items를 반환한다")
fun shouldReturnEmptyGenericSettlementResponseWhenNoRowsExist() {
val startDate = "2026-02-20".convertLocalDateTime()
val endDate = "2026-02-21".convertLocalDateTime(hour = 23, minute = 59, second = 59)
Mockito.`when`(repository.getCalculateLiveByCreatorTotalCount(startDate, endDate, 7L)).thenReturn(0)
Mockito.`when`(repository.getCalculateLiveByCreator(startDate, endDate, 7L)).thenReturn(emptyList())
Mockito.`when`(repository.getCalculateLiveByCreator(startDate, endDate, 7L, 0L, 20L)).thenReturn(emptyList())
val response = service.getCalculateLiveByCreator("2026-02-20", "2026-02-21", 7L, 0L, 20L)
assertEquals(0, response.totalCount)
assertEquals(0, response.total.count)
assertEquals(0, response.total.totalCan)
assertEquals(0, response.total.krw)
assertEquals(0, response.total.fee)
assertEquals(0, response.total.settlementAmount)
assertEquals(0, response.total.tax)
assertEquals(0, response.total.depositAmount)
assertEquals(0, response.total.agentSettlementAmount)
assertEquals(emptyList<GetAgentSettlementByCreatorItem>(), response.items)
}
@Test
@DisplayName("에이전트 서비스는 채널후원 결과가 없으면 total 0과 빈 items를 반환한다")
fun shouldReturnEmptyChannelDonationSettlementResponseWhenNoRowsExist() {
val startDate = "2026-02-20".convertLocalDateTime()
val endDate = "2026-02-21".convertLocalDateTime(hour = 23, minute = 59, second = 59)
Mockito.`when`(repository.getChannelDonationByCreatorTotalCount(startDate, endDate, 7L)).thenReturn(0)
Mockito.`when`(repository.getChannelDonationByCreator(startDate, endDate, 7L)).thenReturn(emptyList())
Mockito.`when`(repository.getChannelDonationByCreator(startDate, endDate, 7L, 0L, 20L)).thenReturn(emptyList())
val response = service.getChannelDonationByCreator("2026-02-20", "2026-02-21", 7L, 0L, 20L)
assertEquals(0, response.totalCount)
assertEquals(0, response.total.count)
assertEquals(0, response.total.totalCan)
assertEquals(0, response.total.krw)
assertEquals(0, response.total.fee)
assertEquals(0, response.total.settlementAmount)
assertEquals(0, response.total.withholdingTax)
assertEquals(0, response.total.depositAmount)
assertEquals(0, response.total.agentSettlementAmount)
assertEquals(emptyList<GetAgentChannelDonationSettlementByCreatorItem>(), response.items)
}
@Test
@DisplayName("에이전트 서비스는 finalized snapshot을 creatorId desc 순서로 페이지 조회한다")
fun shouldPageFinalizedSnapshotsByCreatorIdDesc() {
val startDate = "2026-02-20".convertLocalDateTime()
val endDate = "2026-02-21".convertLocalDateTime(hour = 23, minute = 59, second = 59)
Mockito.`when`(
snapshotRepository.findAllByPeriodStartAndPeriodEndAndSettlementTypeAndAgentIdOrderByCreatorIdDesc(
startDate,
endDate,
AgentSettlementSnapshotType.LIVE,
7L
)
).thenReturn(
listOf(
createSnapshot(
settlementType = AgentSettlementSnapshotType.LIVE,
count = 3,
totalCan = 300,
krw = 30_000,
fee = 1_980,
settlementAmount = 19_614,
tax = 647,
depositAmount = 18_967,
agentSettlementAmount = 1_961,
appliedAgentSettlementRatio = 10
).also { it.creatorId = 31L; it.creatorNickname = "creator-c" },
createSnapshot(
settlementType = AgentSettlementSnapshotType.LIVE,
count = 2,
totalCan = 200,
krw = 20_000,
fee = 1_320,
settlementAmount = 13_076,
tax = 431,
depositAmount = 12_645,
agentSettlementAmount = 1_308,
appliedAgentSettlementRatio = 10
).also { it.creatorId = 21L; it.creatorNickname = "creator-b" },
createSnapshot(
settlementType = AgentSettlementSnapshotType.LIVE,
count = 1,
totalCan = 100,
krw = 10_000,
fee = 660,
settlementAmount = 6_538,
tax = 216,
depositAmount = 6_322,
agentSettlementAmount = 654,
appliedAgentSettlementRatio = 10
).also { it.creatorId = 11L; it.creatorNickname = "creator-a" }
)
)
val response = service.getCalculateLiveByCreator("2026-02-20", "2026-02-21", 7L, 1L, 1L)
assertEquals(3, response.totalCount)
assertEquals(1, response.items.size)
assertEquals(21L, response.items[0].creatorId)
assertEquals("creator-b", response.items[0].creatorNickname)
Mockito.verifyNoInteractions(repository)
}
@Test
@DisplayName("finalized 이후 live 데이터가 바뀌어도 동일 기간 응답은 snapshot 값을 유지한다")
fun shouldKeepUsingFinalizedSnapshotAfterLiveDataChanges() {
val startDate = "2026-02-20".convertLocalDateTime()
val endDate = "2026-02-21".convertLocalDateTime(hour = 23, minute = 59, second = 59)
Mockito.`when`(
snapshotRepository.findAllByPeriodStartAndPeriodEndAndSettlementTypeAndAgentIdOrderByCreatorIdDesc(
startDate,
endDate,
AgentSettlementSnapshotType.LIVE,
7L
)
).thenReturn(
listOf(
createSnapshot(
settlementType = AgentSettlementSnapshotType.LIVE,
count = 2,
totalCan = 100,
krw = 10_000,
fee = 660,
settlementAmount = 6_538,
tax = 216,
depositAmount = 6_322,
agentSettlementAmount = 654,
appliedAgentSettlementRatio = 10
)
)
)
Mockito.`when`(repository.getCalculateLiveByCreatorTotalCount(startDate, endDate, 7L)).thenReturn(99)
Mockito.`when`(repository.getCalculateLiveByCreator(startDate, endDate, 7L)).thenReturn(
listOf(
GetAgentCreatorSettlementSummaryQueryData(
creatorId = 88L,
creatorNickname = "changed-live",
count = 10L,
totalCan = 999,
settlementRatio = 50,
agentSettlementRatio = 30
)
)
)
val response = service.getCalculateLiveByCreator("2026-02-20", "2026-02-21", 7L, 0L, 20L)
assertEquals(1, response.totalCount)
assertEquals(21L, response.items[0].creatorId)
assertEquals(100, response.total.totalCan)
assertEquals(654, response.total.agentSettlementAmount)
Mockito.verifyNoInteractions(repository)
}
private fun createSnapshot(
settlementType: AgentSettlementSnapshotType,
count: Int,