Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] 참여자별 정산 현황 조회 및 액션 이력 조회 수정 #377

Merged
merged 6 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import server.haengdong.application.response.MemberBillReportAppResponse;
import server.haengdong.domain.action.BillAction;
import server.haengdong.domain.action.BillActionRepository;
Expand All @@ -15,6 +16,7 @@
import server.haengdong.exception.HaengdongException;

@RequiredArgsConstructor
@Transactional(readOnly = true)
@Service
public class ActionService {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,22 @@ public record ActionAppResponse(
String name,
Long price,
Long sequence,
boolean isFixed,
ActionType actionType
) {

public ActionAppResponse(Long actionId, String name, Long price, Long sequence, ActionType actionType) {
this(actionId, name, price, sequence, false, actionType);
}

public static ActionAppResponse of(BillAction billAction) {
return new ActionAppResponse(
billAction.getAction().getId(),
billAction.getTitle(),
billAction.getPrice(),
billAction.getSequence(),
ActionType.BILL
billAction.isFixed(),
ActionAppResponse.ActionType.BILL
);
}

Expand All @@ -30,7 +36,8 @@ public static ActionAppResponse of(MemberAction memberAction) {
memberAction.getMemberName(),
null,
memberAction.getSequence(),
ActionType.of(status)
false,
ActionAppResponse.ActionType.of(status)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -24,6 +27,7 @@ public class BillAction implements Comparable<BillAction> {
public static final int MAX_TITLE_LENGTH = 30;
public static final long MIN_PRICE = 1L;
public static final long MAX_PRICE = 10_000_000L;
private static final long DEFAULT_PRICE = 0L;

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -37,17 +41,27 @@ public class BillAction implements Comparable<BillAction> {

private Long price;

private boolean isFixed;

@OneToMany(mappedBy = "billAction", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private List<BillActionDetail> billActionDetails = new ArrayList<>();

public BillAction(Action action, String title, Long price) {
this(null, action, title, price);
this(null, action, title, price, false); // TODO: 수정 필요
}

private BillAction(Long id, Action action, String title, Long price) {
public BillAction(Action action, String title, Long price, boolean isFixed) {
this(null, action, title, price, isFixed);
}

private BillAction(Long id, Action action, String title, Long price, boolean isFixed) {
validateTitle(title);
validatePrice(price);
this.id = id;
this.action = action;
this.title = title.trim();
this.price = price;
this.isFixed = isFixed;
}

private void validateTitle(String title) {
Expand All @@ -64,7 +78,7 @@ private void validatePrice(Long price) {
}

public BillAction update(String title, Long price) {
return new BillAction(id, action, title, price);
return new BillAction(id, action, title, price, isFixed);
}

public Long getSequence() {
Expand All @@ -75,6 +89,23 @@ public Event getEvent() {
return action.getEvent();
}

public Long findPriceByMemberName(String memberName) {
return billActionDetails.stream()
.filter(billActionDetail -> billActionDetail.isMemberMatch(memberName))
.map(BillActionDetail::getPrice)
.findFirst()
.orElse(DEFAULT_PRICE);
}

public void addDetails(List<BillActionDetail> billActionDetails) {
billActionDetails.forEach(this::addDetail);
}

private void addDetail(BillActionDetail billActionDetail) {
this.billActionDetails.add(billActionDetail);
billActionDetail.setBillAction(this);
}

@Override
public int compareTo(BillAction o) {
return Long.compare(this.getSequence(), o.getSequence());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,17 @@ public class BillActionDetail {
private String memberName;

private Long price;

public BillActionDetail(String memberName, Long price) {
this.memberName = memberName;
this.price = price;
}

public void setBillAction(BillAction billAction) {
this.billAction = billAction;
}

public boolean isMemberMatch(String memberName) {
return this.memberName.equals(memberName);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isMemberMatch 의미는 같은 맴버인지 확인하는 메서드라는 걸 알겠지만,
메서드 이름에서 맴버의 이름으로 같은지 확인한다는 것이 드러나면 좋을 것 같아요.
어떤게 더 좋을지 모르겠네요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금 프로젝트에서 memberName이 member의 역할을 하고 있어서 그런 거 같기도 해요. 비교하는 대상이 명확하게 드러나는 게 더 좋은 것 같아서 hasMemberName으로 수정했습니다 :)

}
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ private static void addBillAction(
return;
}

Long pricePerMember = billAction.getPrice() / currentMembers.size();
for (String currentMember : currentMembers.getMembers()) {
Long price = memberBillReports.get(currentMember) + pricePerMember;
Long currentPrice = billAction.findPriceByMemberName(currentMember);
Long price = memberBillReports.get(currentMember) + currentPrice;
memberBillReports.put(currentMember, price);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,21 @@ public record ActionResponse(
Long actionId,
String name,
Long price,
Long sequence
Long sequence,
boolean isFixed
) {

public ActionResponse(Long actionId, String name, Long price, Long sequence) {
this(actionId, name, price, sequence, false);
}

public static ActionResponse of(ActionAppResponse actionAppResponse) {
return new ActionResponse(
actionAppResponse.actionId(),
actionAppResponse.name(),
actionAppResponse.price(),
actionAppResponse.sequence()
actionAppResponse.sequence(),
actionAppResponse.isFixed()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import server.haengdong.application.response.MemberBillReportAppResponse;
import server.haengdong.domain.action.Action;
import server.haengdong.domain.action.BillAction;
import server.haengdong.domain.action.BillActionDetail;
import server.haengdong.domain.action.BillActionRepository;
import server.haengdong.domain.action.MemberAction;
import server.haengdong.domain.action.MemberActionRepository;
Expand Down Expand Up @@ -49,9 +50,21 @@ void getMemberBillReports() {
);
List<BillAction> billActions = List.of(
new BillAction(new Action(savedEvent, 4L), "뽕족", 60_000L),
new BillAction(new Action(savedEvent, 6L), "인생맥주", 40_000L),
new BillAction(new Action(savedEvent, 7L), "인생네컷", 20_000L)
);
billActions.get(0).addDetails(
List.of(
new BillActionDetail("소하", 10_000L),
new BillActionDetail("감자", 40_000L),
new BillActionDetail("쿠키", 10_000L)
)
);
billActions.get(1).addDetails(
List.of(
new BillActionDetail("소하", 5_000L),
new BillActionDetail("쿠키", 15_000L)
)
);
memberActionRepository.saveAll(memberActions);
billActionRepository.saveAll(billActions);

Expand All @@ -61,9 +74,9 @@ void getMemberBillReports() {
.hasSize(3)
.extracting(MemberBillReportAppResponse::name, MemberBillReportAppResponse::price)
.containsExactlyInAnyOrder(
tuple("감자", 20_000L),
tuple("쿠키", 50_000L),
tuple("소하", 50_000L)
tuple("감자", 40_000L),
tuple("쿠키", 25_000L),
tuple("소하", 15_000L)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,27 +72,27 @@ void saveEvent() throws Exception {
given(authService.getTokenName()).willReturn("eventToken");

mockMvc.perform(post("/api/events")
.contentType(MediaType.APPLICATION_JSON)
.content(requestBody))
.contentType(MediaType.APPLICATION_JSON)
.content(requestBody))
.andDo(print())
.andExpect(status().isOk())
.andExpect(cookie().value("eventToken", "jwtToken"))
.andExpect(jsonPath("$.eventId").value("쿠키 토큰"))
.andDo(
document("createEvent",
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint()),
requestFields(
fieldWithPath("eventName").type(JsonFieldType.STRING).description("행사 이름"),
fieldWithPath("password").type(JsonFieldType.STRING).description("행사 비밀 번호")
),
responseFields(
fieldWithPath("eventId").type(JsonFieldType.STRING)
.description("행사 ID")
),
responseCookies(
cookieWithName("eventToken").description("행사 관리자용 토큰")
)
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint()),
requestFields(
fieldWithPath("eventName").type(JsonFieldType.STRING).description("행사 이름"),
fieldWithPath("password").type(JsonFieldType.STRING).description("행사 비밀 번호")
),
responseFields(
fieldWithPath("eventId").type(JsonFieldType.STRING)
.description("행사 ID")
),
responseCookies(
cookieWithName("eventToken").description("행사 관리자용 토큰")
)
)
);
}
Expand All @@ -110,14 +110,14 @@ void findEventTest() throws Exception {
.andExpect(jsonPath("$.eventName").value("행동대장 회식"))
.andDo(
document("getEvent",
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint()),
pathParameters(
parameterWithName("eventId").description("행사 ID")
),
responseFields(
fieldWithPath("eventName").type(JsonFieldType.STRING).description("행사 이름")
)
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint()),
pathParameters(
parameterWithName("eventId").description("행사 ID")
),
responseFields(
fieldWithPath("eventName").type(JsonFieldType.STRING).description("행사 이름")
)
)
);
}
Expand Down Expand Up @@ -178,8 +178,10 @@ void updateMember() throws Exception {
),
requestFields(
fieldWithPath("members").type(JsonFieldType.ARRAY).description("수정할 참여자 목록"),
fieldWithPath("members[].before").type(JsonFieldType.STRING).description("수정 전 참여자 이름"),
fieldWithPath("members[].after").type(JsonFieldType.STRING).description("수정 후 참여자 이름")
fieldWithPath("members[].before").type(JsonFieldType.STRING)
.description("수정 전 참여자 이름"),
fieldWithPath("members[].after").type(JsonFieldType.STRING)
.description("수정 후 참여자 이름")
)
)
);
Expand Down Expand Up @@ -278,7 +280,9 @@ void findActions() throws Exception {
fieldWithPath("steps[].actions[].price").type(JsonFieldType.NUMBER).optional()
.description("참여자 액션일 경우 null, 지출 액션일 경우 지출 금액"),
fieldWithPath("steps[].actions[].sequence").type(JsonFieldType.NUMBER)
.description("액션 순서")
.description("액션 순서"),
fieldWithPath("steps[].actions[].isFixed").type(JsonFieldType.BOOLEAN)
.description("지출 액션의 지출 고정 금액이 설정 여부")
)
)
);
Expand All @@ -289,20 +293,20 @@ void findActions() throws Exception {
void authenticateTest() throws Exception {
String token = "TOKEN";
mockMvc.perform(post("/api/events/{eventId}/auth", token)
.cookie(EVENT_COOKIE))
.cookie(EVENT_COOKIE))
.andDo(print())
.andExpect(status().isOk())

.andDo(
document("authenticateEvent",
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint()),
pathParameters(
parameterWithName("eventId").description("행사 ID")
),
requestCookies(
cookieWithName("eventToken").description("행사 관리자 토큰").optional()
)
preprocessRequest(prettyPrint()),
preprocessResponse(prettyPrint()),
pathParameters(
parameterWithName("eventId").description("행사 ID")
),
requestCookies(
cookieWithName("eventToken").description("행사 관리자 토큰").optional()
)
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,21 @@ void createByActions() {
Event event = Fixture.EVENT1;
List<BillAction> billActions = List.of(
new BillAction(new Action(event, 4L), "뽕족", 60_000L),
new BillAction(new Action(event, 6L), "인생맥주", 40_000L),
new BillAction(new Action(event, 7L), "인생네컷", 20_000L)
);
billActions.get(0).addDetails(
List.of(
new BillActionDetail("소하", 10_000L),
new BillActionDetail("감자", 40_000L),
new BillActionDetail("쿠키", 10_000L)
)
);
billActions.get(1).addDetails(
List.of(
new BillActionDetail("소하", 5_000L),
new BillActionDetail("쿠키", 15_000L)
)
);
List<MemberAction> memberActions = List.of(
new MemberAction(new Action(event, 1L), "소하", IN, 1L),
new MemberAction(new Action(event, 2L), "감자", IN, 1L),
Expand All @@ -34,9 +46,9 @@ void createByActions() {
assertThat(memberBillReport.getReports())
.containsAllEntriesOf(
Map.of(
"감자", 20_000L,
"쿠키", 50_000L,
"소하", 50_000L
"감자", 40_000L,
"쿠키", 25_000L,
"소하", 15_000L
)
);
}
Expand Down
Loading