diff --git a/src/main/java/com/pawwithu/connectdog/domain/post/controller/PostController.java b/src/main/java/com/pawwithu/connectdog/domain/post/controller/PostController.java index 151408d3..1a7ae721 100644 --- a/src/main/java/com/pawwithu/connectdog/domain/post/controller/PostController.java +++ b/src/main/java/com/pawwithu/connectdog/domain/post/controller/PostController.java @@ -1,6 +1,7 @@ package com.pawwithu.connectdog.domain.post.controller; import com.pawwithu.connectdog.domain.post.dto.request.PostCreateRequest; +import com.pawwithu.connectdog.domain.post.dto.request.PostExtendRequest; import com.pawwithu.connectdog.domain.post.dto.request.PostSearchRequest; import com.pawwithu.connectdog.domain.post.dto.request.PostUpdateRequest; import com.pawwithu.connectdog.domain.post.dto.response.*; @@ -136,7 +137,8 @@ public ResponseEntity getIntermediaryOnePost(@Au @Operation(summary = "공고 끌어올리기", description = "공고를 끌어올립니다.", responses = {@ApiResponse(responseCode = "204", description = "공고 끌어올리기 성공") , @ApiResponse(responseCode = "400" - , description = "M2, 해당 이동봉사 중개를 찾을 수 없습니다. \t\n P2, 해당 공고를 찾을 수 없습니다." + , description = "M2, 해당 이동봉사 중개를 찾을 수 없습니다. \t\n P2, 해당 공고를 찾을 수 없습니다. \t\n " + + "B1, 잘못된 끌어올리기 요청입니다." , content = @Content(schema = @Schema(implementation = ErrorResponse.class))) }) @PatchMapping(value = "/intermediaries/posts/{postId}/boost") @@ -145,4 +147,18 @@ public ResponseEntity boostPost(@AuthenticationPrincipal UserDetails login postService.boostPost(loginUser.getUsername(), postId); return ResponseEntity.noContent().build(); } + + @Operation(summary = "공고 연장하기", description = "공고를 연장합니다.", + responses = {@ApiResponse(responseCode = "204", description = "공고 연장하기 성공") + , @ApiResponse(responseCode = "400" + , description = "M2, 해당 이동봉사 중개를 찾을 수 없습니다. \t\n P2, 해당 공고를 찾을 수 없습니다. \t\n " + + "P3, 잘못된 공고 날짜입니다." + , content = @Content(schema = @Schema(implementation = ErrorResponse.class))) + }) + @PatchMapping(value = "/intermediaries/posts/{postId}/extend") + public ResponseEntity extendPost(@AuthenticationPrincipal UserDetails loginUser, @RequestBody PostExtendRequest request, + @PathVariable Long postId) { + postService.extendPost(loginUser.getUsername(), postId, request); + return ResponseEntity.noContent().build(); + } } diff --git a/src/main/java/com/pawwithu/connectdog/domain/post/dto/request/PostExtendRequest.java b/src/main/java/com/pawwithu/connectdog/domain/post/dto/request/PostExtendRequest.java new file mode 100644 index 00000000..e4959fff --- /dev/null +++ b/src/main/java/com/pawwithu/connectdog/domain/post/dto/request/PostExtendRequest.java @@ -0,0 +1,16 @@ +package com.pawwithu.connectdog.domain.post.dto.request; + +import jakarta.validation.constraints.NotNull; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDate; + +public record PostExtendRequest(@NotNull(message = "이동봉사가 필요한 날짜는 필수 입력 값입니다.") + @DateTimeFormat(pattern = "yyyy-MM-dd") + LocalDate startDate, + @NotNull(message = "이동봉사가 필요한 날짜는 필수 입력 값입니다.") + @DateTimeFormat(pattern = "yyyy-MM-dd") + LocalDate endDate, + String pickUpTime) { + +} \ No newline at end of file diff --git a/src/main/java/com/pawwithu/connectdog/domain/post/entity/Post.java b/src/main/java/com/pawwithu/connectdog/domain/post/entity/Post.java index 6d6b3af1..f488698b 100644 --- a/src/main/java/com/pawwithu/connectdog/domain/post/entity/Post.java +++ b/src/main/java/com/pawwithu/connectdog/domain/post/entity/Post.java @@ -83,4 +83,11 @@ public void updateDeletedIntermediary(Intermediary deletedIntermediary) { } public void updateBoostDate() { this.boostDate = LocalDateTime.now(); } + + public void extendDate(LocalDate startDate, LocalDate endDate, String pickUpTime) { + this.startDate = startDate; + this.endDate = endDate; + this.pickUpTime = pickUpTime; + this.status = PostStatus.RECRUITING; + } } diff --git a/src/main/java/com/pawwithu/connectdog/domain/post/repository/impl/CustomPostRepositoryImpl.java b/src/main/java/com/pawwithu/connectdog/domain/post/repository/impl/CustomPostRepositoryImpl.java index 205496d2..0ee05f37 100644 --- a/src/main/java/com/pawwithu/connectdog/domain/post/repository/impl/CustomPostRepositoryImpl.java +++ b/src/main/java/com/pawwithu/connectdog/domain/post/repository/impl/CustomPostRepositoryImpl.java @@ -48,7 +48,7 @@ public List getHomePosts() { .join(post.mainImage, postImage) .join(post.dog, dog) .where(post.status.eq(PostStatus.RECRUITING)) - .orderBy(post.createdDate.desc()) + .orderBy(post.boostDate.desc()) .limit(6) .fetch(); } @@ -253,7 +253,7 @@ private OrderSpecifier[] createOrderSpecifierEC(String orderCondition) { private OrderSpecifier[] createOrderSpecifierCE(String orderCondition) { // default = 최근 등록순 -> 마감 임박순 OrderSpecifier[] defaultOrder = { - new OrderSpecifier(Order.DESC, post.createdDate), + new OrderSpecifier(Order.DESC, post.boostDate), new OrderSpecifier(Order.ASC, post.endDate) }; log.info("ordercondition {} :", orderCondition); @@ -264,7 +264,7 @@ private OrderSpecifier[] createOrderSpecifierCE(String orderCondition) { return orderCondition.equals("마감 임박순") ? new OrderSpecifier[]{ new OrderSpecifier(Order.ASC, post.endDate), - new OrderSpecifier(Order.DESC, post.createdDate)} + new OrderSpecifier(Order.DESC, post.boostDate)} : defaultOrder; } diff --git a/src/main/java/com/pawwithu/connectdog/domain/post/service/PostService.java b/src/main/java/com/pawwithu/connectdog/domain/post/service/PostService.java index 1b7d04ba..737a249b 100644 --- a/src/main/java/com/pawwithu/connectdog/domain/post/service/PostService.java +++ b/src/main/java/com/pawwithu/connectdog/domain/post/service/PostService.java @@ -8,6 +8,7 @@ import com.pawwithu.connectdog.domain.intermediary.entity.Intermediary; import com.pawwithu.connectdog.domain.intermediary.repository.IntermediaryRepository; import com.pawwithu.connectdog.domain.post.dto.request.PostCreateRequest; +import com.pawwithu.connectdog.domain.post.dto.request.PostExtendRequest; import com.pawwithu.connectdog.domain.post.dto.request.PostSearchRequest; import com.pawwithu.connectdog.domain.post.dto.request.PostUpdateRequest; import com.pawwithu.connectdog.domain.post.dto.response.*; @@ -29,6 +30,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; @@ -179,6 +181,7 @@ public PostIntermediaryGetOneResponse getIntermediaryOnePost(String email, Long return response; } + @CacheEvict(value = "homePosts", key = "'volunteer'", cacheManager = "redisCacheManager") // 공고 끌어올리기 시 홈 화면 공고 조회 캐시 삭제 public void boostPost(String email, Long postId) { // 이동봉사 중개 Intermediary intermediary = intermediaryRepository.findByEmail(email).orElseThrow(() -> new BadRequestException(INTERMEDIARY_NOT_FOUND)); @@ -191,4 +194,17 @@ public void boostPost(String email, Long postId) { } post.updateBoostDate(); } + + public void extendPost(String email, Long postId, PostExtendRequest request) { + // 이동봉사 중개 + Intermediary intermediary = intermediaryRepository.findByEmail(email).orElseThrow(() -> new BadRequestException(INTERMEDIARY_NOT_FOUND)); + // 공고 + Post post = postRepository.findByIdAndIntermediaryIdAndStatus(postId, intermediary.getId(), PostStatus.EXPIRED).orElseThrow(() -> new BadRequestException(POST_NOT_FOUND)); + LocalDate now = LocalDate.now(); + if (now.isAfter(request.endDate()) || request.endDate().isBefore(request.startDate())) { + throw new BadRequestException(INVALID_POST_DATE); + } + // startDate, endDate, pickUpTime 업데이트 및 공고 상태 모집 마감 -> 모집중 변경 + post.extendDate(request.startDate(), request.endDate(), request.pickUpTime()); + } } diff --git a/src/main/java/com/pawwithu/connectdog/error/ErrorCode.java b/src/main/java/com/pawwithu/connectdog/error/ErrorCode.java index fa76c29d..47cc12b3 100644 --- a/src/main/java/com/pawwithu/connectdog/error/ErrorCode.java +++ b/src/main/java/com/pawwithu/connectdog/error/ErrorCode.java @@ -39,6 +39,7 @@ public enum ErrorCode { INVALID_POST_STATUS("P1", "잘못된 공고 상태입니다."), POST_NOT_FOUND("P2", "해당 공고를 찾을 수 없습니다."), + INVALID_POST_DATE("P3", "잘못된 공고 날짜입니다."), ALREADY_EXIST_BOOKMARK("B1", "이미 등록된 북마크입니다."), NOT_FOUND_BOOKMARK("B2", "등록되지 않은 북마크입니다."), diff --git a/src/test/java/com/pawwithu/connectdog/domain/application/controller/ApplicationControllerTest.java b/src/test/java/com/pawwithu/connectdog/domain/application/controller/ApplicationControllerTest.java index 43216ebf..35245bca 100644 --- a/src/test/java/com/pawwithu/connectdog/domain/application/controller/ApplicationControllerTest.java +++ b/src/test/java/com/pawwithu/connectdog/domain/application/controller/ApplicationControllerTest.java @@ -118,7 +118,7 @@ void setUp() { void 이동봉사자_신청내역_단건_조회() throws Exception { //given LocalDate date = LocalDate.of(2023, 10, 2); - ApplicationVolunteerGetOneResponse response = new ApplicationVolunteerGetOneResponse(1L, date, "하노정", "01022223333", "이동봉사 신청합니다."); + ApplicationVolunteerGetOneResponse response = new ApplicationVolunteerGetOneResponse(1L, date, "하노정", "한호정", "01022223333", "이동봉사 신청합니다."); Long applicationId = 1L; //when @@ -283,7 +283,7 @@ void setUp() { void 이동봉사_중개_신청내역_단건_조회() throws Exception { //given LocalDate date = LocalDate.of(2023, 10, 2); - ApplicationIntermediaryGetOneResponse response = new ApplicationIntermediaryGetOneResponse(1L, date, "한호정", "01022223333", "이동봉사 신청합니다."); + ApplicationIntermediaryGetOneResponse response = new ApplicationIntermediaryGetOneResponse(1L, date, "한호정", "한호정", "01022223333", "이동봉사 신청합니다."); Long applicationId = 1L; //when diff --git a/src/test/java/com/pawwithu/connectdog/domain/post/controller/PostControllerTest.java b/src/test/java/com/pawwithu/connectdog/domain/post/controller/PostControllerTest.java index 74dd208a..7be67945 100644 --- a/src/test/java/com/pawwithu/connectdog/domain/post/controller/PostControllerTest.java +++ b/src/test/java/com/pawwithu/connectdog/domain/post/controller/PostControllerTest.java @@ -241,4 +241,28 @@ void setUp() { result.andExpect(status().isNoContent()); verify(postService, times(1)).boostPost(anyString(), anyLong()); } + + @Test + void 이동봉사_공고_연장하기() throws Exception { + //given + Long postId = 1L; + String startDate = "2023-10-02"; // 문자열로 직접 정의 + String endDate = "2023-11-07"; // 문자열로 직접 정의 + String pickUpTime = "12:00"; + String request = String.format( + "{\"startDate\":\"%s\",\"endDate\":\"%s\",\"pickUpTime\":\"%s\"}", + startDate, endDate, pickUpTime + ); + + //when + ResultActions result = mockMvc.perform( + patch("/intermediaries/posts/{postId}/extend", postId) + .contentType(MediaType.APPLICATION_JSON) + .content(request) + ); + + //then + result.andExpect(status().isNoContent()); + verify(postService, times(1)).extendPost(anyString(), anyLong(), any()); + } } \ No newline at end of file