Merge pull request '콘텐츠 누적 매출 API 추가' (#79) from test into main
Reviewed-on: #79
This commit is contained in:
		| @@ -1,6 +1,7 @@ | |||||||
| package kr.co.vividnext.sodalive.admin.calculate | package kr.co.vividnext.sodalive.admin.calculate | ||||||
|  |  | ||||||
| import kr.co.vividnext.sodalive.common.ApiResponse | import kr.co.vividnext.sodalive.common.ApiResponse | ||||||
|  | import org.springframework.data.domain.Pageable | ||||||
| import org.springframework.security.access.prepost.PreAuthorize | import org.springframework.security.access.prepost.PreAuthorize | ||||||
| import org.springframework.web.bind.annotation.GetMapping | import org.springframework.web.bind.annotation.GetMapping | ||||||
| import org.springframework.web.bind.annotation.RequestMapping | import org.springframework.web.bind.annotation.RequestMapping | ||||||
| @@ -22,4 +23,9 @@ class AdminCalculateController(private val service: AdminCalculateService) { | |||||||
|         @RequestParam startDateStr: String, |         @RequestParam startDateStr: String, | ||||||
|         @RequestParam endDateStr: String |         @RequestParam endDateStr: String | ||||||
|     ) = ApiResponse.ok(service.getCalculateContentList(startDateStr, endDateStr)) |     ) = ApiResponse.ok(service.getCalculateContentList(startDateStr, endDateStr)) | ||||||
|  |  | ||||||
|  |     @GetMapping("/cumulative-sales-by-content") | ||||||
|  |     fun getCumulativeSalesByContent(pageable: Pageable) = ApiResponse.ok( | ||||||
|  |         service.getCumulativeSalesByContent(pageable.offset, pageable.pageSize.toLong()) | ||||||
|  |     ) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -89,4 +89,37 @@ class AdminCalculateQueryRepository(private val queryFactory: JPAQueryFactory) { | |||||||
|             "%Y-%m-%d" |             "%Y-%m-%d" | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     fun getCumulativeSalesByContentTotalCount(): Int { | ||||||
|  |         return queryFactory | ||||||
|  |             .select(audioContent.id) | ||||||
|  |             .from(order) | ||||||
|  |             .innerJoin(order.audioContent, audioContent) | ||||||
|  |             .innerJoin(audioContent.member, member) | ||||||
|  |             .groupBy(member.id, audioContent.id, order.can) | ||||||
|  |             .fetch() | ||||||
|  |             .size | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fun getCumulativeSalesByContent(offset: Long, limit: Long): List<GetCumulativeSalesByContentQueryData> { | ||||||
|  |         return queryFactory | ||||||
|  |             .select( | ||||||
|  |                 QGetCumulativeSalesByContentQueryData( | ||||||
|  |                     member.nickname, | ||||||
|  |                     audioContent.title, | ||||||
|  |                     getFormattedDate(audioContent.createdAt), | ||||||
|  |                     order.can, | ||||||
|  |                     order.id.count(), | ||||||
|  |                     order.can.sum() | ||||||
|  |                 ) | ||||||
|  |             ) | ||||||
|  |             .from(order) | ||||||
|  |             .innerJoin(order.audioContent, audioContent) | ||||||
|  |             .innerJoin(audioContent.member, member) | ||||||
|  |             .groupBy(member.id, audioContent.id, order.can) | ||||||
|  |             .offset(offset) | ||||||
|  |             .limit(limit) | ||||||
|  |             .orderBy(member.id.desc(), audioContent.id.asc()) | ||||||
|  |             .fetch() | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -134,4 +134,44 @@ class AdminCalculateService(private val repository: AdminCalculateQueryRepositor | |||||||
|             } |             } | ||||||
|             .toList() |             .toList() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     fun getCumulativeSalesByContent(offset: Long, limit: Long): GetCumulativeSalesByContentResponse { | ||||||
|  |         val totalCount = repository.getCumulativeSalesByContentTotalCount() | ||||||
|  |         val items = repository | ||||||
|  |             .getCumulativeSalesByContent(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 | ||||||
|  |  | ||||||
|  |                 CumulativeSalesByContentItem( | ||||||
|  |                     nickname = it.nickname, | ||||||
|  |                     title = it.title, | ||||||
|  |                     registrationDate = it.registrationDate, | ||||||
|  |                     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) | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,38 @@ | |||||||
|  | package kr.co.vividnext.sodalive.admin.calculate | ||||||
|  |  | ||||||
|  | import com.fasterxml.jackson.annotation.JsonProperty | ||||||
|  | import com.querydsl.core.annotations.QueryProjection | ||||||
|  |  | ||||||
|  | data class GetCumulativeSalesByContentQueryData @QueryProjection constructor( | ||||||
|  |     // 등록 크리에이터 닉네임 | ||||||
|  |     val nickname: String, | ||||||
|  |     // 콘텐츠 제목 | ||||||
|  |     val title: String, | ||||||
|  |     // 콘텐츠 등록 날짜 | ||||||
|  |     val registrationDate: String, | ||||||
|  |     // 판매 금액(캔) | ||||||
|  |     val orderPrice: Int, | ||||||
|  |     // 인원 | ||||||
|  |     val numberOfPeople: Long, | ||||||
|  |     // 합계 | ||||||
|  |     val totalCan: Int | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | data class GetCumulativeSalesByContentResponse( | ||||||
|  |     @JsonProperty("totalCount") val totalCount: Int, | ||||||
|  |     @JsonProperty("items") val items: List<CumulativeSalesByContentItem> | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | data class CumulativeSalesByContentItem( | ||||||
|  |     @JsonProperty("nickname") val nickname: String, | ||||||
|  |     @JsonProperty("title") val title: String, | ||||||
|  |     @JsonProperty("registrationDate") val registrationDate: String, | ||||||
|  |     @JsonProperty("orderPrice") val orderPrice: Int, | ||||||
|  |     @JsonProperty("numberOfPeople") val numberOfPeople: Int, | ||||||
|  |     @JsonProperty("totalCan") val totalCan: Int, | ||||||
|  |     @JsonProperty("totalKrw") val totalKrw: Int, | ||||||
|  |     @JsonProperty("paymentFee") val paymentFee: Int, | ||||||
|  |     @JsonProperty("settlementAmount") val settlementAmount: Int, | ||||||
|  |     @JsonProperty("tax") val tax: Int, | ||||||
|  |     @JsonProperty("depositAmount") val depositAmount: Int | ||||||
|  | ) | ||||||
		Reference in New Issue
	
	Block a user