From 1dc5020f76052809b465a81d05d15f4f4a58c67e Mon Sep 17 00:00:00 2001 From: "fernanda.mello" Date: Sun, 28 Sep 2025 23:41:37 -0300 Subject: [PATCH 1/2] Cria rascunho de rota para buscar horarios disponiveis para atendimento --- .../controllers/ScheduleController.java | 35 ++++-- .../dto/responses/TimeSlotResponseDTO.java | 26 +++++ .../application/services/ScheduleService.java | 94 ++++++++------- .../repositories/ScheduleRepository.java | 107 ++++++++++++++++-- 4 files changed, 206 insertions(+), 56 deletions(-) create mode 100644 pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/TimeSlotResponseDTO.java diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/ScheduleController.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/ScheduleController.java index 0b4bebe6..c5516cf7 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/ScheduleController.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/ScheduleController.java @@ -1,30 +1,35 @@ package com.pointtils.pointtils.src.application.controllers; -import com.pointtils.pointtils.src.application.dto.requests.ScheduleRequestDTO; -import com.pointtils.pointtils.src.application.dto.requests.SchedulePatchRequestDTO; import com.pointtils.pointtils.src.application.dto.requests.ScheduleListRequestDTO; +import com.pointtils.pointtils.src.application.dto.requests.SchedulePatchRequestDTO; +import com.pointtils.pointtils.src.application.dto.requests.ScheduleRequestDTO; import com.pointtils.pointtils.src.application.dto.responses.ApiResponse; -import com.pointtils.pointtils.src.application.dto.responses.ScheduleResponseDTO; import com.pointtils.pointtils.src.application.dto.responses.PaginatedScheduleResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.ScheduleResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.TimeSlotResponseDTO; import com.pointtils.pointtils.src.application.services.ScheduleService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.AllArgsConstructor; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; + +import java.time.LocalDate; +import java.util.List; import java.util.UUID; @RestController @@ -75,4 +80,14 @@ public ResponseEntity> deleteSchedule(@PathVariable UUID sched ApiResponse response = new ApiResponse<>(true, "Horário excluído com sucesso", null); return ResponseEntity.ok(response); } + + @GetMapping("/available") + @Operation(summary = "Lista todos os intervalos de horários disponíveis cadastrados") + public ResponseEntity>> listAvailableSchedules(@RequestParam UUID interpreterId, + @RequestParam LocalDate dateFrom, + @RequestParam LocalDate dateTo) { + List availableTimeSlots = service.findAvailableSchedules(interpreterId, dateFrom, dateTo); + ApiResponse> response = new ApiResponse<>(true, "Horários disponíveis obtidos com sucesso", availableTimeSlots); + return ResponseEntity.ok(response); + } } diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/TimeSlotResponseDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/TimeSlotResponseDTO.java new file mode 100644 index 00000000..6de6aeef --- /dev/null +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/TimeSlotResponseDTO.java @@ -0,0 +1,26 @@ +package com.pointtils.pointtils.src.application.dto.responses; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.time.LocalTime; +import java.util.Date; +import java.util.UUID; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class TimeSlotResponseDTO { + + private Date date; + @JsonProperty("interpreter_id") + private UUID interpreterId; + @JsonProperty("start_time") + private LocalTime startTime; + @JsonProperty("end_time") + private LocalTime endTime; +} diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/ScheduleService.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/ScheduleService.java index 0de61be5..a3ae1f2c 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/ScheduleService.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/ScheduleService.java @@ -1,19 +1,24 @@ package com.pointtils.pointtils.src.application.services; -import com.pointtils.pointtils.src.application.dto.requests.ScheduleRequestDTO; import com.pointtils.pointtils.src.application.dto.requests.ScheduleListRequestDTO; import com.pointtils.pointtils.src.application.dto.requests.SchedulePatchRequestDTO; -import com.pointtils.pointtils.src.application.dto.responses.ScheduleResponseDTO; +import com.pointtils.pointtils.src.application.dto.requests.ScheduleRequestDTO; import com.pointtils.pointtils.src.application.dto.responses.PaginatedScheduleResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.ScheduleResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.TimeSlotResponseDTO; import com.pointtils.pointtils.src.core.domain.entities.Interpreter; import com.pointtils.pointtils.src.core.domain.entities.Schedule; -import com.pointtils.pointtils.src.infrastructure.repositories.ScheduleRepository; import com.pointtils.pointtils.src.infrastructure.repositories.InterpreterRepository; +import com.pointtils.pointtils.src.infrastructure.repositories.ScheduleRepository; import jakarta.persistence.EntityNotFoundException; import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.sql.Time; +import java.time.LocalDate; +import java.util.Date; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -31,10 +36,10 @@ public ScheduleResponseDTO registerSchedule(ScheduleRequestDTO dto) { } boolean hasConflict = scheduleRepository.existsByInterpreterIdAndDayAndStartTimeLessThanAndEndTimeGreaterThan( - dto.getInterpreterId(), - dto.getDay(), - dto.getEndTime(), - dto.getStartTime() + dto.getInterpreterId(), + dto.getDay(), + dto.getEndTime(), + dto.getStartTime() ); if (hasConflict) { @@ -74,37 +79,50 @@ public ScheduleResponseDTO findById(UUID scheduleId) { public PaginatedScheduleResponseDTO findAll(ScheduleListRequestDTO query, Pageable pageable) { Page schedules = scheduleRepository.findAllWithFilters( - pageable, - query.getInterpreterId(), - query.getDay(), - query.getDateFrom(), - query.getDateTo() + pageable, + query.getInterpreterId(), + query.getDay(), + query.getDateFrom(), + query.getDateTo() ); - + List items = schedules.map(s -> ScheduleResponseDTO.builder() - .id(s.getId()) - .interpreterId(s.getInterpreter().getId()) - .day(s.getDay()) - .startTime(s.getStartTime()) - .endTime(s.getEndTime()) - .build()).toList(); + .id(s.getId()) + .interpreterId(s.getInterpreter().getId()) + .day(s.getDay()) + .startTime(s.getStartTime()) + .endTime(s.getEndTime()) + .build()).toList(); return PaginatedScheduleResponseDTO.builder() - .page(schedules.getNumber()) - .size(schedules.getSize()) - .total(schedules.getTotalElements()) - .items(items) - .build(); + .page(schedules.getNumber()) + .size(schedules.getSize()) + .total(schedules.getTotalElements()) + .items(items) + .build(); + } + + public List findAvailableSchedules(UUID interpreterId, LocalDate dateFrom, LocalDate dateTo) { + List timeSlots = scheduleRepository.findAvailableTimeSlots(interpreterId, dateFrom, dateTo); + + return timeSlots.stream() + .map(timeSlot -> new TimeSlotResponseDTO( + (Date) timeSlot[1], + (UUID) timeSlot[0], + ((Time) timeSlot[2]).toLocalTime(), + ((Time) timeSlot[3]).toLocalTime() + )) + .toList(); } public ScheduleResponseDTO updateSchedule(UUID scheduleId, SchedulePatchRequestDTO dto) { Schedule schedule = scheduleRepository.findById(scheduleId) - .orElseThrow(() -> new EntityNotFoundException("Horário não encontrado")); + .orElseThrow(() -> new EntityNotFoundException("Horário não encontrado")); if (dto.getDay() != null) { schedule.setDay(dto.getDay()); } - + if (dto.getStartTime() != null) { schedule.setStartTime(dto.getStartTime()); } @@ -118,11 +136,11 @@ public ScheduleResponseDTO updateSchedule(UUID scheduleId, SchedulePatchRequestD } boolean hasConflict = scheduleRepository.existsConflictForUpdate( - schedule.getId(), - schedule.getInterpreter().getId(), - schedule.getDay(), - schedule.getStartTime(), - schedule.getEndTime() + schedule.getId(), + schedule.getInterpreter().getId(), + schedule.getDay(), + schedule.getStartTime(), + schedule.getEndTime() ); if (hasConflict) { @@ -132,12 +150,12 @@ public ScheduleResponseDTO updateSchedule(UUID scheduleId, SchedulePatchRequestD Schedule saved = scheduleRepository.save(schedule); return ScheduleResponseDTO.builder() - .id(saved.getId()) - .interpreterId(saved.getInterpreter().getId()) - .day(saved.getDay()) - .startTime(saved.getStartTime()) - .endTime(saved.getEndTime()) - .build(); + .id(saved.getId()) + .interpreterId(saved.getInterpreter().getId()) + .day(saved.getDay()) + .startTime(saved.getStartTime()) + .endTime(saved.getEndTime()) + .build(); } public void deleteById(UUID scheduleId) { diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/infrastructure/repositories/ScheduleRepository.java b/pointtils/src/main/java/com/pointtils/pointtils/src/infrastructure/repositories/ScheduleRepository.java index d93bc01e..aadd6eca 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/infrastructure/repositories/ScheduleRepository.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/infrastructure/repositories/ScheduleRepository.java @@ -1,18 +1,20 @@ package com.pointtils.pointtils.src.infrastructure.repositories; -import java.util.UUID; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; import com.pointtils.pointtils.src.core.domain.entities.Schedule; -import java.time.LocalTime; import com.pointtils.pointtils.src.core.domain.entities.enums.DayOfWeek; +import com.pointtils.pointtils.src.infrastructure.repositories.spec.ScheduleSpecifications; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import java.util.List; - -import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.domain.Specification; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.time.LocalDate; +import java.time.LocalTime; +import java.util.List; +import java.util.UUID; public interface ScheduleRepository extends JpaRepository, JpaSpecificationExecutor { List findByInterpreterIdAndDay(UUID interpreterId, DayOfWeek day); @@ -26,4 +28,93 @@ default Page findAllWithFilters(Pageable pageable, UUID interpreterId, Specification spec = ScheduleSpecifications.withFilters(interpreterId, day, dateFrom, dateTo); return findAll(spec, pageable); } + + @Query(value = """ + WITH date_range AS ( + SELECT + i AS selected_date, + EXTRACT(DOW FROM i)::int AS dow + FROM generate_series(CAST(:dateFrom AS DATE), CAST(:dateTo AS DATE), '1 day'::interval) AS i + ), + schedule_days AS ( + SELECT + s.id AS schedule_id, + s.interpreter_id, + s.day, + s.start_time, + s.end_time, + n.selected_date + FROM schedule s + JOIN date_range n ON + ( + CASE s.day + WHEN 'SUN' THEN 0 + WHEN 'MON' THEN 1 + WHEN 'TUE' THEN 2 + WHEN 'WED' THEN 3 + WHEN 'THU' THEN 4 + WHEN 'FRI' THEN 5 + WHEN 'SAT' THEN 6 + END + ) = n.dow + WHERE interpreter_id = :interpreterId + ), + time_slots AS ( + -- Slots iniciando em hora cheia + SELECT + sd.schedule_id, + sd.interpreter_id, + sd.day, + sd.selected_date, + generate_series( + '2000-01-01'::timestamp + sd.start_time, + '2000-01-01'::timestamp + sd.end_time - interval '1 hour', + interval '1 hour' + ) AS slot_start + FROM schedule_days sd + + UNION ALL + + -- Slots iniciando em meia hora + SELECT + sd.schedule_id, + sd.interpreter_id, + sd.day, + sd.selected_date, + generate_series( + '2000-01-01'::timestamp + sd.start_time + interval '30 minutes', + '2000-01-01'::timestamp + sd.end_time - interval '30 minutes' - interval '1 hour', + interval '1 hour' + ) AS slot_start + FROM schedule_days sd + ), + slots_with_end AS ( + SELECT + *, + slot_start + interval '1 hour' AS slot_end + FROM time_slots + ), + filtered_slots AS ( + SELECT sw.* + FROM slots_with_end sw + WHERE NOT EXISTS ( + SELECT 1 + FROM appointment a + WHERE a.interpreter_id = sw.interpreter_id + AND a.date = sw.selected_date + AND ('2000-01-01'::timestamp + a.start_time) < sw.slot_end + AND ('2000-01-01'::timestamp + a.end_time) > sw.slot_start + ) + ) + SELECT + interpreter_id AS interpreterId, + selected_date::date, + slot_start::time AS startTime, + slot_end::time AS endTime + FROM filtered_slots + ORDER BY interpreter_id, selected_date, slot_start + """, nativeQuery = true) + List findAvailableTimeSlots(@Param("interpreterId") UUID interpreterId, + @Param("dateFrom") LocalDate dateFrom, + @Param("dateTo") LocalDate dateTo); } From 1afddf467eabfcfe2fee35ab55014c51cd80a55b Mon Sep 17 00:00:00 2001 From: "fernanda.mello" Date: Mon, 29 Sep 2025 00:26:51 -0300 Subject: [PATCH 2/2] Corrige formato de resposta de rota /v1/schedules/available --- .../controllers/ScheduleController.java | 12 +++--- .../src/application/dto/TimeSlotDTO.java | 22 +++++++++++ .../AvailableTimeSlotsResponseDTO.java | 24 ++++++++++++ .../dto/responses/TimeSlotResponseDTO.java | 5 --- .../application/mapper/TimeSlotMapper.java | 37 +++++++++++++++++++ .../application/services/ScheduleService.java | 12 ++++-- .../repositories/ScheduleRepository.java | 5 +-- 7 files changed, 99 insertions(+), 18 deletions(-) create mode 100644 pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/TimeSlotDTO.java create mode 100644 pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/AvailableTimeSlotsResponseDTO.java create mode 100644 pointtils/src/main/java/com/pointtils/pointtils/src/application/mapper/TimeSlotMapper.java diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/ScheduleController.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/ScheduleController.java index c5516cf7..b6cd4a00 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/ScheduleController.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/controllers/ScheduleController.java @@ -4,9 +4,9 @@ import com.pointtils.pointtils.src.application.dto.requests.SchedulePatchRequestDTO; import com.pointtils.pointtils.src.application.dto.requests.ScheduleRequestDTO; import com.pointtils.pointtils.src.application.dto.responses.ApiResponse; +import com.pointtils.pointtils.src.application.dto.responses.AvailableTimeSlotsResponseDTO; import com.pointtils.pointtils.src.application.dto.responses.PaginatedScheduleResponseDTO; import com.pointtils.pointtils.src.application.dto.responses.ScheduleResponseDTO; -import com.pointtils.pointtils.src.application.dto.responses.TimeSlotResponseDTO; import com.pointtils.pointtils.src.application.services.ScheduleService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; @@ -83,11 +83,11 @@ public ResponseEntity> deleteSchedule(@PathVariable UUID sched @GetMapping("/available") @Operation(summary = "Lista todos os intervalos de horários disponíveis cadastrados") - public ResponseEntity>> listAvailableSchedules(@RequestParam UUID interpreterId, - @RequestParam LocalDate dateFrom, - @RequestParam LocalDate dateTo) { - List availableTimeSlots = service.findAvailableSchedules(interpreterId, dateFrom, dateTo); - ApiResponse> response = new ApiResponse<>(true, "Horários disponíveis obtidos com sucesso", availableTimeSlots); + public ResponseEntity>> listAvailableSchedules(@RequestParam UUID interpreterId, + @RequestParam LocalDate dateFrom, + @RequestParam LocalDate dateTo) { + List availableTimeSlots = service.findAvailableSchedules(interpreterId, dateFrom, dateTo); + ApiResponse> response = new ApiResponse<>(true, "Horários disponíveis obtidos com sucesso", availableTimeSlots); return ResponseEntity.ok(response); } } diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/TimeSlotDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/TimeSlotDTO.java new file mode 100644 index 00000000..335f605e --- /dev/null +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/TimeSlotDTO.java @@ -0,0 +1,22 @@ +package com.pointtils.pointtils.src.application.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.time.LocalTime; +import java.util.Date; +import java.util.UUID; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class TimeSlotDTO { + + private Date date; + private UUID interpreterId; + private LocalTime startTime; + private LocalTime endTime; +} diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/AvailableTimeSlotsResponseDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/AvailableTimeSlotsResponseDTO.java new file mode 100644 index 00000000..e4e6eb5c --- /dev/null +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/AvailableTimeSlotsResponseDTO.java @@ -0,0 +1,24 @@ +package com.pointtils.pointtils.src.application.dto.responses; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.Date; +import java.util.List; +import java.util.UUID; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class AvailableTimeSlotsResponseDTO { + + private Date date; + @JsonProperty("interpreter_id") + private UUID interpreterId; + @JsonProperty("time_slots") + private List timeSlots; +} diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/TimeSlotResponseDTO.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/TimeSlotResponseDTO.java index 6de6aeef..93190995 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/TimeSlotResponseDTO.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/dto/responses/TimeSlotResponseDTO.java @@ -7,8 +7,6 @@ import lombok.Setter; import java.time.LocalTime; -import java.util.Date; -import java.util.UUID; @Getter @Setter @@ -16,9 +14,6 @@ @AllArgsConstructor public class TimeSlotResponseDTO { - private Date date; - @JsonProperty("interpreter_id") - private UUID interpreterId; @JsonProperty("start_time") private LocalTime startTime; @JsonProperty("end_time") diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/mapper/TimeSlotMapper.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/mapper/TimeSlotMapper.java new file mode 100644 index 00000000..2e86b2ff --- /dev/null +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/mapper/TimeSlotMapper.java @@ -0,0 +1,37 @@ +package com.pointtils.pointtils.src.application.mapper; + +import com.pointtils.pointtils.src.application.dto.TimeSlotDTO; +import com.pointtils.pointtils.src.application.dto.responses.AvailableTimeSlotsResponseDTO; +import com.pointtils.pointtils.src.application.dto.responses.TimeSlotResponseDTO; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class TimeSlotMapper { + + public List toAvailableTimeSlotsResponse(List timeSlots) { + Map availableTimeSlots = new HashMap<>(); + timeSlots.forEach(timeSlot -> { + String key = timeSlot.getDate().toString() + timeSlot.getInterpreterId().toString(); + if (availableTimeSlots.containsKey(key)) { + availableTimeSlots.get(key).getTimeSlots() + .add(new TimeSlotResponseDTO(timeSlot.getStartTime(), timeSlot.getEndTime())); + } else { + var response = new AvailableTimeSlotsResponseDTO( + timeSlot.getDate(), + timeSlot.getInterpreterId(), + new ArrayList<>(List.of(new TimeSlotResponseDTO(timeSlot.getStartTime(), timeSlot.getEndTime()))) + ); + availableTimeSlots.put(key, response); + } + }); + return availableTimeSlots.values().stream() + .sorted(Comparator.comparing(AvailableTimeSlotsResponseDTO::getDate)) + .toList(); + } +} diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/ScheduleService.java b/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/ScheduleService.java index a3ae1f2c..ec961bad 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/ScheduleService.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/application/services/ScheduleService.java @@ -1,11 +1,13 @@ package com.pointtils.pointtils.src.application.services; +import com.pointtils.pointtils.src.application.dto.TimeSlotDTO; import com.pointtils.pointtils.src.application.dto.requests.ScheduleListRequestDTO; import com.pointtils.pointtils.src.application.dto.requests.SchedulePatchRequestDTO; import com.pointtils.pointtils.src.application.dto.requests.ScheduleRequestDTO; +import com.pointtils.pointtils.src.application.dto.responses.AvailableTimeSlotsResponseDTO; import com.pointtils.pointtils.src.application.dto.responses.PaginatedScheduleResponseDTO; import com.pointtils.pointtils.src.application.dto.responses.ScheduleResponseDTO; -import com.pointtils.pointtils.src.application.dto.responses.TimeSlotResponseDTO; +import com.pointtils.pointtils.src.application.mapper.TimeSlotMapper; import com.pointtils.pointtils.src.core.domain.entities.Interpreter; import com.pointtils.pointtils.src.core.domain.entities.Schedule; import com.pointtils.pointtils.src.infrastructure.repositories.InterpreterRepository; @@ -28,6 +30,7 @@ public class ScheduleService { private final ScheduleRepository scheduleRepository; private final InterpreterRepository interpreterRepository; + private final TimeSlotMapper timeSlotMapper; public ScheduleResponseDTO registerSchedule(ScheduleRequestDTO dto) { Optional foundInterpreter = interpreterRepository.findById(dto.getInterpreterId()); @@ -102,17 +105,18 @@ public PaginatedScheduleResponseDTO findAll(ScheduleListRequestDTO query, Pageab .build(); } - public List findAvailableSchedules(UUID interpreterId, LocalDate dateFrom, LocalDate dateTo) { + public List findAvailableSchedules(UUID interpreterId, LocalDate dateFrom, LocalDate dateTo) { List timeSlots = scheduleRepository.findAvailableTimeSlots(interpreterId, dateFrom, dateTo); - return timeSlots.stream() - .map(timeSlot -> new TimeSlotResponseDTO( + List foundTimeSlots = timeSlots.stream() + .map(timeSlot -> new TimeSlotDTO( (Date) timeSlot[1], (UUID) timeSlot[0], ((Time) timeSlot[2]).toLocalTime(), ((Time) timeSlot[3]).toLocalTime() )) .toList(); + return timeSlotMapper.toAvailableTimeSlotsResponse(foundTimeSlots); } public ScheduleResponseDTO updateSchedule(UUID scheduleId, SchedulePatchRequestDTO dto) { diff --git a/pointtils/src/main/java/com/pointtils/pointtils/src/infrastructure/repositories/ScheduleRepository.java b/pointtils/src/main/java/com/pointtils/pointtils/src/infrastructure/repositories/ScheduleRepository.java index aadd6eca..b0f2a1ce 100644 --- a/pointtils/src/main/java/com/pointtils/pointtils/src/infrastructure/repositories/ScheduleRepository.java +++ b/pointtils/src/main/java/com/pointtils/pointtils/src/infrastructure/repositories/ScheduleRepository.java @@ -2,7 +2,6 @@ import com.pointtils.pointtils.src.core.domain.entities.Schedule; import com.pointtils.pointtils.src.core.domain.entities.enums.DayOfWeek; -import com.pointtils.pointtils.src.infrastructure.repositories.spec.ScheduleSpecifications; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; @@ -115,6 +114,6 @@ WHERE NOT EXISTS ( ORDER BY interpreter_id, selected_date, slot_start """, nativeQuery = true) List findAvailableTimeSlots(@Param("interpreterId") UUID interpreterId, - @Param("dateFrom") LocalDate dateFrom, - @Param("dateTo") LocalDate dateTo); + @Param("dateFrom") LocalDate dateFrom, + @Param("dateTo") LocalDate dateTo); }