diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/AdminCalculateController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/AdminCalculateController.kt index ef892f3..f956175 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/AdminCalculateController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/AdminCalculateController.kt @@ -1,6 +1,7 @@ package kr.co.vividnext.sodalive.admin.calculate import kr.co.vividnext.sodalive.common.ApiResponse +import org.springframework.data.domain.Pageable import org.springframework.security.access.prepost.PreAuthorize import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.RequestMapping @@ -22,4 +23,9 @@ class AdminCalculateController(private val service: AdminCalculateService) { @RequestParam startDateStr: String, @RequestParam endDateStr: String ) = ApiResponse.ok(service.getCalculateContentList(startDateStr, endDateStr)) + + @GetMapping("/cumulative-sales-by-content") + fun getCumulativeSalesByContent(pageable: Pageable) = ApiResponse.ok( + service.getCumulativeSalesByContent(pageable.offset, pageable.pageSize.toLong()) + ) } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/AdminCalculateQueryRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/AdminCalculateQueryRepository.kt index 499da25..812d7c3 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/AdminCalculateQueryRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/AdminCalculateQueryRepository.kt @@ -89,4 +89,37 @@ class AdminCalculateQueryRepository(private val queryFactory: JPAQueryFactory) { "%Y-%m-%d" ) } + + fun getCumulativeSalesByContentTotalCount(): Int { + return queryFactory + .select(audioContent.id) + .from(order) + .innerJoin(order.audioContent, audioContent) + .innerJoin(audioContent.member, member) + .groupBy(member.id, audioContent.id, order.can) + .fetch() + .size + } + + fun getCumulativeSalesByContent(offset: Long, limit: Long): List { + return queryFactory + .select( + QGetCumulativeSalesByContentQueryData( + member.nickname, + audioContent.title, + getFormattedDate(audioContent.createdAt), + order.can, + order.id.count(), + order.can.sum() + ) + ) + .from(order) + .innerJoin(order.audioContent, audioContent) + .innerJoin(audioContent.member, member) + .groupBy(member.id, audioContent.id, order.can) + .offset(offset) + .limit(limit) + .orderBy(member.id.desc(), audioContent.id.asc()) + .fetch() + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/AdminCalculateService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/AdminCalculateService.kt index d97f1d8..1044ff5 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/AdminCalculateService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/AdminCalculateService.kt @@ -134,4 +134,44 @@ class AdminCalculateService(private val repository: AdminCalculateQueryRepositor } .toList() } + + fun getCumulativeSalesByContent(offset: Long, limit: Long): GetCumulativeSalesByContentResponse { + val totalCount = repository.getCumulativeSalesByContentTotalCount() + val items = repository + .getCumulativeSalesByContent(offset, limit) + .asSequence() + .map { + // 원화 = totalCoin * 100 ( 캔 1개 = 100원 ) + val totalKrw = it.totalCan * 100 + + // 결제수수료 : 6.6% + val paymentFee = totalKrw * 0.066f + + // 정산금액 = (원화 - 결제수수료) 의 70% + val settlementAmount = (totalKrw.toFloat() - paymentFee) * 0.7 + + // 원천세 = 정산금액의 3.3% + val tax = settlementAmount * 0.033 + + // 입금액 + val depositAmount = settlementAmount - tax + + CumulativeSalesByContentItem( + nickname = it.nickname, + title = it.title, + registrationDate = it.registrationDate, + orderPrice = it.orderPrice, + numberOfPeople = it.numberOfPeople.toInt(), + totalCan = it.totalCan, + totalKrw = totalKrw, + paymentFee = paymentFee.roundToInt(), + settlementAmount = settlementAmount.roundToInt(), + tax = tax.roundToInt(), + depositAmount = depositAmount.roundToInt() + ) + } + .toList() + + return GetCumulativeSalesByContentResponse(totalCount, items) + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/GetCumulativeSalesByContentResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/GetCumulativeSalesByContentResponse.kt new file mode 100644 index 0000000..5ea0c98 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/GetCumulativeSalesByContentResponse.kt @@ -0,0 +1,38 @@ +package kr.co.vividnext.sodalive.admin.calculate + +import com.fasterxml.jackson.annotation.JsonProperty +import com.querydsl.core.annotations.QueryProjection + +data class GetCumulativeSalesByContentQueryData @QueryProjection constructor( + // 등록 크리에이터 닉네임 + val nickname: String, + // 콘텐츠 제목 + val title: String, + // 콘텐츠 등록 날짜 + val registrationDate: String, + // 판매 금액(캔) + val orderPrice: Int, + // 인원 + val numberOfPeople: Long, + // 합계 + val totalCan: Int +) + +data class GetCumulativeSalesByContentResponse( + @JsonProperty("totalCount") val totalCount: Int, + @JsonProperty("items") val items: List +) + +data class CumulativeSalesByContentItem( + @JsonProperty("nickname") val nickname: String, + @JsonProperty("title") val title: String, + @JsonProperty("registrationDate") val registrationDate: String, + @JsonProperty("orderPrice") val orderPrice: Int, + @JsonProperty("numberOfPeople") val numberOfPeople: Int, + @JsonProperty("totalCan") val totalCan: Int, + @JsonProperty("totalKrw") val totalKrw: Int, + @JsonProperty("paymentFee") val paymentFee: Int, + @JsonProperty("settlementAmount") val settlementAmount: Int, + @JsonProperty("tax") val tax: Int, + @JsonProperty("depositAmount") val depositAmount: Int +)