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] 액션 이력 조회 기능 구현 #76

Merged
merged 3 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
@@ -1,10 +1,18 @@
package server.haengdong.application;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import server.haengdong.application.request.EventAppRequest;
import server.haengdong.application.response.ActionAppResponse;
import server.haengdong.application.response.EventAppResponse;
import server.haengdong.application.response.EventDetailAppResponse;
import server.haengdong.domain.action.BillAction;
import server.haengdong.domain.action.BillActionRepository;
import server.haengdong.domain.action.MemberAction;
import server.haengdong.domain.action.MemberActionRepository;
import server.haengdong.domain.event.Event;
import server.haengdong.domain.event.EventRepository;
import server.haengdong.domain.event.EventTokenProvider;
Expand All @@ -17,6 +25,8 @@ public class EventService {

private final EventRepository eventRepository;
private final EventTokenProvider eventTokenProvider;
private final BillActionRepository billActionRepository;
private final MemberActionRepository memberActionRepository;

public EventAppResponse saveEvent(EventAppRequest request) {
String token = eventTokenProvider.createToken();
Expand All @@ -32,4 +42,46 @@ public EventDetailAppResponse findEvent(String token) {

return EventDetailAppResponse.of(event);
}

public List<ActionAppResponse> findActions(String token) {
Event event = eventRepository.findByToken(token).orElseThrow(() -> new IllegalArgumentException(""));

List<BillAction> billActions = billActionRepository.findByAction_Event(event).stream()
.sorted(Comparator.comparing(BillAction::getSequence)).toList();
List<MemberAction> memberActions = memberActionRepository.findAllByEvent(event).stream()
.sorted(Comparator.comparing(MemberAction::getSequence)).toList();

return getActionAppResponses(billActions, memberActions);
}

private List<ActionAppResponse> getActionAppResponses(
List<BillAction> billActions,
List<MemberAction> memberActions
) {
int billActionIndex = 0;
int memberActionIndex = 0;
List<ActionAppResponse> actionAppResponses = new ArrayList<>();

while (billActionIndex < billActions.size() && memberActionIndex < memberActions.size()) {
BillAction billAction = billActions.get(billActionIndex);
MemberAction memberAction = memberActions.get(memberActionIndex);
if (billAction.getSequence() < memberAction.getSequence()) {
actionAppResponses.add(ActionAppResponse.of(billAction));
billActionIndex++;
} else {
actionAppResponses.add(ActionAppResponse.of(memberAction));
memberActionIndex++;
}
}
while (billActionIndex < billActions.size()) {
BillAction billAction = billActions.get(billActionIndex++);
actionAppResponses.add(ActionAppResponse.of(billAction));
}
while (memberActionIndex < memberActions.size()) {
MemberAction memberAction = memberActions.get(memberActionIndex++);
actionAppResponses.add(ActionAppResponse.of(memberAction));
}

return actionAppResponses;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package server.haengdong.application.response;

import server.haengdong.domain.action.BillAction;
import server.haengdong.domain.action.MemberAction;
import server.haengdong.domain.action.MemberActionStatus;

public record ActionAppResponse(
Long actionId,
String name,
Long price,
Long sequence,
ActionType actionType
) {

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

public static ActionAppResponse of(MemberAction memberAction) {
MemberActionStatus status = memberAction.getStatus();

return new ActionAppResponse(
memberAction.getAction().getId(),
memberAction.getMemberName(),
null,
memberAction.getSequence(),
ActionType.of(status)
);
}

public String actionTypeName() {
return actionType.name();
}

public enum ActionType {
BILL,
IN,
OUT,
;

private static ActionType of(MemberActionStatus memberActionStatus) {
if (MemberActionStatus.IN == memberActionStatus) {
return IN;
}
return OUT;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import server.haengdong.presentation.request.EventSaveRequest;
import server.haengdong.presentation.response.EventDetailResponse;
import server.haengdong.presentation.response.EventResponse;
import server.haengdong.presentation.response.StepResponse;

@RequiredArgsConstructor
@RestController
Expand All @@ -32,4 +33,11 @@ public ResponseEntity<EventDetailResponse> findEvent(@PathVariable("eventId") St

return ResponseEntity.ok(eventDetailResponse);
}

@GetMapping("/api/events/{eventId}/actions")
public ResponseEntity<StepResponse> findActions(@PathVariable("eventId") String token) {
StepResponse stepResponse = StepResponse.of(eventService.findActions(token));

return ResponseEntity.ok(stepResponse);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package server.haengdong.presentation.response;

import server.haengdong.application.response.ActionAppResponse;

public record ActionResponse(
Long actionId,
String name,
Long price,
Long sequence
) {

public static ActionResponse of(ActionAppResponse actionAppResponse) {
return new ActionResponse(
actionAppResponse.actionId(),
actionAppResponse.name(),
actionAppResponse.price(),
actionAppResponse.sequence()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package server.haengdong.presentation.response;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import server.haengdong.application.response.ActionAppResponse;

public record ActionsResponse(
String type,
String stepName,
Set<String> members,
List<ActionResponse> actions
) {

public static ActionsResponse of(List<ActionAppResponse> actions, Set<String> members) {
List<ActionResponse> actionResponses = actions.stream()
.map(ActionResponse::of)
.toList();

String actionType = actions.get(0).actionTypeName();
return new ActionsResponse(
actionType,
null,
new HashSet<>(members),
actionResponses
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package server.haengdong.presentation.response;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import server.haengdong.application.response.ActionAppResponse;

public record StepResponse(
List<ActionsResponse> steps
) {

public static StepResponse of(List<ActionAppResponse> actions) {
List<ActionsResponse> actionsResponse = new ArrayList<>();
Set<String> members = new HashSet<>();
ActionAppResponse firstAction = getFirstAction(actions);
List<ActionAppResponse> group = new ArrayList<>();
group.add(firstAction);
String currentActionType = firstAction.actionTypeName();
members.add(firstAction.name());

for (int i = 1; i < actions.size(); i++) {
ActionAppResponse action = actions.get(i);
String typeName = action.actionTypeName();
if (currentActionType.equals(typeName)) {
if (typeName.equals("IN")) {
members.add(action.name());
}
if (typeName.equals("OUT")) {
members.remove(action.name());
}
group.add(action);
continue;
}
if (currentActionType.equals("BILL")) {
actionsResponse.add(ActionsResponse.of(group, members));
} else {
actionsResponse.add(ActionsResponse.of(group, Set.of()));
}
currentActionType = typeName;
group.clear();
if (typeName.equals("IN")) {
members.add(action.name());
}
if (typeName.equals("OUT")) {
members.remove(action.name());
}
group.add(action);
}

if (currentActionType.equals("BILL")) {
actionsResponse.add(ActionsResponse.of(group, members));
} else {
actionsResponse.add(ActionsResponse.of(group, null));
}

return new StepResponse(actionsResponse);
}

private static ActionAppResponse getFirstAction(List<ActionAppResponse> actions) {
return actions.get(0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,27 @@


import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.BDDMockito.given;

import java.util.List;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import server.haengdong.application.request.EventAppRequest;
import server.haengdong.application.response.ActionAppResponse;
import server.haengdong.application.response.EventAppResponse;
import server.haengdong.application.response.EventDetailAppResponse;
import server.haengdong.domain.action.Action;
import server.haengdong.domain.action.ActionRepository;
import server.haengdong.domain.action.BillAction;
import server.haengdong.domain.action.BillActionRepository;
import server.haengdong.domain.action.MemberAction;
import server.haengdong.domain.action.MemberActionRepository;
import server.haengdong.domain.action.MemberActionStatus;
import server.haengdong.domain.event.Event;
import server.haengdong.domain.event.EventRepository;
import server.haengdong.domain.event.EventTokenProvider;
Expand All @@ -29,8 +39,20 @@ class EventServiceTest {
@Autowired
private EventRepository eventRepository;

@Autowired
private ActionRepository actionRepository;

@Autowired
private BillActionRepository billActionRepository;

@Autowired
private MemberActionRepository memberActionRepository;

@AfterEach
void tearDown() {
billActionRepository.deleteAllInBatch();
memberActionRepository.deleteAllInBatch();
actionRepository.deleteAllInBatch();
eventRepository.deleteAllInBatch();
}

Expand All @@ -56,4 +78,33 @@ void findEventTest() {

assertThat(eventDetailAppResponse.eventName()).isEqualTo("행동대장 회식");
}

@DisplayName("행사에 속한 모든 액션을 조회한다.")
@Test
void findActionsTest() {
Event event = new Event("행동대장 회식", "웨디_토큰");
Action action = new Action(event, 1L);
MemberAction memberAction = new MemberAction(action, "토다리", MemberActionStatus.IN, 1L);
Action action1 = new Action(event, 2L);
MemberAction memberAction1 = new MemberAction(action1, "쿠키", MemberActionStatus.IN, 1L);
Action action2 = new Action(event, 3L);
BillAction billAction = new BillAction(action2, "뽕나무쟁이족발", 30000L);
eventRepository.save(event);
memberActionRepository.saveAll(List.of(memberAction, memberAction1));
billActionRepository.save(billAction);

List<ActionAppResponse> actionAppResponses = eventService.findActions("웨디_토큰");

assertThat(actionAppResponses).hasSize(3)
.extracting(ActionAppResponse::actionId,
ActionAppResponse::name,
ActionAppResponse::price,
ActionAppResponse::sequence,
ActionAppResponse::actionTypeName)
.containsExactly(
tuple(1L, "토다리", null, 1L, "IN"),
tuple(2L, "쿠키", null, 2L, "IN"),
tuple(3L, "뽕나무쟁이족발", 30000L, 3L, "BILL")
);
}
}
Loading
Loading