From b3b7f739ff64e90fbfd9ead7da46d7d292f16ee4 Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 13 Nov 2023 18:22:24 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=BD=98=ED=85=90=EC=B8=A0=20=EC=A0=95=EC=82=B0=20?= =?UTF-8?q?-=20API=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/calculate/AdminCalculateService.kt | 1 + .../CreatorAdminCalculateController.kt | 20 +++++ .../CreatorAdminCalculateQueryRepository.kt | 84 +++++++++++++++++++ .../calculate/CreatorAdminCalculateService.kt | 66 +++++++++++++++ .../GetCalculateContentListResponse.kt | 9 ++ 5 files changed, 180 insertions(+) create mode 100644 src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/GetCalculateContentListResponse.kt 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 6fd3d8c..d97f1d8 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 @@ -93,6 +93,7 @@ class AdminCalculateService(private val repository: AdminCalculateQueryRepositor return repository .getCalculateContentList(startDate, endDate) + .asSequence() .map { val orderTypeStr = if (it.orderType == OrderType.RENTAL) { "대여" 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 6c9266c..99646c1 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 @@ -3,6 +3,7 @@ package kr.co.vividnext.sodalive.creator.admin.calculate import kr.co.vividnext.sodalive.common.ApiResponse import kr.co.vividnext.sodalive.common.SodaException import kr.co.vividnext.sodalive.member.Member +import org.springframework.data.domain.Pageable import org.springframework.security.access.prepost.PreAuthorize import org.springframework.security.core.annotation.AuthenticationPrincipal import org.springframework.web.bind.annotation.GetMapping @@ -23,4 +24,23 @@ class CreatorAdminCalculateController(private val service: CreatorAdminCalculate if (member == null) throw SodaException("로그인 정보를 확인해주세요.") ApiResponse.ok(service.getCalculateLive(startDateStr, endDateStr, member)) } + + @GetMapping("/content-list") + fun getCalculateContentList( + @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.getCalculateContentList( + startDateStr, + endDateStr, + 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 bf35b5e..4a1579d 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 @@ -1,12 +1,18 @@ package kr.co.vividnext.sodalive.creator.admin.calculate +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.GetCalculateContentQueryData import kr.co.vividnext.sodalive.admin.calculate.GetCalculateLiveQueryData +import kr.co.vividnext.sodalive.admin.calculate.QGetCalculateContentQueryData import kr.co.vividnext.sodalive.admin.calculate.QGetCalculateLiveQueryData 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 +import kr.co.vividnext.sodalive.content.QAudioContent.audioContent +import kr.co.vividnext.sodalive.content.order.QOrder.order import kr.co.vividnext.sodalive.live.room.QLiveRoom.liveRoom import kr.co.vividnext.sodalive.member.QMember.member import org.springframework.stereotype.Repository @@ -58,4 +64,82 @@ class CreatorAdminCalculateQueryRepository(private val queryFactory: JPAQueryFac .orderBy(formattedDate.desc()) .fetch() } + + fun getCalculateContentListTotalCount( + startDate: LocalDateTime, + endDate: LocalDateTime, + memberId: Long + ): Int { + val orderFormattedDate = getFormattedDate(order.createdAt) + return queryFactory + .select(useCanCalculate.id) + .from(useCanCalculate) + .innerJoin(useCanCalculate.useCan, useCan) + .innerJoin(useCan.order, order) + .innerJoin(order.audioContent, audioContent) + .innerJoin(audioContent.member, member) + .where( + useCanCalculate.status.eq(UseCanCalculateStatus.RECEIVED) + .and(useCanCalculate.recipientCreatorId.eq(memberId)) + .and(order.createdAt.goe(startDate)) + .and(order.createdAt.loe(endDate)) + ) + .groupBy(audioContent.id, order.type, orderFormattedDate, order.can) + .orderBy(member.id.desc(), orderFormattedDate.desc(), audioContent.id.asc()) + .fetch() + .size + } + + fun getCalculateContentList( + startDate: LocalDateTime, + endDate: LocalDateTime, + memberId: Long, + offset: Long = 0, + limit: Long = 20 + ): List { + val orderFormattedDate = getFormattedDate(order.createdAt) + return queryFactory + .select( + QGetCalculateContentQueryData( + member.nickname, + audioContent.title, + getFormattedDate(audioContent.createdAt), + orderFormattedDate, + order.type, + order.can, + order.id.count(), + order.can.sum() + ) + ) + .from(useCanCalculate) + .innerJoin(useCanCalculate.useCan, useCan) + .innerJoin(useCan.order, order) + .innerJoin(order.audioContent, audioContent) + .innerJoin(audioContent.member, member) + .where( + useCanCalculate.status.eq(UseCanCalculateStatus.RECEIVED) + .and(useCanCalculate.recipientCreatorId.eq(memberId)) + .and(order.createdAt.goe(startDate)) + .and(order.createdAt.loe(endDate)) + ) + .groupBy(audioContent.id, order.type, orderFormattedDate, order.can) + .orderBy(member.id.desc(), orderFormattedDate.desc(), audioContent.id.asc()) + .offset(offset) + .limit(limit) + .fetch() + } + + private fun getFormattedDate(dateTimePath: DateTimePath): StringTemplate { + return Expressions.stringTemplate( + "DATE_FORMAT({0}, {1})", + Expressions.dateTimeTemplate( + LocalDateTime::class.java, + "CONVERT_TZ({0},{1},{2})", + dateTimePath, + "UTC", + "Asia/Seoul" + ), + "%Y-%m-%d" + ) + } } 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 636db1f..fda18dc 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.GetCalculateContentResponse import kr.co.vividnext.sodalive.admin.calculate.GetCalculateLiveResponse import kr.co.vividnext.sodalive.can.use.CanUsage +import kr.co.vividnext.sodalive.content.order.OrderType import kr.co.vividnext.sodalive.member.Member import org.springframework.stereotype.Service import java.time.LocalDate @@ -72,4 +74,68 @@ class CreatorAdminCalculateService(private val repository: CreatorAdminCalculate } .toList() } + + fun getCalculateContentList( + startDateStr: String, + endDateStr: String, + memberId: Long, + offset: Long, + limit: Long + ): GetCalculateContentListResponse { + 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.getCalculateContentListTotalCount(startDate, endDate, memberId) + val items = repository.getCalculateContentList(startDate, endDate, 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 + + GetCalculateContentResponse( + nickname = it.nickname, + title = it.title, + registrationDate = it.registrationDate, + saleDate = it.saleDate, + 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 GetCalculateContentListResponse(totalCount, items) + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/GetCalculateContentListResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/GetCalculateContentListResponse.kt new file mode 100644 index 0000000..dbd1d23 --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/GetCalculateContentListResponse.kt @@ -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.GetCalculateContentResponse + +data class GetCalculateContentListResponse( + @JsonProperty("totalCount") val totalCount: Int, + @JsonProperty("items") val items: List +) From 19875a841d0aa5c4b729e60e5a54d78767282d5e Mon Sep 17 00:00:00 2001 From: Klaus Date: Mon, 13 Nov 2023 18:46:49 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=ED=81=AC=EB=A6=AC=EC=97=90=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=BD=98=ED=85=90=EC=B8=A0=20=EC=A0=95=EC=82=B0=20?= =?UTF-8?q?-=20totalCount=20query=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/calculate/CreatorAdminCalculateQueryRepository.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 4a1579d..99c3814 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 @@ -72,7 +72,7 @@ class CreatorAdminCalculateQueryRepository(private val queryFactory: JPAQueryFac ): Int { val orderFormattedDate = getFormattedDate(order.createdAt) return queryFactory - .select(useCanCalculate.id) + .select(audioContent.id) .from(useCanCalculate) .innerJoin(useCanCalculate.useCan, useCan) .innerJoin(useCan.order, order)