Skip to content

Commit

Permalink
[BE] ✨ feat : 비디오별 판매 비율 API merge
Browse files Browse the repository at this point in the history
[BE] ✨ feat : 비디오별 판매 비율 API #494
  • Loading branch information
hobeen-kim authored Sep 28, 2023
2 parents a833124 + f7049c1 commit b8f1e7b
Show file tree
Hide file tree
Showing 10 changed files with 407 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
IMPORTANT: month 를 null 로 주면 연도별 조회, year 을 null 로 주면 전체 조회

[[Adjustment-list]]
== 비디오별 정산 내역
== 비디오별 정산 내역 페이징
=== HTTP Request
include::{snippets}/adjustment/adjustment/http-request.adoc[]
==== Request Headers
Expand Down
24 changes: 24 additions & 0 deletions Server/src/docs/asciidoc/snippets/adjustment/videoadjustment.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
:doctype: book
:icons: font
:source-highlighter: highlightjs
:toc: left
:toclevels: 2
:sectlinks:
:docinfo: shared-head

[[Video-Adjustment]]
= 비디오별 정산 내역 API

IMPORTANT: month 를 null 로 주면 연도별 조회, year 을 null 로 주면 전체 조회

== 비디오별 정산 내역 비율
=== HTTP Request
include::{snippets}/adjustment/calculatevideorate/http-request.adoc[]
==== Request Headers
include::{snippets}/adjustment/calculatevideorate/request-headers.adoc[]
==== Request Query Parameters
include::{snippets}/adjustment/calculatevideorate/request-parameters.adoc[]
=== HTTP Response
include::{snippets}/adjustment/calculatevideorate/http-response.adoc[]
==== Response Fields
include::{snippets}/adjustment/calculatevideorate/response-fields.adoc[]
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.server.domain.adjustment.service.AdjustmentService;
import com.server.domain.adjustment.service.dto.response.AccountResponse;
import com.server.domain.adjustment.service.dto.response.ToTalAdjustmentResponse;
import com.server.domain.adjustment.service.dto.response.VideoAdjustmentResponse;
import com.server.domain.order.controller.dto.request.AdjustmentSort;
import com.server.domain.adjustment.service.dto.response.AdjustmentResponse;
import com.server.global.annotation.LoginId;
Expand All @@ -21,6 +22,7 @@
import javax.validation.constraints.Min;
import javax.validation.constraints.Positive;
import java.net.URI;
import java.util.List;

@RestController
@RequestMapping("/adjustments")
Expand All @@ -46,7 +48,20 @@ public ResponseEntity<ApiPageResponse<AdjustmentResponse>> adjustment(

Page<AdjustmentResponse> response = adjustmentService.adjustment(loginMemberId, page - 1, size, month, year, sort.getSort());

return ResponseEntity.ok(ApiPageResponse.ok(response, getAdjustmentMessage(month, year)));
return ResponseEntity.ok(ApiPageResponse.ok(response, getAdjustmentMessage(month, year) + " 정산 내역"));
}

@GetMapping("/videos")
public ResponseEntity<ApiSingleResponse<List<VideoAdjustmentResponse>>> calculateVideoRate(
@RequestParam(required = false) @Min(value = 1) @Max(value = 12) Integer month,
@RequestParam(required = false) @Min(value = 2020) Integer year,
@LoginId Long loginMemberId) {

checkValidDate(month, year);

List<VideoAdjustmentResponse> total = adjustmentService.calculateVideoRate(loginMemberId, month, year);

return ResponseEntity.ok(ApiSingleResponse.ok(total, getAdjustmentMessage(month, year) + " 비디오 정산 내역"));
}

@GetMapping("/total-adjustment")
Expand All @@ -59,7 +74,7 @@ public ResponseEntity<ApiSingleResponse<ToTalAdjustmentResponse>> calculateAmoun

ToTalAdjustmentResponse total = adjustmentService.totalAdjustment(loginMemberId, month, year);

return ResponseEntity.ok(ApiSingleResponse.ok(total, getAdjustmentMessage(month, year)));
return ResponseEntity.ok(ApiSingleResponse.ok(total, getAdjustmentMessage(month, year) + " 정산 내역"));
}

