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 ad38af1..ef892f3 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 @@ -16,4 +16,10 @@ class AdminCalculateController(private val service: AdminCalculateService) { @RequestParam startDateStr: String, @RequestParam endDateStr: String ) = ApiResponse.ok(service.getCalculateLive(startDateStr, endDateStr)) + + @GetMapping("/content-list") + fun getCalculateContentList( + @RequestParam startDateStr: String, + @RequestParam endDateStr: String + ) = ApiResponse.ok(service.getCalculateContentList(startDateStr, endDateStr)) } 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 7ed389c..d6aa125 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 @@ -1,10 +1,14 @@ package kr.co.vividnext.sodalive.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.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 @@ -13,17 +17,7 @@ import java.time.LocalDateTime @Repository class AdminCalculateQueryRepository(private val queryFactory: JPAQueryFactory) { fun getCalculateLive(startDate: LocalDateTime, endDate: LocalDateTime): List { - val formattedDate = Expressions.stringTemplate( - "DATE_FORMAT({0}, {1})", - Expressions.dateTimeTemplate( - LocalDateTime::class.java, - "CONVERT_TZ({0},{1},{2})", - liveRoom.beginDateTime, - "UTC", - "Asia/Seoul" - ), - "%Y-%m-%d" - ) + val formattedDate = getFormattedDate(liveRoom.beginDateTime) return queryFactory .select( @@ -51,4 +45,48 @@ class AdminCalculateQueryRepository(private val queryFactory: JPAQueryFactory) { .orderBy(member.nickname.desc(), formattedDate.desc()) .fetch() } + + fun getCalculateContentList(startDate: LocalDateTime, endDate: LocalDateTime): 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(order.createdAt.goe(startDate)) + .and(order.createdAt.loe(endDate)) + ) + .groupBy(audioContent.id, order.type, order.createdAt, order.can) + .orderBy(member.id.desc(), orderFormattedDate.desc()) + .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/admin/calculate/AdminCalculateService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/AdminCalculateService.kt index 5434e50..fdaa535 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 @@ -1,6 +1,7 @@ package kr.co.vividnext.sodalive.admin.calculate import kr.co.vividnext.sodalive.can.use.CanUsage +import kr.co.vividnext.sodalive.content.order.OrderType import org.springframework.stereotype.Service import java.time.LocalDate import java.time.ZoneId @@ -70,4 +71,59 @@ class AdminCalculateService(private val repository: AdminCalculateQueryRepositor } .toList() } + + fun getCalculateContentList(startDateStr: String, endDateStr: String): List { + 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() + + return repository + .getCalculateContentList(startDate, endDate) + .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() + } } diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/GetCalculateContentQueryData.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/GetCalculateContentQueryData.kt new file mode 100644 index 0000000..39ca14e --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/GetCalculateContentQueryData.kt @@ -0,0 +1,23 @@ +package kr.co.vividnext.sodalive.admin.calculate + +import com.querydsl.core.annotations.QueryProjection +import kr.co.vividnext.sodalive.content.order.OrderType + +data class GetCalculateContentQueryData @QueryProjection constructor( + // 등록 크리에이터 닉네임 + val nickname: String, + // 콘텐츠 제목 + val title: String, + // 콘텐츠 등록 날짜 + val registrationDate: String, + // 콘텐츠 판매 날짜 + val saleDate: String, + // 대여/소장 구분 + val orderType: OrderType, + // 판매 금액(캔) + val orderPrice: Int, + // 인원 + val numberOfPeople: Long, + // 합계 + val totalCan: Int +) diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/GetCalculateContentResponse.kt b/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/GetCalculateContentResponse.kt new file mode 100644 index 0000000..60381dc --- /dev/null +++ b/src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/GetCalculateContentResponse.kt @@ -0,0 +1,30 @@ +package kr.co.vividnext.sodalive.admin.calculate + +data class GetCalculateContentResponse( + // 등록 크리에이터 닉네임 + val nickname: String, + // 콘텐츠 제목 + val title: String, + // 콘텐츠 등록 날짜 + val registrationDate: String, + // 콘텐츠 판매 날짜 + val saleDate: String, + // 대여/소장 구분 + val orderType: String, + // 판매 금액(캔) + val orderPrice: Int, + // 인원 + val numberOfPeople: Int, + // 합계 + val totalCan: Int, + // 원화 + val totalKrw: Int, + // 수수료 + val paymentFee: Int, + // 정산금액 + val settlementAmount: Int, + // 원천세(세금 3.3%) + val tax: Int, + // 입금액 + val depositAmount: Int +)