test #89
| @@ -53,4 +53,23 @@ class CreatorAdminCalculateController(private val service: CreatorAdminCalculate | ||||
|  | ||||
|         ApiResponse.ok(service.getCumulativeSalesByContent(member.id!!, pageable.offset, pageable.pageSize.toLong())) | ||||
|     } | ||||
|  | ||||
|     @GetMapping("/content-donation-list") | ||||
|     fun getCalculateContentDonationList( | ||||
|         @RequestParam startDateStr: String, | ||||
|         @RequestParam endDateStr: String, | ||||
|         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member?, | ||||
|         pageable: Pageable | ||||
|     ) = run { | ||||
|         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||
|         ApiResponse.ok( | ||||
|             service.getCalculateContentDonationList( | ||||
|                 startDateStr, | ||||
|                 endDateStr, | ||||
|                 member.id!!, | ||||
|                 pageable.offset, | ||||
|                 pageable.pageSize.toLong() | ||||
|             ) | ||||
|         ) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -4,12 +4,15 @@ import com.querydsl.core.types.dsl.DateTimePath | ||||
| import com.querydsl.core.types.dsl.Expressions | ||||
| import com.querydsl.core.types.dsl.StringTemplate | ||||
| import com.querydsl.jpa.impl.JPAQueryFactory | ||||
| import kr.co.vividnext.sodalive.admin.calculate.GetCalculateContentDonationQueryData | ||||
| 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.QGetCalculateContentDonationQueryData | ||||
| 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.CanUsage | ||||
| 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 | ||||
| @@ -184,4 +187,63 @@ class CreatorAdminCalculateQueryRepository(private val queryFactory: JPAQueryFac | ||||
|             .orderBy(member.id.desc(), audioContent.id.desc()) | ||||
|             .fetch() | ||||
|     } | ||||
|  | ||||
|     fun getCalculateContentDonationListTotalCount( | ||||
|         startDate: LocalDateTime, | ||||
|         endDate: LocalDateTime, | ||||
|         memberId: Long | ||||
|     ): Int { | ||||
|         val donationFormattedDate = getFormattedDate(useCan.createdAt) | ||||
|         return queryFactory | ||||
|             .select(audioContent.id) | ||||
|             .from(useCan) | ||||
|             .innerJoin(useCan.audioContent, audioContent) | ||||
|             .innerJoin(audioContent.member, member) | ||||
|             .where( | ||||
|                 useCan.isRefund.isFalse | ||||
|                     .and(useCan.canUsage.eq(CanUsage.DONATION)) | ||||
|                     .and(useCan.createdAt.goe(startDate)) | ||||
|                     .and(useCan.createdAt.loe(endDate)) | ||||
|                     .and(audioContent.member.id.eq(memberId)) | ||||
|             ) | ||||
|             .groupBy(donationFormattedDate, audioContent.id) | ||||
|             .fetch() | ||||
|             .size | ||||
|     } | ||||
|  | ||||
|     fun getCalculateContentDonationList( | ||||
|         startDate: LocalDateTime, | ||||
|         endDate: LocalDateTime, | ||||
|         memberId: Long, | ||||
|         offset: Long, | ||||
|         limit: Long | ||||
|     ): List<GetCalculateContentDonationQueryData> { | ||||
|         val donationFormattedDate = getFormattedDate(useCan.createdAt) | ||||
|         return queryFactory | ||||
|             .select( | ||||
|                 QGetCalculateContentDonationQueryData( | ||||
|                     member.nickname, | ||||
|                     audioContent.title, | ||||
|                     getFormattedDate(audioContent.createdAt), | ||||
|                     donationFormattedDate, | ||||
|                     useCan.id.count(), | ||||
|                     useCan.can.add(useCan.rewardCan).sum() | ||||
|                 ) | ||||
|             ) | ||||
|             .from(useCan) | ||||
|             .innerJoin(useCan.audioContent, audioContent) | ||||
|             .innerJoin(audioContent.member, member) | ||||
|             .where( | ||||
|                 useCan.isRefund.isFalse | ||||
|                     .and(useCan.canUsage.eq(CanUsage.DONATION)) | ||||
|                     .and(useCan.createdAt.goe(startDate)) | ||||
|                     .and(useCan.createdAt.loe(endDate)) | ||||
|                     .and(audioContent.member.id.eq(memberId)) | ||||
|             ) | ||||
|             .groupBy(donationFormattedDate, audioContent.id) | ||||
|             .offset(offset) | ||||
|             .limit(limit) | ||||
|             .orderBy(member.id.asc(), donationFormattedDate.desc()) | ||||
|             .fetch() | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| package kr.co.vividnext.sodalive.creator.admin.calculate | ||||
|  | ||||
| import kr.co.vividnext.sodalive.admin.calculate.CumulativeSalesByContentItem | ||||
| import kr.co.vividnext.sodalive.admin.calculate.GetCalculateContentDonationResponse | ||||
| import kr.co.vividnext.sodalive.admin.calculate.GetCalculateContentResponse | ||||
| import kr.co.vividnext.sodalive.admin.calculate.GetCalculateLiveResponse | ||||
| import kr.co.vividnext.sodalive.admin.calculate.GetCumulativeSalesByContentResponse | ||||
| @@ -205,4 +206,62 @@ class CreatorAdminCalculateService(private val repository: CreatorAdminCalculate | ||||
|  | ||||
|         return GetCumulativeSalesByContentResponse(totalCount, items) | ||||
|     } | ||||
|  | ||||
|     @Transactional(readOnly = true) | ||||
|     fun getCalculateContentDonationList( | ||||
|         startDateStr: String, | ||||
|         endDateStr: String, | ||||
|         memberId: Long, | ||||
|         offset: Long, | ||||
|         limit: Long | ||||
|     ): GetCreatorCalculateContentDonationResponse { | ||||
|         val dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") | ||||
|         val startDate = LocalDate.parse(startDateStr, dateTimeFormatter).atTime(0, 0, 0) | ||||
|             .atZone(ZoneId.of("Asia/Seoul")) | ||||
|             .withZoneSameInstant(ZoneId.of("UTC")) | ||||
|             .toLocalDateTime() | ||||
|  | ||||
|         val endDate = LocalDate.parse(endDateStr, dateTimeFormatter).atTime(23, 59, 59) | ||||
|             .atZone(ZoneId.of("Asia/Seoul")) | ||||
|             .withZoneSameInstant(ZoneId.of("UTC")) | ||||
|             .toLocalDateTime() | ||||
|  | ||||
|         val totalCount = repository.getCalculateContentDonationListTotalCount(startDate, endDate, memberId) | ||||
|         val items = repository | ||||
|             .getCalculateContentDonationList(startDate, endDate, memberId, 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 | ||||
|  | ||||
|                 GetCalculateContentDonationResponse( | ||||
|                     nickname = it.nickname, | ||||
|                     title = it.title, | ||||
|                     registrationDate = it.registrationDate, | ||||
|                     donationDate = it.donationDate, | ||||
|                     numberOfDonation = it.numberOfDonation.toInt(), | ||||
|                     totalCan = it.totalCan, | ||||
|                     totalKrw = totalKrw, | ||||
|                     paymentFee = paymentFee.roundToInt(), | ||||
|                     settlementAmount = settlementAmount.roundToInt(), | ||||
|                     tax = tax.roundToInt(), | ||||
|                     depositAmount = depositAmount.roundToInt() | ||||
|                 ) | ||||
|             } | ||||
|             .toList() | ||||
|  | ||||
|         return GetCreatorCalculateContentDonationResponse(totalCount, items) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,9 @@ | ||||
| package kr.co.vividnext.sodalive.creator.admin.calculate | ||||
|  | ||||
| import com.fasterxml.jackson.annotation.JsonProperty | ||||
| import kr.co.vividnext.sodalive.admin.calculate.GetCalculateContentDonationResponse | ||||
|  | ||||
| data class GetCreatorCalculateContentDonationResponse( | ||||
|     @JsonProperty("totalCount") val totalCount: Int, | ||||
|     @JsonProperty("items") val items: List<GetCalculateContentDonationResponse> | ||||
| ) | ||||
		Reference in New Issue
	
	Block a user