Skip to content

Commit

Permalink
Merge pull request #135 from Team-Going/feature/133
Browse files Browse the repository at this point in the history
[feat] 여행 TODO 상세 조회 API 스펙 및 비즈니스 로직 변경
  • Loading branch information
SunwoongH authored Mar 3, 2024
2 parents 136570f + 64f9110 commit 9929558
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 14 deletions.
1 change: 1 addition & 0 deletions doorip-api/src/main/java/org/doorip/common/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ public abstract class Constants {
public static final int PROPENSITY_WEIGHT = 25;
public static final int MAX_PARTICIPANT_COUNT = 6;
public static final int MIN_PARTICIPANT_COUNT = 1;
public static final int TODO_OWNER_POSITION = 0;
}
5 changes: 5 additions & 0 deletions doorip-api/src/main/java/org/doorip/trip/api/TodoApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ ResponseEntity<BaseResponse<?>> getTripTodos(@Parameter(hidden = true)
responseCode = "401",
description = "액세스 토큰이 만료되었습니다. 재발급 받아주세요.",
content = @Content),
@ApiResponse(
responseCode = "404",
description = "존재하지 않는 여행입니다.",
content = @Content),
@ApiResponse(
responseCode = "404",
description = "존재하지 않는 여행 TODO입니다.",
Expand All @@ -142,6 +146,7 @@ ResponseEntity<BaseResponse<?>> getTripTodos(@Parameter(hidden = true)
content = @Content)})
ResponseEntity<BaseResponse<?>> getTripTodo(@Parameter(hidden = true)
@UserId final Long userId,
@PathVariable final Long tripId,
@PathVariable final Long todoId);

@Operation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ public ResponseEntity<BaseResponse<?>> getTripTodos(@UserId final Long userId,
return ApiResponseUtil.success(SuccessMessage.OK, response);
}