@GetMapping("/account")
Expand Down Expand Up @@ -91,13 +106,13 @@ private void checkValidDate(Integer month, Integer year) {

private String getAdjustmentMessage(Integer month, Integer year) {
if(month == null && year == null) {
return "전체 정산 내역";
return "전체";
}

if(month != null && year != null) {
return year + "년 " + month + "월 정산 내역";
return year + "년 " + month + "월";
}

return year + "년 정산 내역";
return year + "년";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.server.domain.adjustment.domain.Adjustment;
import com.server.domain.adjustment.repository.dto.AdjustmentData;
import com.server.domain.adjustment.repository.dto.VideoAdjustmentData;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

Expand All @@ -14,4 +15,6 @@ public interface AdjustmentRepositoryCustom {
Integer calculateAmount(Long memberId, Integer month, Integer year);

List<Adjustment> findMonthlyData(Long memberId, Integer year);

List<VideoAdjustmentData> calculateVideo(Long memberId, Integer month, Integer year);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.server.domain.adjustment.repository;

import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.server.domain.adjustment.domain.Adjustment;
import com.server.domain.adjustment.repository.dto.AdjustmentData;
import com.server.domain.adjustment.repository.dto.QVideoAdjustmentData;
import com.server.domain.adjustment.repository.dto.VideoAdjustmentData;
import com.server.domain.order.entity.OrderStatus;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
Expand All @@ -15,6 +19,7 @@
import java.util.stream.Collectors;

import static com.server.domain.adjustment.domain.QAdjustment.*;
import static com.server.domain.order.entity.QOrder.order;
import static com.server.domain.order.entity.QOrderVideo.orderVideo;
import static com.server.domain.video.entity.QVideo.video;

Expand Down Expand Up @@ -64,7 +69,7 @@ public Page<AdjustmentData> findByPeriod(Long memberId, Pageable pageable, Integ
JPAQuery<Long> countQuery = queryFactory.select(video.count())
.from(video)
.join(video.orderVideos, orderVideo)
.where(video.channel.channelId.eq(memberId));
.where(eqMemberId(memberId));

return new PageImpl<>(videoReportDatas, pageable, countQuery.fetchOne());
}
Expand Down Expand Up @@ -98,6 +103,48 @@ public List<Adjustment> findMonthlyData(Long memberId, Integer year) {
.fetch();
}

@Override
public List<VideoAdjustmentData> calculateVideo(Long memberId, Integer month, Integer year) {

return queryFactory.select(
new QVideoAdjustmentData(
video.videoId,
video.videoName,
orderVideo.price.sum()
)
)
.from(video)
.join(video.orderVideos, orderVideo)
.join(orderVideo.order, order)
.where(getCompletedOrder(),
eqMemberId(memberId),
eqOrderYear(year),
eqOrderMonth(month)
)
.groupBy(video.videoId)
.fetch();
}

private Predicate eqOrderYear(Integer year) {
if(year == null) return null;

return order.completedDate.year().eq(year);
}

private Predicate eqOrderMonth(Integer month) {
if(month == null) return null;

return order.completedDate.month().eq(month);
}

private BooleanExpression eqMemberId(Long memberId) {
return video.channel.channelId.eq(memberId);
}

private BooleanExpression getCompletedOrder() {
return orderVideo.orderStatus.eq(OrderStatus.COMPLETED);
}

private BooleanExpression YearEq(Integer year) {

if(year == null) return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.server.domain.adjustment.repository.dto;

import com.querydsl.core.annotations.QueryProjection;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class VideoAdjustmentData {

private Long videoId;
private String videoName;
private Integer amount;

@QueryProjection
public VideoAdjustmentData(Long videoId, String videoName, Integer amount) {
this.videoId = videoId;
this.videoName = videoName;
this.amount = amount;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
import com.server.domain.adjustment.domain.AdjustmentStatus;
import com.server.domain.adjustment.repository.AdjustmentRepository;
import com.server.domain.adjustment.repository.dto.AdjustmentData;
import com.server.domain.adjustment.repository.dto.VideoAdjustmentData;
import com.server.domain.adjustment.service.dto.request.AccountUpdateServiceRequest;
import com.server.domain.adjustment.service.dto.response.AccountResponse;
import com.server.domain.adjustment.service.dto.response.AdjustmentResponse;
import com.server.domain.adjustment.service.dto.response.MonthAdjustmentResponse;
import com.server.domain.adjustment.service.dto.response.ToTalAdjustmentResponse;
import com.server.domain.adjustment.service.dto.response.*;
import com.server.domain.member.entity.Member;
import com.server.domain.member.repository.MemberRepository;
import com.server.global.exception.businessexception.memberexception.MemberNotFoundException;
Expand Down Expand Up @@ -151,6 +149,7 @@ public AccountResponse getAccount(Long loginMemberId) {
return AccountResponse.of(account);
}

@Transactional
public void updateAccount(Long loginMemberId, AccountUpdateServiceRequest request) {

Account account = getAccountOrNull(loginMemberId);
Expand All @@ -162,7 +161,15 @@ public void updateAccount(Long loginMemberId, AccountUpdateServiceRequest reques
}else {
account.updateAccount(request.getName(), request.getAccount(), request.getBank());
}
}

public List<VideoAdjustmentResponse> calculateVideoRate(Long loginMemberId, Integer month, Integer year) {

List<VideoAdjustmentData> datas = adjustmentRepository.calculateVideo(loginMemberId, month, year);

int total = datas.stream().map(VideoAdjustmentData::getAmount).mapToInt(Integer::intValue).sum();

return datas.stream().map(data -> VideoAdjustmentResponse.of(data, total)).collect(Collectors.toList());
}

private Account getAccountOrNull(Long loginMemberId) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.server.domain.adjustment.service.dto.response;

import com.server.domain.adjustment.repository.dto.VideoAdjustmentData;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@AllArgsConstructor
@Builder
@Getter
public class VideoAdjustmentResponse {

private Long videoId;
private String videoName;
private Integer amount;
private Float portion;

public static VideoAdjustmentResponse of(VideoAdjustmentData data, int total) {

float portion = ((float) (data.getAmount())) / total;

return VideoAdjustmentResponse.builder()
.videoId(data.getVideoId())
.videoName(data.getVideoName())
.amount(data.getAmount())
.portion(portion)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

import com.server.domain.adjustment.controller.dto.request.AccountUpdateApiRequest;
import com.server.domain.adjustment.domain.AdjustmentStatus;
import com.server.domain.adjustment.service.dto.response.AccountResponse;
import com.server.domain.adjustment.service.dto.response.AdjustmentResponse;
import com.server.domain.adjustment.service.dto.response.MonthAdjustmentResponse;
import com.server.domain.adjustment.service.dto.response.ToTalAdjustmentResponse;
import com.server.domain.adjustment.service.dto.response.*;
import com.server.domain.order.controller.dto.request.AdjustmentSort;
import com.server.global.reponse.ApiPageResponse;
import com.server.global.reponse.ApiSingleResponse;
Expand All @@ -24,6 +21,7 @@
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.BDDMockito.given;
import static org.springframework.http.MediaType.*;
import static org.springframework.restdocs.headers.HeaderDocumentation.headerWithName;
import static org.springframework.restdocs.headers.HeaderDocumentation.requestHeaders;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
Expand Down Expand Up @@ -293,7 +291,7 @@ void updateAccount() throws Exception {
ResultActions actions = mockMvc.perform(
put(BASE_URL + "/account")
.header(AUTHORIZATION, TOKEN)
.contentType(MediaType.APPLICATION_JSON)
.contentType(APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request))
);

Expand All @@ -317,8 +315,56 @@ void updateAccount() throws Exception {
)
)
);
}

@Test
@DisplayName("월별/연도별 비디오별 정산 내역 API")
void calculateVideoRate() throws Exception {
//given
int size = 5;
int year = 2023;
int month = 9;
List<VideoAdjustmentResponse> response = createVideoAdjustmentResponse(size);

given(adjustmentService.calculateVideoRate(anyLong(), anyInt(), anyInt())).willReturn(response);

String apiResponse = objectMapper.writeValueAsString(ApiSingleResponse.ok(response, year + "년 " + month + "월 비디오 정산 내역"));

//when
ResultActions actions = mockMvc.perform(
get(BASE_URL + "/videos")
.param("year", String.valueOf(year))
.param("month", String.valueOf(month))
.header(AUTHORIZATION, TOKEN)
.accept(APPLICATION_JSON)
);

//then
actions
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string(apiResponse))
;

//restdocs
actions.andDo(
documentHandler.document(
requestHeaders(
headerWithName(AUTHORIZATION).description("액세스 토큰")
),
requestParameters(
parameterWithName("month").description("정산 월").optional(),
parameterWithName("year").description("정산 년도").optional()
),
singleResponseFields(
fieldWithPath("data").description("정산 내역"),
fieldWithPath("data[].videoId").description("비디오 ID"),
fieldWithPath("data[].videoName").description("비디오 이름"),
fieldWithPath("data[].amount").description("해당 기간 정산 금액"),
fieldWithPath("data[].portion").description("해당 기간 판매 비율")
)
)
);
}

private ToTalAdjustmentResponse createToTalAdjustmentResponse(Integer month, Integer year) {
Expand Down Expand Up @@ -367,4 +413,21 @@ private List<AdjustmentResponse> createAdjustmentResponse(int size) {

return responses;
}

private List<VideoAdjustmentResponse> createVideoAdjustmentResponse(int size) {

List<VideoAdjustmentResponse> responses = new ArrayList<>();

for(int i = 1; i <= size; i++) {
VideoAdjustmentResponse response = VideoAdjustmentResponse.builder()
.videoId((long) i)
.videoName("videoName")
.amount(10000)
.portion(0.2f)
.build();

responses.add(response);
}
return responses;
}
}
Loading

0 comments on commit b8f1e7b

Please sign in to comment.