크리에이터 관리자 - 콘텐츠 누적 매출 API #81
| @@ -12,6 +12,11 @@ import kotlin.math.roundToInt | |||||||
|  |  | ||||||
| @Service | @Service | ||||||
| class AdminCalculateService(private val repository: AdminCalculateQueryRepository) { | class AdminCalculateService(private val repository: AdminCalculateQueryRepository) { | ||||||
|  |     @Transactional(readOnly = true) | ||||||
|  |     @Cacheable( | ||||||
|  |         cacheNames = ["default"], | ||||||
|  |         key = "'calculateLive:' + " + "#startDateStr + ':' + #endDateStr" | ||||||
|  |     ) | ||||||
|     fun getCalculateLive(startDateStr: String, endDateStr: String): List<GetCalculateLiveResponse> { |     fun getCalculateLive(startDateStr: String, endDateStr: String): List<GetCalculateLiveResponse> { | ||||||
|         val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") |         val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") | ||||||
|         val startDate = LocalDate.parse(startDateStr, dateTimeFormatter).atTime(0, 0, 0) |         val startDate = LocalDate.parse(startDateStr, dateTimeFormatter).atTime(0, 0, 0) | ||||||
| @@ -135,6 +140,11 @@ class AdminCalculateService(private val repository: AdminCalculateQueryRepositor | |||||||
|             .toList() |             .toList() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Transactional(readOnly = true) | ||||||
|  |     @Cacheable( | ||||||
|  |         cacheNames = ["cache_ttl_3_hours"], | ||||||
|  |         key = "'cumulativeSalesByContent:' + " + "#offset + ':' + #limit" | ||||||
|  |     ) | ||||||
|     fun getCumulativeSalesByContent(offset: Long, limit: Long): GetCumulativeSalesByContentResponse { |     fun getCumulativeSalesByContent(offset: Long, limit: Long): GetCumulativeSalesByContentResponse { | ||||||
|         val totalCount = repository.getCumulativeSalesByContentTotalCount() |         val totalCount = repository.getCumulativeSalesByContentTotalCount() | ||||||
|         val items = repository |         val items = repository | ||||||
|   | |||||||
| @@ -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())) | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,8 +6,10 @@ import com.querydsl.core.types.dsl.StringTemplate | |||||||
| import com.querydsl.jpa.impl.JPAQueryFactory | import com.querydsl.jpa.impl.JPAQueryFactory | ||||||
| import kr.co.vividnext.sodalive.admin.calculate.GetCalculateContentQueryData | import kr.co.vividnext.sodalive.admin.calculate.GetCalculateContentQueryData | ||||||
| import kr.co.vividnext.sodalive.admin.calculate.GetCalculateLiveQueryData | 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.QGetCalculateContentQueryData | ||||||
| import kr.co.vividnext.sodalive.admin.calculate.QGetCalculateLiveQueryData | 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.QUseCan.useCan | ||||||
| import kr.co.vividnext.sodalive.can.use.QUseCanCalculate.useCanCalculate | import kr.co.vividnext.sodalive.can.use.QUseCanCalculate.useCanCalculate | ||||||
| import kr.co.vividnext.sodalive.can.use.UseCanCalculateStatus | import kr.co.vividnext.sodalive.can.use.UseCanCalculateStatus | ||||||
| @@ -142,4 +144,44 @@ class CreatorAdminCalculateQueryRepository(private val queryFactory: JPAQueryFac | |||||||
|             "%Y-%m-%d" |             "%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<GetCumulativeSalesByContentQueryData> { | ||||||
|  |         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() | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,9 @@ | |||||||
| package kr.co.vividnext.sodalive.creator.admin.calculate | 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.GetCalculateContentResponse | ||||||
| import kr.co.vividnext.sodalive.admin.calculate.GetCalculateLiveResponse | 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.can.use.CanUsage | ||||||
| import kr.co.vividnext.sodalive.content.order.OrderType | import kr.co.vividnext.sodalive.content.order.OrderType | ||||||
| import kr.co.vividnext.sodalive.member.Member | import kr.co.vividnext.sodalive.member.Member | ||||||
| @@ -138,4 +140,51 @@ class CreatorAdminCalculateService(private val repository: CreatorAdminCalculate | |||||||
|  |  | ||||||
|         return GetCalculateContentListResponse(totalCount, items) |         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) | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user