@GetMapping("/todos/{todoId}")
@GetMapping("/{tripId}/todos/{todoId}")
@Override
public ResponseEntity<BaseResponse<?>> getTripTodo(@UserId final Long userId,
@PathVariable final Long tripId,
@PathVariable final Long todoId) {
final TodoDetailGetResponse response = todoService.getTripTodo(userId, todoId);
final TodoDetailGetResponse response = todoService.getTripTodo(userId, tripId, todoId);
return ApiResponseUtil.success(SuccessMessage.OK, response);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.doorip.trip.dto.response;

import lombok.AccessLevel;
import lombok.Builder;
import org.doorip.trip.domain.Participant;

@Builder(access = AccessLevel.PRIVATE)
public record TodoDetailAllocatorResponse(
Long participantId,
String name,
boolean isOwner,
boolean isAllocated
) {
public static TodoDetailAllocatorResponse of(String name, boolean isOwner, boolean isAllocated, Participant participant) {
return TodoDetailAllocatorResponse.builder()
.participantId(participant.getId())
.name(name)
.isOwner(isOwner)
.isAllocated(isAllocated)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ public record TodoDetailGetResponse(
String title,
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy.MM.dd", timezone = "Asia/Seoul")
LocalDate endDate,
List<TodoAllocatorResponse> allocators,
List<TodoDetailAllocatorResponse> allocators,
String memo,
boolean secret
) {
public static TodoDetailGetResponse of(Todo todo, List<TodoAllocatorResponse> allocators) {
public static TodoDetailGetResponse of(Todo todo, List<TodoDetailAllocatorResponse> allocators) {
return TodoDetailGetResponse.builder()
.title(todo.getTitle())
.endDate(todo.getEndDate())
Expand Down
71 changes: 61 additions & 10 deletions doorip-api/src/main/java/org/doorip/trip/service/TodoService.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
import org.doorip.trip.domain.*;
import org.doorip.trip.dto.request.TodoCreateRequest;
import org.doorip.trip.dto.response.TodoAllocatorResponse;
import org.doorip.trip.dto.response.TodoDetailAllocatorResponse;
import org.doorip.trip.dto.response.TodoDetailGetResponse;
import org.doorip.trip.dto.response.TodoGetResponse;
import org.doorip.trip.repository.ParticipantRepository;
import org.doorip.trip.repository.TodoRepository;
import org.doorip.trip.repository.TripRepository;
import org.doorip.user.domain.User;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -25,9 +27,9 @@
@Transactional(readOnly = true)
@Service
public class TodoService {
private final TodoRepository todoRepository;
private final TripRepository tripRepository;
private final ParticipantRepository participantRepository;
private final TodoRepository todoRepository;

@Transactional
public void createTripTodo(Long tripId, TodoCreateRequest request) {
Expand All @@ -43,10 +45,10 @@ public List<TodoGetResponse> getTripTodos(Long userId, Long tripId, String categ
return getTripTodosResponse(userId, todos);
}

public TodoDetailGetResponse getTripTodo(Long userId, Long todoId) {
public TodoDetailGetResponse getTripTodo(Long userId, Long tripId, Long todoId) {
Trip findTrip = getTrip(tripId);
Todo findTodo = getTodo(todoId);
List<TodoAllocatorResponse> allocatorResponses = getAndSortAllocatorsResponses(userId, findTodo);
return TodoDetailGetResponse.of(findTodo, allocatorResponses);
return getTripTodoResponse(userId, findTrip, findTodo);
}

@Transactional
Expand All @@ -72,11 +74,6 @@ private void validateAllocators(List<Long> allocators) {
}
}

private Trip getTrip(Long tripId) {
return tripRepository.findById(tripId)
.orElseThrow(() -> new EntityNotFoundException(ErrorMessage.TRIP_NOT_FOUND));
}

private Todo createTodo(TodoCreateRequest request, Trip trip) {
return Todo.createTodo(request.title(), request.endDate(), request.memo(), Secret.of(request.secret()), trip);
}
Expand Down Expand Up @@ -106,6 +103,16 @@ private List<TodoGetResponse> getTripTodosResponse(Long userId, List<Todo> todos
return response;
}

private Trip getTrip(Long tripId) {
return tripRepository.findById(tripId)
.orElseThrow(() -> new EntityNotFoundException(ErrorMessage.TRIP_NOT_FOUND));
}

private TodoDetailGetResponse getTripTodoResponse(Long userId, Trip findTrip, Todo findTodo) {
List<TodoDetailAllocatorResponse> allocatorResponses = getAndSortAllocatorResponses(userId, findTrip, findTodo);
return TodoDetailGetResponse.of(findTodo, allocatorResponses);
}

private Todo getTodo(Long todoId) {
return todoRepository.findById(todoId)
.orElseThrow(() -> new EntityNotFoundException(ErrorMessage.TODO_NOT_FOUND));
Expand Down Expand Up @@ -142,6 +149,13 @@ private List<TodoAllocatorResponse> getAndSortAllocatorsResponses(Long userId, T
return allocatorResponses;
}

private List<TodoDetailAllocatorResponse> getAndSortAllocatorResponses(Long userId, Trip findTrip, Todo findTodo) {
List<Participant> participants = findTrip.getParticipants();
Participant ownerParticipant = getOwnerParticipant(userId, participants);
sortParticipants(ownerParticipant, participants);
List<Allocator> allocators = findTodo.getAllocators();
return getAllocatorResponses(ownerParticipant, participants, allocators);
}

private List<TodoAllocatorResponse> getAllocatorResponses(Long userId, List<Allocator> allocators) {
return new ArrayList<>(allocators.stream()
Expand All @@ -159,7 +173,44 @@ private TodoAllocatorResponse getOwnerAllocator(List<TodoAllocatorResponse> allo
private void sortAllocators(TodoAllocatorResponse ownerAllocator, List<TodoAllocatorResponse> allocatorResponses) {
if (ownerAllocator != null) {
allocatorResponses.remove(ownerAllocator);
allocatorResponses.add(0, ownerAllocator);
allocatorResponses.add(Constants.TODO_OWNER_POSITION, ownerAllocator);
}
}

private Participant getOwnerParticipant(Long userId, List<Participant> participants) {
return participants.stream()
.filter(participant -> isOwnerParticipant(userId, participant))
.findFirst()
.orElse(null);
}

private void sortParticipants(Participant ownerParticipant, List<Participant> participants) {
if (ownerParticipant != null) {
participants.remove(ownerParticipant);
participants.add(Constants.TODO_OWNER_POSITION, ownerParticipant);
}
}

private List<TodoDetailAllocatorResponse> getAllocatorResponses(Participant ownerParticipant, List<Participant> participants, List<Allocator> allocators) {
return participants.stream()
.map(participant -> {
boolean isAllocated = allocators.stream()
.anyMatch(allocator -> isAllocatedParticipant(allocator, participant));
User findUser = participant.getUser();
return TodoDetailAllocatorResponse.of(findUser.getName(), participant == ownerParticipant, isAllocated, participant);
})
.toList();
}

private boolean isOwnerParticipant(Long userId, Participant participant) {
User findUser = participant.getUser();
Long findUserId = findUser.getId();
return findUserId.equals(userId);
}

private boolean isAllocatedParticipant(Allocator allocator, Participant participant) {
Participant findParticipant = allocator.getParticipant();
Long findParticipantId = findParticipant.getId();
return findParticipantId.equals(participant.getId());
}
}

0 comments on commit 9929558

Please sign in to comment.