Skip to content

Commit

Permalink
Merge pull request #54 from Project-Catcher/feat-ny-make-schedule-detail
Browse files Browse the repository at this point in the history
Feat: 추천 템플릿 목록 조회
  • Loading branch information
inyoung0215 authored Dec 22, 2023
2 parents 2741701 + f788aaf commit 7baab41
Show file tree
Hide file tree
Showing 12 changed files with 222 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.catcher.core.domain.entity.ScheduleDetail;
import com.catcher.core.domain.entity.User;

import java.util.List;
import java.util.Optional;

public interface ScheduleDetailRepository {
Expand All @@ -14,4 +15,6 @@ public interface ScheduleDetailRepository {
Optional<ScheduleDetail> findByIdWithUser(Long scheduleDetailId);

void deleteScheduleDetail(User user, Long scheduleDetailId);

List<ScheduleDetail> findBySchedule(Schedule schedule);
}
17 changes: 17 additions & 0 deletions src/main/java/com/catcher/core/database/TemplateRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.catcher.core.database;

import com.catcher.core.domain.entity.Template;
import com.catcher.core.domain.entity.enums.RecommendedStatus;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;

public interface TemplateRepository {
@Query("SELECT t FROM Template t " +
"JOIN FETCH t.schedule s " +
"WHERE t.recommendedStatus = :status")
List<Template> findByRecommendedStatus(@Param("status") RecommendedStatus recommendedStatus);

void save(Template template);
}
4 changes: 4 additions & 0 deletions src/main/java/com/catcher/core/domain/entity/Template.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
import com.catcher.core.domain.entity.enums.RecommendedStatus;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.Where;

import java.time.ZonedDateTime;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder
@Table(name = "template")
@Where(clause = "deleted_at is null")
public class Template extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.catcher.core.dto.response;

import com.catcher.core.domain.entity.ScheduleDetail;
import com.catcher.core.domain.entity.Template;
import com.catcher.core.domain.entity.enums.ItemType;
import lombok.Getter;

import java.time.LocalDateTime;
import java.util.List;

@Getter
public class GetRecommendedTemplateResponse {
private final List<TemplateDTO> templates;

public GetRecommendedTemplateResponse(List<TemplateDTO> templates) {
this.templates = templates;
}

@Getter
public static class TemplateDTO {
private final Long id;
private final String title;
private final String location;
private final String thumbnailUrl;
private final Long days;
private final List<TemplateScheduleDetailDTO> scheduleDetails;

public TemplateDTO(Template template, List<TemplateScheduleDetailDTO> scheduleDetails) {
this.id = template.getId();
this.title = template.getSchedule().getTitle();
this.location = template.getSchedule().getLocation().getAddress().getDescription();
this.thumbnailUrl = template.getSchedule().getThumbnailUrl();
this.days = template.getDays();
this.scheduleDetails = scheduleDetails;
}
}

@Getter
public static class TemplateScheduleDetailDTO {
private final Long id;
private final String description;
private final String color;
private final ItemType itemType;
private final Long itemId;
private final LocalDateTime startAt;
private final LocalDateTime endAt;

public TemplateScheduleDetailDTO(ScheduleDetail scheduleDetail) {
this.id = scheduleDetail.getId();
this.description = scheduleDetail.getDescription();
this.color = scheduleDetail.getColor();
this.itemType = scheduleDetail.getItemType();
this.itemId = scheduleDetail.getItemId();
this.startAt = scheduleDetail.getStartAt();
this.endAt = scheduleDetail.getEndAt();
}
}
}
23 changes: 23 additions & 0 deletions src/main/java/com/catcher/core/service/ScheduleService.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class ScheduleService {
private final TagRepository tagRepository;
private final UploadFileRepository uploadFileRepository;
private final ScheduleTagRepository scheduleTagRepository;
private final TemplateRepository templateRepository;

@Transactional(readOnly = true)
public DraftScheduleResponse getDraftSchedule(User user) {
Expand Down Expand Up @@ -276,4 +277,26 @@ private ScheduleDetail getScheduleDetail(User user, Long scheduleDetailId) {

return scheduleDetail;
}

@Transactional(readOnly = true)
public GetRecommendedTemplateResponse getRecommendedTemplate() {
List<Template> templateList = templateRepository.findByRecommendedStatus(RecommendedStatus.ENABLED);

List<GetRecommendedTemplateResponse.TemplateDTO> templateDTOList = templateList.stream()
.map(template -> {
List<ScheduleDetail> scheduleDetailList = scheduleDetailRepository.findBySchedule(template.getSchedule());
return getTemplateDTO(template, scheduleDetailList);
})
.collect(Collectors.toList());

return new GetRecommendedTemplateResponse(templateDTOList);
}

private GetRecommendedTemplateResponse.TemplateDTO getTemplateDTO(Template template, List<ScheduleDetail> scheduleDetailList) {
List<GetRecommendedTemplateResponse.TemplateScheduleDetailDTO> templateScheduleDetailDTOList = scheduleDetailList.stream()
.map(GetRecommendedTemplateResponse.TemplateScheduleDetailDTO::new)
.collect(Collectors.toList());

return new GetRecommendedTemplateResponse.TemplateDTO(template, templateScheduleDetailDTOList);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
Expand All @@ -34,4 +35,9 @@ public Optional<ScheduleDetail> findByIdWithUser(Long scheduleDetailId) {
public void deleteScheduleDetail(User user, Long scheduleDetailId) {
scheduleDetailJpaRepository.updateScheduleDetailToDeleted(user, scheduleDetailId);
}

@Override
public List<ScheduleDetail> findBySchedule(Schedule schedule) {
return scheduleDetailJpaRepository.findBySchedule(schedule);
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/catcher/datasource/TemplateRepositoryImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.catcher.datasource;

import com.catcher.core.database.TemplateRepository;
import com.catcher.core.domain.entity.Template;
import com.catcher.core.domain.entity.enums.RecommendedStatus;
import com.catcher.datasource.repository.TemplateJpaRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
@RequiredArgsConstructor
public class TemplateRepositoryImpl implements TemplateRepository {
private final TemplateJpaRepository templateJpaRepository;

@Override
public List<Template> findByRecommendedStatus(RecommendedStatus recommendedStatus) {
return templateJpaRepository.findByRecommendedStatus(recommendedStatus);
}

@Override
public void save(Template template) {
templateJpaRepository.save(template);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.Optional;

public interface ScheduleDetailJpaRepository extends JpaRepository<ScheduleDetail, Long> {
Expand All @@ -23,4 +24,6 @@ public interface ScheduleDetailJpaRepository extends JpaRepository<ScheduleDetai
"SET sd.deletedAt = CURRENT_TIMESTAMP " +
"WHERE sd.id = :id AND sd.schedule.user = :user")
void updateScheduleDetailToDeleted(@Param("user") User user, @Param("id") Long scheduleDetailId);

List<ScheduleDetail> findBySchedule(Schedule schedule);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.catcher.datasource.repository;

import com.catcher.core.domain.entity.Template;
import com.catcher.core.domain.entity.enums.RecommendedStatus;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface TemplateJpaRepository extends JpaRepository<Template, Long> {


List<Template> findByRecommendedStatus(RecommendedStatus recommendedStatus);
}

This file was deleted.

8 changes: 8 additions & 0 deletions src/main/java/com/catcher/resource/ScheduleController.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ public CommonResponse<ScheduleListResponse> getScheduleList(
ScheduleListRequest scheduleListRequest
) {
ScheduleListResponse response = scheduleService.getScheduleListByFilter(scheduleListRequest);
return CommonResponse.success(response);
}

@Operation(summary = "세부 일정 수정")
Expand All @@ -150,4 +151,11 @@ public CommonResponse<Object> deleteScheduleDetail(
scheduleService.deleteScheduleDetail(user, scheduleDetailId);
return CommonResponse.success();
}

@Operation(summary = "추천 템플릿 목록 조회")
@GetMapping("/templates")
public CommonResponse<GetRecommendedTemplateResponse> getTemplates() {
GetRecommendedTemplateResponse response = scheduleService.getRecommendedTemplate();
return CommonResponse.success(response);
}
}
61 changes: 61 additions & 0 deletions src/test/java/com/catcher/core/service/ScheduleServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ class ScheduleServiceTest {
@Autowired
LocationJpaRepository locationJpaRepository;

@Autowired
TemplateRepository templateRepository;

@PersistenceContext
EntityManager em;

Expand Down Expand Up @@ -501,6 +504,64 @@ void invalid_user_delete_schedule_detail() {
.isInstanceOf(BaseException.class);
}

@DisplayName("SUCCESS: 추천 템플릿 목록 조회")
@Test
void get_recommended_template() {
// Given
User user = createUser(createRandomUUID(), createRandomUUID(), createRandomUUID(), createRandomUUID());
userRepository.save(user);

Schedule schedule = createSchedule(user, location, ScheduleStatus.DRAFT);
scheduleRepository.save(schedule);

ScheduleDetail scheduleDetail = createScheduleDetail(schedule, ItemType.CATCHERITEM, 1L);
scheduleDetailRepository.save(scheduleDetail);

Template template = createTemplate(schedule, RecommendedStatus.ENABLED);
templateRepository.save(template);

// When
GetRecommendedTemplateResponse result = scheduleService.getRecommendedTemplate();

// Then
assertEquals(1, result.getTemplates().size());
assertEquals(template.getId(), result.getTemplates().get(0).getId());
assertEquals(template.getDays(), result.getTemplates().get(0).getDays());
assertEquals(scheduleDetail.getId(), result.getTemplates().get(0).getScheduleDetails().get(0).getId());
}

@DisplayName("SUCCESS: 추천 템플릿 목록 조회 시 추천 등록된 템플릿이 없을 경우")
@Test
void get_recommended_template_when_none_result() {
// Given
User user = createUser(createRandomUUID(), createRandomUUID(), createRandomUUID(), createRandomUUID());
userRepository.save(user);

Schedule schedule = createSchedule(user, location, ScheduleStatus.DRAFT);
scheduleRepository.save(schedule);

ScheduleDetail scheduleDetail = createScheduleDetail(schedule, ItemType.CATCHERITEM, 1L);
scheduleDetailRepository.save(scheduleDetail);

Template template = createTemplate(schedule, RecommendedStatus.DISABLED);
templateRepository.save(template);

// When
GetRecommendedTemplateResponse result = scheduleService.getRecommendedTemplate();

// Then
assertEquals(0, result.getTemplates().size());
}

private Template createTemplate(Schedule schedule, RecommendedStatus status) {
return Template.builder()
.schedule(schedule)
.days(2L)
.theme("theme")
.recommendedStatus(status)
.build();
}

private User createUser(String name, String phone, String email, String nickname) {
return User.builder()
.username(name)
Expand Down

0 comments on commit 7baab41

Please sign in to comment.