From 68be926b4e094fc71edb81c8e5085d225a00382f Mon Sep 17 00:00:00 2001 From: Arachne <66822642+Arachneee@users.noreply.github.com> Date: Fri, 16 Aug 2024 16:38:52 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=EC=95=A1=EC=85=98=20=EC=9D=B4?= =?UTF-8?q?=EB=A0=A5=20=EC=A1=B0=ED=9A=8C=20v2=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#375)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/EventController.java | 11 ++++ .../response/ActionResponse2.java | 22 +++++++ .../response/ActionsResponse.java | 14 +++++ .../docs/EventControllerDocsTest.java | 63 +++++++++++++++++++ 4 files changed, 110 insertions(+) create mode 100644 server/src/main/java/server/haengdong/presentation/response/ActionResponse2.java create mode 100644 server/src/main/java/server/haengdong/presentation/response/ActionsResponse.java diff --git a/server/src/main/java/server/haengdong/presentation/EventController.java b/server/src/main/java/server/haengdong/presentation/EventController.java index 54de966e5..34261042f 100644 --- a/server/src/main/java/server/haengdong/presentation/EventController.java +++ b/server/src/main/java/server/haengdong/presentation/EventController.java @@ -1,6 +1,7 @@ package server.haengdong.presentation; import jakarta.validation.Valid; +import java.util.List; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -15,10 +16,12 @@ import org.springframework.web.bind.annotation.RestController; import server.haengdong.application.AuthService; import server.haengdong.application.EventService; +import server.haengdong.application.response.ActionAppResponse; import server.haengdong.infrastructure.auth.CookieProperties; import server.haengdong.presentation.request.EventLoginRequest; import server.haengdong.presentation.request.EventSaveRequest; import server.haengdong.presentation.request.MemberNamesUpdateRequest; +import server.haengdong.presentation.response.ActionsResponse; import server.haengdong.presentation.response.EventDetailResponse; import server.haengdong.presentation.response.EventResponse; import server.haengdong.presentation.response.MembersResponse; @@ -60,6 +63,14 @@ public ResponseEntity findActions(@PathVariable("eventId") String return ResponseEntity.ok(stepsResponse); } + @GetMapping("/api/events/{eventId}/actions/v2") + public ResponseEntity findActions2(@PathVariable("eventId") String token) { + List actions = eventService.findActions(token); + ActionsResponse actionsResponse = ActionsResponse.of(actions); + + return ResponseEntity.ok(actionsResponse); + } + @GetMapping("/api/events/{eventId}/members") public ResponseEntity findAllMembers(@PathVariable("eventId") String token) { MembersResponse response = MembersResponse.of(eventService.findAllMembers(token)); diff --git a/server/src/main/java/server/haengdong/presentation/response/ActionResponse2.java b/server/src/main/java/server/haengdong/presentation/response/ActionResponse2.java new file mode 100644 index 000000000..ea46c5bd9 --- /dev/null +++ b/server/src/main/java/server/haengdong/presentation/response/ActionResponse2.java @@ -0,0 +1,22 @@ +package server.haengdong.presentation.response; + +import server.haengdong.application.response.ActionAppResponse; + +public record ActionResponse2( + Long actionId, + String name, + Long price, + Long sequence, + String type +) { + + public static ActionResponse2 of(ActionAppResponse actionAppResponse) { + return new ActionResponse2( + actionAppResponse.actionId(), + actionAppResponse.name(), + actionAppResponse.price(), + actionAppResponse.sequence(), + actionAppResponse.actionType().name() + ); + } +} diff --git a/server/src/main/java/server/haengdong/presentation/response/ActionsResponse.java b/server/src/main/java/server/haengdong/presentation/response/ActionsResponse.java new file mode 100644 index 000000000..88c0184ec --- /dev/null +++ b/server/src/main/java/server/haengdong/presentation/response/ActionsResponse.java @@ -0,0 +1,14 @@ +package server.haengdong.presentation.response; + +import java.util.List; +import server.haengdong.application.response.ActionAppResponse; + +public record ActionsResponse( + List actions +) { + public static ActionsResponse of(List actions) { + return new ActionsResponse(actions.stream() + .map(ActionResponse2::of) + .toList()); + } +} diff --git a/server/src/test/java/server/haengdong/docs/EventControllerDocsTest.java b/server/src/test/java/server/haengdong/docs/EventControllerDocsTest.java index 09546bcc3..39c023d45 100644 --- a/server/src/test/java/server/haengdong/docs/EventControllerDocsTest.java +++ b/server/src/test/java/server/haengdong/docs/EventControllerDocsTest.java @@ -284,6 +284,69 @@ void findActions() throws Exception { ); } + @DisplayName("행사 전체 액션 이력 조회 v2") + @Test + void findActions2() throws Exception { + String token = "TOKEN"; + List actionAppResponses = List.of( + new ActionAppResponse(1L, "망쵸", null, 1L, ActionType.IN), + new ActionAppResponse(2L, "족발", 100L, 2L, ActionType.BILL), + new ActionAppResponse(3L, "인생네컷", 1000L, 3L, ActionType.BILL), + new ActionAppResponse(4L, "망쵸", null, 4L, ActionType.OUT) + ); + given(eventService.findActions(token)).willReturn(actionAppResponses); + + mockMvc.perform(get("/api/events/{eventId}/actions/v2", token) + .accept(MediaType.APPLICATION_JSON)) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.actions[0].actionId").value(equalTo(1))) + .andExpect(jsonPath("$.actions[0].name").value(equalTo("망쵸"))) + .andExpect(jsonPath("$.actions[0].price").value(equalTo(null))) + .andExpect(jsonPath("$.actions[0].sequence").value(equalTo(1))) + .andExpect(jsonPath("$.actions[0].type").value(equalTo("IN"))) + + .andExpect(jsonPath("$.actions[1].actionId").value(equalTo(2))) + .andExpect(jsonPath("$.actions[1].name").value(equalTo("족발"))) + .andExpect(jsonPath("$.actions[1].price").value(equalTo(100))) + .andExpect(jsonPath("$.actions[1].sequence").value(equalTo(2))) + .andExpect(jsonPath("$.actions[1].type").value(equalTo("BILL"))) + + .andExpect(jsonPath("$.actions[2].actionId").value(equalTo(3))) + .andExpect(jsonPath("$.actions[2].name").value(equalTo("인생네컷"))) + .andExpect(jsonPath("$.actions[2].price").value(equalTo(1000))) + .andExpect(jsonPath("$.actions[2].sequence").value(equalTo(3))) + .andExpect(jsonPath("$.actions[2].type").value(equalTo("BILL"))) + + .andExpect(jsonPath("$.actions[3].actionId").value(equalTo(4))) + .andExpect(jsonPath("$.actions[3].name").value(equalTo("망쵸"))) + .andExpect(jsonPath("$.actions[3].price").value(equalTo(null))) + .andExpect(jsonPath("$.actions[3].sequence").value(equalTo(4))) + .andExpect(jsonPath("$.actions[3].type").value(equalTo("OUT"))) + + .andDo( + document("findActions", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + pathParameters( + parameterWithName("eventId").description("행사 ID") + ), + responseFields( + fieldWithPath("actions[].actionId").type(JsonFieldType.NUMBER) + .description("액션 ID"), + fieldWithPath("actions[].name").type(JsonFieldType.STRING) + .description("참여자 액션일 경우 참여자 이름, 지출 액션일 경우 지출 내역 이름"), + fieldWithPath("actions[].price").type(JsonFieldType.NUMBER).optional() + .description("참여자 액션일 경우 null, 지출 액션일 경우 지출 금액"), + fieldWithPath("actions[].sequence").type(JsonFieldType.NUMBER) + .description("액션 순서"), + fieldWithPath("actions[].type").type(JsonFieldType.STRING) + .description("액션 타입") + ) + ) + ); + } + @DisplayName("행사 어드민 권한을 확인한다.") @Test void authenticateTest() throws Exception { From 45f147de0f963adca9edf59b82ceb7cc0e5ab26c Mon Sep 17 00:00:00 2001 From: Arachne <66822642+Arachneee@users.noreply.github.com> Date: Fri, 16 Aug 2024 17:47:13 +0900 Subject: [PATCH 2/2] =?UTF-8?q?[BE]=20=ED=96=89=EC=82=AC=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC=20=EC=9D=B8=EC=9B=90=20=EB=98=90=EB=8A=94=20=EC=A7=80?= =?UTF-8?q?=EC=B6=9C=20=EC=B4=9D=EC=95=A1=20=EB=B3=80=EB=8F=99=EC=8B=9C=20?= =?UTF-8?q?=EC=B0=A8=EB=93=B1=20=EC=A0=95=EC=82=B0=20=EC=B4=88=EA=B8=B0?= =?UTF-8?q?=ED=99=94=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20(#370)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 지출 액션 수정시 지출 디테일 초기화 기능 구현 * feat: 맴버 액션 삭제시 지출 디테일 초기화 기능 구현 * feat: 맴버 삭제시 지출 디테일 초기화 기능 구현 * fix: 버그 수정 * fix: 버그 수정 --- .../application/BillActionService.java | 16 ++++ .../application/MemberActionService.java | 30 ++++++- .../domain/action/BillActionDetail.java | 10 +++ .../action/BillActionDetailRepository.java | 5 ++ .../domain/action/BillActionRepository.java | 8 ++ .../domain/action/CurrentMembers.java | 4 + .../domain/action/MemberActionRepository.java | 7 ++ .../application/BillActionServiceTest.java | 38 ++++++++ .../application/MemberActionServiceTest.java | 87 +++++++++++++++++++ 9 files changed, 203 insertions(+), 2 deletions(-) diff --git a/server/src/main/java/server/haengdong/application/BillActionService.java b/server/src/main/java/server/haengdong/application/BillActionService.java index 468508d07..de79f9f5f 100644 --- a/server/src/main/java/server/haengdong/application/BillActionService.java +++ b/server/src/main/java/server/haengdong/application/BillActionService.java @@ -9,6 +9,8 @@ import server.haengdong.domain.action.Action; import server.haengdong.domain.action.ActionRepository; import server.haengdong.domain.action.BillAction; +import server.haengdong.domain.action.BillActionDetail; +import server.haengdong.domain.action.BillActionDetailRepository; import server.haengdong.domain.action.BillActionRepository; import server.haengdong.domain.event.Event; import server.haengdong.domain.event.EventRepository; @@ -23,6 +25,7 @@ public class BillActionService { private final BillActionRepository billActionRepository; private final ActionRepository actionRepository; private final EventRepository eventRepository; + private final BillActionDetailRepository billActionDetailRepository; @Transactional public void saveAllBillAction(String eventToken, List requests) { @@ -49,10 +52,23 @@ public void updateBillAction(String token, Long actionId, BillActionUpdateAppReq validateToken(token, billAction); + resetBillActionDetail(billAction, request.price()); + BillAction updatedBillAction = billAction.update(request.title(), request.price()); billActionRepository.save(updatedBillAction); } + private void resetBillActionDetail(BillAction billAction, Long updatePrice) { + if (billAction.getPrice() != updatePrice) { + List billActionDetails = billActionDetailRepository.findByBillAction(billAction); + int memberCount = billActionDetails.size(); + if (memberCount != 0) { + Long eachPrice = updatePrice / memberCount; + billActionDetails.forEach(billActionDetail -> billActionDetail.updatePrice(eachPrice)); + } + } + } + private void validateToken(String token, BillAction billAction) { Event event = billAction.getEvent(); if (event.isTokenMismatch(token)) { diff --git a/server/src/main/java/server/haengdong/application/MemberActionService.java b/server/src/main/java/server/haengdong/application/MemberActionService.java index 79318fa98..5b9416888 100644 --- a/server/src/main/java/server/haengdong/application/MemberActionService.java +++ b/server/src/main/java/server/haengdong/application/MemberActionService.java @@ -8,6 +8,10 @@ import server.haengdong.application.response.CurrentMemberAppResponse; import server.haengdong.domain.action.Action; import server.haengdong.domain.action.ActionRepository; +import server.haengdong.domain.action.BillAction; +import server.haengdong.domain.action.BillActionDetail; +import server.haengdong.domain.action.BillActionDetailRepository; +import server.haengdong.domain.action.BillActionRepository; import server.haengdong.domain.action.CurrentMembers; import server.haengdong.domain.action.MemberAction; import server.haengdong.domain.action.MemberActionRepository; @@ -25,6 +29,8 @@ public class MemberActionService { private final MemberActionRepository memberActionRepository; private final EventRepository eventRepository; private final ActionRepository actionRepository; + private final BillActionDetailRepository billActionDetailRepository; + private final BillActionRepository billActionRepository; @Transactional public void saveMemberAction(String token, MemberActionsSaveAppRequest request) { @@ -65,6 +71,9 @@ public void deleteMember(String token, String memberName) { .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.EVENT_NOT_FOUND)); memberActionRepository.deleteAllByEventAndMemberName(event, memberName); + + List billActions = billActionRepository.findByAction_Event(event); + billActions.forEach(billAction -> resetBillAction(event, billAction)); } @Transactional @@ -76,7 +85,24 @@ public void deleteMemberAction(String token, Long actionId) { MemberAction memberAction = memberActionRepository.findByAction(action) .orElseThrow(() -> new HaengdongException(HaengdongErrorCode.MEMBER_ACTION_NOT_FOUND)); - memberActionRepository.deleteAllByMemberNameAndMinSequence(memberAction.getMemberName(), - memberAction.getSequence()); + memberActionRepository.deleteAllByMemberNameAndMinSequence(memberAction.getMemberName(), memberAction.getSequence()); + + List billActions = billActionRepository.findByEventAndGreaterThanSequence(event, action.getSequence()); + billActions.forEach(billAction -> resetBillAction(event, billAction)); + } + + private void resetBillAction(Event event, BillAction billAction) { + List memberActions = memberActionRepository.findByEventAndSequence(event, billAction.getSequence()); + CurrentMembers currentMembers = CurrentMembers.of(memberActions); + + billActionDetailRepository.deleteAllByBillAction(billAction); + + if (currentMembers.isNotEmpty()) { + Long eachPrice = billAction.getPrice() / currentMembers.size(); + for (String member : currentMembers.getMembers()) { + BillActionDetail billActionDetail = new BillActionDetail(billAction, member, eachPrice); + billActionDetailRepository.save(billActionDetail); + } + } } } diff --git a/server/src/main/java/server/haengdong/domain/action/BillActionDetail.java b/server/src/main/java/server/haengdong/domain/action/BillActionDetail.java index 6cd01a667..161a6663b 100644 --- a/server/src/main/java/server/haengdong/domain/action/BillActionDetail.java +++ b/server/src/main/java/server/haengdong/domain/action/BillActionDetail.java @@ -25,4 +25,14 @@ public class BillActionDetail { private String memberName; private Long price; + + public BillActionDetail(BillAction billAction, String memberName, Long price) { + this.billAction = billAction; + this.memberName = memberName; + this.price = price; + } + + public void updatePrice(Long price) { + this.price = price; + } } diff --git a/server/src/main/java/server/haengdong/domain/action/BillActionDetailRepository.java b/server/src/main/java/server/haengdong/domain/action/BillActionDetailRepository.java index eb910eabf..3bda6d020 100644 --- a/server/src/main/java/server/haengdong/domain/action/BillActionDetailRepository.java +++ b/server/src/main/java/server/haengdong/domain/action/BillActionDetailRepository.java @@ -1,8 +1,13 @@ package server.haengdong.domain.action; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface BillActionDetailRepository extends JpaRepository { + + List findByBillAction(BillAction billAction); + + void deleteAllByBillAction(BillAction billAction); } diff --git a/server/src/main/java/server/haengdong/domain/action/BillActionRepository.java b/server/src/main/java/server/haengdong/domain/action/BillActionRepository.java index a0e6a1bf1..817a63bf8 100644 --- a/server/src/main/java/server/haengdong/domain/action/BillActionRepository.java +++ b/server/src/main/java/server/haengdong/domain/action/BillActionRepository.java @@ -4,6 +4,7 @@ import java.util.Optional; import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; import server.haengdong.domain.event.Event; @@ -16,4 +17,11 @@ public interface BillActionRepository extends JpaRepository { void deleteByAction_EventAndActionId(Event event, Long actionId); Optional findByAction_Id(Long actionId); + + @Query(""" + select ba + from BillAction ba + where ba.action.event = :event and ba.action.sequence > :sequence + """) + List findByEventAndGreaterThanSequence(Event event, Long sequence); } diff --git a/server/src/main/java/server/haengdong/domain/action/CurrentMembers.java b/server/src/main/java/server/haengdong/domain/action/CurrentMembers.java index 7706c05d1..9a85c6075 100644 --- a/server/src/main/java/server/haengdong/domain/action/CurrentMembers.java +++ b/server/src/main/java/server/haengdong/domain/action/CurrentMembers.java @@ -67,6 +67,10 @@ public boolean isEmpty() { return members.isEmpty(); } + public boolean isNotEmpty() { + return !isEmpty(); + } + public int size() { return members.size(); } diff --git a/server/src/main/java/server/haengdong/domain/action/MemberActionRepository.java b/server/src/main/java/server/haengdong/domain/action/MemberActionRepository.java index 8cf9e42cf..324ff9797 100644 --- a/server/src/main/java/server/haengdong/domain/action/MemberActionRepository.java +++ b/server/src/main/java/server/haengdong/domain/action/MemberActionRepository.java @@ -43,4 +43,11 @@ public interface MemberActionRepository extends JpaRepository findAllByAction_EventAndMemberName(Event event, String memberName); boolean existsByAction_EventAndMemberName(Event event, String updatedMemberName); + + @Query(""" + select ma + from MemberAction ma + where ma.action.event = :event and ma.action.sequence < :sequence + """) + List findByEventAndSequence(Event event, Long sequence); } diff --git a/server/src/test/java/server/haengdong/application/BillActionServiceTest.java b/server/src/test/java/server/haengdong/application/BillActionServiceTest.java index 51eaa6e0b..f43fe8968 100644 --- a/server/src/test/java/server/haengdong/application/BillActionServiceTest.java +++ b/server/src/test/java/server/haengdong/application/BillActionServiceTest.java @@ -13,6 +13,8 @@ import server.haengdong.application.request.BillActionUpdateAppRequest; import server.haengdong.domain.action.Action; import server.haengdong.domain.action.BillAction; +import server.haengdong.domain.action.BillActionDetail; +import server.haengdong.domain.action.BillActionDetailRepository; import server.haengdong.domain.action.BillActionRepository; import server.haengdong.domain.event.Event; import server.haengdong.domain.event.EventRepository; @@ -30,6 +32,9 @@ class BillActionServiceTest extends ServiceTestSupport { @Autowired private BillActionRepository billActionRepository; + @Autowired + private BillActionDetailRepository billActionDetailRepository; + @DisplayName("지출 내역을 생성한다.") @Test void saveAllBillAction() { @@ -107,6 +112,39 @@ void updateBillAction1() { .isInstanceOf(HaengdongException.class); } + @DisplayName("지출 내역 금액을 변경하면 지출 디테일이 초기화 된다.") + @Test + void updateBillAction2() { + Event event = Fixture.EVENT1; + Event savedEvent = eventRepository.save(event); + Action action = Action.createFirst(savedEvent); + BillAction billAction = new BillAction(action, "뽕족", 10_000L); + BillAction savedBillAction = billActionRepository.save(billAction); + BillActionDetail billActionDetail1 = new BillActionDetail(savedBillAction, "감자", 3000L); + BillActionDetail billActionDetail2 = new BillActionDetail(savedBillAction, "고구마", 2000L); + BillActionDetail billActionDetail3 = new BillActionDetail(savedBillAction, "당근", 3000L); + BillActionDetail billActionDetail4 = new BillActionDetail(savedBillAction, "양파", 2000L); + + billActionDetailRepository.saveAll(List.of(billActionDetail1, billActionDetail2, billActionDetail3, billActionDetail4)); + + Long actionId = savedBillAction.getAction().getId(); + BillActionUpdateAppRequest request = new BillActionUpdateAppRequest("인생맥주", 20_000L); + + billActionService.updateBillAction(event.getToken(), actionId, request); + + BillAction updatedBillAction = billActionRepository.findById(savedBillAction.getId()).get(); + List billActionDetails = billActionDetailRepository.findByBillAction(updatedBillAction); + + assertThat(billActionDetails).hasSize(4) + .extracting("memberName", "price") + .containsExactlyInAnyOrder( + tuple("감자", 5000L), + tuple("고구마", 5000L), + tuple("당근", 5000L), + tuple("양파", 5000L) + ); + } + @DisplayName("지출 내역을 삭제한다.") @Test void deleteBillAction() { diff --git a/server/src/test/java/server/haengdong/application/MemberActionServiceTest.java b/server/src/test/java/server/haengdong/application/MemberActionServiceTest.java index 8f0af8dfe..14a7d4225 100644 --- a/server/src/test/java/server/haengdong/application/MemberActionServiceTest.java +++ b/server/src/test/java/server/haengdong/application/MemberActionServiceTest.java @@ -14,6 +14,10 @@ import server.haengdong.application.request.MemberActionSaveAppRequest; import server.haengdong.application.request.MemberActionsSaveAppRequest; import server.haengdong.domain.action.Action; +import server.haengdong.domain.action.BillAction; +import server.haengdong.domain.action.BillActionDetail; +import server.haengdong.domain.action.BillActionDetailRepository; +import server.haengdong.domain.action.BillActionRepository; import server.haengdong.domain.action.MemberAction; import server.haengdong.domain.action.MemberActionRepository; import server.haengdong.domain.action.MemberActionStatus; @@ -33,6 +37,12 @@ class MemberActionServiceTest extends ServiceTestSupport { @Autowired private EventRepository eventRepository; + @Autowired + private BillActionRepository billActionRepository; + + @Autowired + private BillActionDetailRepository billActionDetailRepository; + @DisplayName("현재 행사에 참여하고 있는 경우에 나갈 수 있다.") @Test void saveMemberActionTest() { @@ -115,6 +125,44 @@ void deleteMember() { ); } + @DisplayName("이벤트에 속한 멤버을 삭제하면 전체 지출 내역 디테일이 초기화된다.") + @Test + void deleteMember1() { + Event event = Fixture.EVENT1; + eventRepository.save(event); + MemberAction memberAction1 = createMemberAction(new Action(event, 1L), "토다리", IN, 1L); + Action targetAction = new Action(event, 2L); + MemberAction memberAction2 = createMemberAction(targetAction, "토다리", OUT, 2L); + MemberAction memberAction3 = createMemberAction(new Action(event, 3L), "쿠키", IN, 3L); + MemberAction memberAction4 = createMemberAction(new Action(event, 4L), "웨디", IN, 4L); + MemberAction memberAction5 = createMemberAction(new Action(event, 5L), "감자", IN, 5L); + memberActionRepository.saveAll( + List.of(memberAction1, + memberAction2, + memberAction3, + memberAction4, + memberAction5 + ) + ); + BillAction billAction = new BillAction(new Action(event, 6L), "뽕족", 100_000L); + billActionRepository.save(billAction); + BillActionDetail billActionDetail1 = new BillActionDetail(billAction, "쿠키", 40_000L); + BillActionDetail billActionDetail2 = new BillActionDetail(billAction, "웨디", 30_000L); + BillActionDetail billActionDetail3 = new BillActionDetail(billAction, "감자", 30_000L); + billActionDetailRepository.saveAll(List.of(billActionDetail1, billActionDetail2, billActionDetail3)); + + memberActionService.deleteMember(event.getToken(), "쿠키"); + + List billActionDetails = billActionDetailRepository.findByBillAction(billAction); + + assertThat(billActionDetails).hasSize(2) + .extracting("memberName", "price") + .containsExactlyInAnyOrder( + tuple("웨디", 50_000L), + tuple("감자", 50_000L) + ); + } + @DisplayName("이벤트에 속한 멤버 액션을 삭제하면 이후에 기록된 해당 참여자의 모든 멤버 액션을 삭제한다.") @Test void deleteMemberAction() { @@ -151,6 +199,45 @@ void deleteMemberAction() { ); } + @DisplayName("이벤트에 속한 멤버 액션을 삭제하면 이후 지출 내역 디테일이 초기화된다.") + @Test + void deleteMemberAction1() { + Event event = Fixture.EVENT1; + eventRepository.save(event); + MemberAction memberAction1 = createMemberAction(new Action(event, 1L), "토다리", IN, 1L); + Action targetAction = new Action(event, 2L); + MemberAction memberAction2 = createMemberAction(targetAction, "토다리", OUT, 2L); + MemberAction memberAction3 = createMemberAction(new Action(event, 3L), "쿠키", IN, 3L); + MemberAction memberAction4 = createMemberAction(new Action(event, 4L), "웨디", IN, 4L); + MemberAction memberAction5 = createMemberAction(new Action(event, 5L), "감자", IN, 5L); + memberActionRepository.saveAll( + List.of(memberAction1, + memberAction2, + memberAction3, + memberAction4, + memberAction5 + ) + ); + BillAction billAction = new BillAction(new Action(event, 6L), "뽕족", 100_000L); + billActionRepository.save(billAction); + BillActionDetail billActionDetail1 = new BillActionDetail(billAction, "쿠키", 40_000L); + BillActionDetail billActionDetail2 = new BillActionDetail(billAction, "웨디", 30_000L); + BillActionDetail billActionDetail3 = new BillActionDetail(billAction, "감자", 30_000L); + billActionDetailRepository.saveAll(List.of(billActionDetail1, billActionDetail2, billActionDetail3)); + + memberActionService.deleteMemberAction(event.getToken(), targetAction.getId()); + List billActionDetails = billActionDetailRepository.findByBillAction(billAction); + + assertThat(billActionDetails).hasSize(4) + .extracting("memberName", "price") + .containsExactlyInAnyOrder( + tuple("토다리", 25_000L), + tuple("쿠키", 25_000L), + tuple("웨디", 25_000L), + tuple("감자", 25_000L) + ); + } + private MemberAction createMemberAction( Action action, String memberName,