diff --git a/src/main/java/org/dnd/timeet/agenda/application/AgendaService.java b/src/main/java/org/dnd/timeet/agenda/application/AgendaService.java index d2c597d..96670fd 100644 --- a/src/main/java/org/dnd/timeet/agenda/application/AgendaService.java +++ b/src/main/java/org/dnd/timeet/agenda/application/AgendaService.java @@ -3,6 +3,7 @@ import java.time.Duration; import java.time.LocalTime; import java.util.Collections; +import java.util.Comparator; import java.util.List; import lombok.RequiredArgsConstructor; import org.dnd.timeet.agenda.domain.Agenda; @@ -35,6 +36,7 @@ public class AgendaService { private final AgendaRepository agendaRepository; private final ParticipantRepository participantRepository; + @Transactional public Long createAgenda(Long meetingId, AgendaCreateRequest createDto, Member member) { Meeting meeting = meetingRepository.findById(meetingId) .orElseThrow(() -> new NotFoundError(ErrorCode.RESOURCE_NOT_FOUND, @@ -48,6 +50,8 @@ public Long createAgenda(Long meetingId, AgendaCreateRequest createDto, Member m } Agenda agenda = createDto.toEntity(meeting); + List agendaList = agendaRepository.findByMeetingId(meetingId); + agenda.setOrderNum(agendaList.size() + 1); agenda = agendaRepository.save(agenda); // 회의 시간 추가 @@ -160,6 +164,36 @@ public AgendaInfoResponse findAgendas(Long meetingId) { .orElseThrow(() -> new NotFoundError(ErrorCode.RESOURCE_NOT_FOUND, Collections.singletonMap("MeetingId", "Meeting not found"))); List agendaList = agendaRepository.findByMeetingId(meetingId); + agendaList.sort(Comparator.comparing(Agenda::getOrderNum)); + return new AgendaInfoResponse(meeting, agendaList); + } + + public AgendaInfoResponse changeAgendaOrder(Long meetingId, List agendaIds) { + Meeting meeting = meetingRepository.findById(meetingId) + .orElseThrow(() -> new NotFoundError(ErrorCode.RESOURCE_NOT_FOUND, + Collections.singletonMap("MeetingId", "Meeting not found"))); + List agendaList = agendaRepository.findByMeetingId(meetingId); + + if (agendaList.size() != agendaIds.size()) { + throw new BadRequestError(BadRequestError.ErrorCode.VALIDATION_FAILED, + Collections.singletonMap("AgendaIds", "Agenda Ids size is not matched")); + } + + if (agendaList.size() != agendaIds.stream().distinct().count()) { + throw new BadRequestError(BadRequestError.ErrorCode.VALIDATION_FAILED, + Collections.singletonMap("AgendaIds", "Agenda Ids are not unique")); + } + + for (int i = 0; i < agendaIds.size(); i++) { + Long agendaId = agendaIds.get(i); + Agenda agenda = agendaList.stream() + .filter(a -> a.getId().equals(agendaId)) + .findFirst() + .orElseThrow(() -> new NotFoundError(ErrorCode.RESOURCE_NOT_FOUND, + Collections.singletonMap("AgendaId", "Agenda Id " + agendaId + " not found"))); + agenda.setOrderNum(i + 1); + } + agendaList.sort(Comparator.comparing(Agenda::getOrderNum)); return new AgendaInfoResponse(meeting, agendaList); } diff --git a/src/main/java/org/dnd/timeet/agenda/controller/AgendaController.java b/src/main/java/org/dnd/timeet/agenda/controller/AgendaController.java index 86057b1..fd103c3 100644 --- a/src/main/java/org/dnd/timeet/agenda/controller/AgendaController.java +++ b/src/main/java/org/dnd/timeet/agenda/controller/AgendaController.java @@ -9,6 +9,7 @@ import org.dnd.timeet.agenda.dto.AgendaActionResponse; import org.dnd.timeet.agenda.dto.AgendaCreateRequest; import org.dnd.timeet.agenda.dto.AgendaInfoResponse; +import org.dnd.timeet.agenda.dto.AgendaOrderRequest; import org.dnd.timeet.agenda.dto.AgendaPatchRequest; import org.dnd.timeet.agenda.dto.AgendaPatchResponse; import org.dnd.timeet.common.security.CustomUserDetails; @@ -85,6 +86,16 @@ public ResponseEntity deleteAgenda( return ResponseEntity.noContent().build(); } + @PatchMapping("/{meeting-id}/agendas/order") + @Operation(summary = "안건 순서 변경", description = "안건의 순서를 변경한다.") + public ResponseEntity> changeAgendaOrder( + @PathVariable("meeting-id") Long meetingId, + @RequestBody @Valid AgendaOrderRequest agendaOrderRequest) { + AgendaInfoResponse agendaInfoResponse = agendaService.changeAgendaOrder(meetingId, + agendaOrderRequest.getAgendaIds()); + return ResponseEntity.ok(ApiUtils.success(agendaInfoResponse)); + } + @PatchMapping("/{meeting-id}/agendas/{agenda-id}") @Operation(summary = "안건 수정", description = "지정된 ID에 해당하는 안건을 수정한다.") public ResponseEntity> deleteAgenda( diff --git a/src/main/java/org/dnd/timeet/agenda/domain/Agenda.java b/src/main/java/org/dnd/timeet/agenda/domain/Agenda.java index 43d2af2..5a9fbd7 100644 --- a/src/main/java/org/dnd/timeet/agenda/domain/Agenda.java +++ b/src/main/java/org/dnd/timeet/agenda/domain/Agenda.java @@ -75,6 +75,9 @@ public Agenda(Meeting meeting, String title, AgendaType type, Duration allocated this.orderNum = orderNum; } + public void setOrderNum(Integer orderNum) { + this.orderNum = orderNum; + } public void start() { validateTransition(AgendaStatus.PENDING); diff --git a/src/main/java/org/dnd/timeet/agenda/dto/AgendaActionResponse.java b/src/main/java/org/dnd/timeet/agenda/dto/AgendaActionResponse.java index 62f694a..262dbb7 100644 --- a/src/main/java/org/dnd/timeet/agenda/dto/AgendaActionResponse.java +++ b/src/main/java/org/dnd/timeet/agenda/dto/AgendaActionResponse.java @@ -34,7 +34,6 @@ public AgendaActionResponse(Agenda agenda, Duration currentDuration, Duration re this.currentDuration = DurationUtils.formatDuration(currentDuration); this.remainingDuration = DurationUtils.formatDuration(remainingDuration); - this.timestamp = DateTimeUtils.formatLocalDateTime(LocalDateTime.now()); } diff --git a/src/main/java/org/dnd/timeet/agenda/dto/AgendaOrderRequest.java b/src/main/java/org/dnd/timeet/agenda/dto/AgendaOrderRequest.java new file mode 100644 index 0000000..70d9701 --- /dev/null +++ b/src/main/java/org/dnd/timeet/agenda/dto/AgendaOrderRequest.java @@ -0,0 +1,18 @@ +package org.dnd.timeet.agenda.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Schema(description = "안건 순서 변경 요청") +@Getter +@Setter +@NoArgsConstructor +public class AgendaOrderRequest { + + @Schema(description = "안건 ID 리스트", example = "[2,1,3]") + private List agendaIds; + +}