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 d528a94..5f859b6 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 @@ -12,6 +12,11 @@ import kotlin.math.roundToInt @Service class AdminCalculateService(private val repository: AdminCalculateQueryRepository) { + @Transactional(readOnly = true) + @Cacheable( + cacheNames = ["default"], + key = "'calculateLive:' + " + "#startDateStr + ':' + #endDateStr" + ) fun getCalculateLive(startDateStr: String, endDateStr: String): List { val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") val startDate = LocalDate.parse(startDateStr, dateTimeFormatter).atTime(0, 0, 0) @@ -135,6 +140,11 @@ class AdminCalculateService(private val repository: AdminCalculateQueryRepositor .toList() } + @Transactional(readOnly = true) + @Cacheable( + cacheNames = ["cache_ttl_3_hours"], + key = "'cumulativeSalesByContent:' + " + "#offset + ':' + #limit" + ) fun getCumulativeSalesByContent(offset: Long, limit: Long): GetCumulativeSalesByContentResponse { val totalCount = repository.getCumulativeSalesByContentTotalCount() val items = repository diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/CreatorAdminCalculateController.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/CreatorAdminCalculateController.kt index 99646c1..409c472 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/CreatorAdminCalculateController.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/CreatorAdminCalculateController.kt @@ -43,4 +43,14 @@ class CreatorAdminCalculateController(private val service: CreatorAdminCalculate ) ) } + + @GetMapping("/cumulative-sales-by-content") + fun getCumulativeSalesByContent( + @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?, + pageable: Pageable + ) = run { + if (member == null) throw SodaException("로그인 정보를 확인해주세요.") + + ApiResponse.ok(service.getCumulativeSalesByContent(member.id!!, pageable.offset, pageable.pageSize.toLong())) + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/CreatorAdminCalculateQueryRepository.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/CreatorAdminCalculateQueryRepository.kt index 99c3814..0a9e488 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/CreatorAdminCalculateQueryRepository.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/CreatorAdminCalculateQueryRepository.kt @@ -6,8 +6,10 @@ import com.querydsl.core.types.dsl.StringTemplate import com.querydsl.jpa.impl.JPAQueryFactory import kr.co.vividnext.sodalive.admin.calculate.GetCalculateContentQueryData import kr.co.vividnext.sodalive.admin.calculate.GetCalculateLiveQueryData +import kr.co.vividnext.sodalive.admin.calculate.GetCumulativeSalesByContentQueryData import kr.co.vividnext.sodalive.admin.calculate.QGetCalculateContentQueryData import kr.co.vividnext.sodalive.admin.calculate.QGetCalculateLiveQueryData +import kr.co.vividnext.sodalive.admin.calculate.QGetCumulativeSalesByContentQueryData 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 @@ -142,4 +144,44 @@ class CreatorAdminCalculateQueryRepository(private val queryFactory: JPAQueryFac "%Y-%m-%d" ) } + + fun getCumulativeSalesByContentTotalCount(memberId: Long): Int { + return queryFactory + .select(audioContent.id) + .from(order) + .innerJoin(order.audioContent, audioContent) + .innerJoin(audioContent.member, member) + .where(audioContent.member.id.eq(memberId)) + .groupBy(member.id, audioContent.id, order.can) + .fetch() + .size + } + + fun getCumulativeSalesByContent( + memberId: Long, + offset: Long, + limit: Long + ): List { + return queryFactory + .select( + QGetCumulativeSalesByContentQueryData( + member.nickname, + audioContent.title, + getFormattedDate(audioContent.createdAt), + order.type, + order.can, + order.id.count(), + order.can.sum() + ) + ) + .from(order) + .innerJoin(order.audioContent, audioContent) + .innerJoin(audioContent.member, member) + .where(audioContent.member.id.eq(memberId)) + .groupBy(member.id, audioContent.id, order.type, order.can) + .offset(offset) + .limit(limit) + .orderBy(member.id.desc(), audioContent.id.desc()) + .fetch() + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/CreatorAdminCalculateService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/CreatorAdminCalculateService.kt index fda18dc..e4dedeb 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/CreatorAdminCalculateService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/CreatorAdminCalculateService.kt @@ -1,7 +1,9 @@ package kr.co.vividnext.sodalive.creator.admin.calculate +import kr.co.vividnext.sodalive.admin.calculate.CumulativeSalesByContentItem import kr.co.vividnext.sodalive.admin.calculate.GetCalculateContentResponse import kr.co.vividnext.sodalive.admin.calculate.GetCalculateLiveResponse +import kr.co.vividnext.sodalive.admin.calculate.GetCumulativeSalesByContentResponse import kr.co.vividnext.sodalive.can.use.CanUsage import kr.co.vividnext.sodalive.content.order.OrderType import kr.co.vividnext.sodalive.member.Member @@ -138,4 +140,51 @@ class CreatorAdminCalculateService(private val repository: CreatorAdminCalculate return GetCalculateContentListResponse(totalCount, items) } + + fun getCumulativeSalesByContent(memberId: Long, offset: Long, limit: Long): GetCumulativeSalesByContentResponse { + val totalCount = repository.getCumulativeSalesByContentTotalCount(memberId) + val items = repository + .getCumulativeSalesByContent(memberId, offset, limit) + .asSequence() + .map { + val orderTypeStr = if (it.orderType == OrderType.RENTAL) { + "대여" + } else { + "소장" + } + + // 원화 = 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, + orderType = orderTypeStr, + 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) + } }