diff --git a/src/main/java/com/mtvs/devlinkbackend/request/controller/RequestController.java b/src/main/java/com/mtvs/devlinkbackend/request/controller/RequestController.java index b968fa3..9872611 100644 --- a/src/main/java/com/mtvs/devlinkbackend/request/controller/RequestController.java +++ b/src/main/java/com/mtvs/devlinkbackend/request/controller/RequestController.java @@ -70,7 +70,51 @@ public ResponseEntity> getRequestsByAccountId( return ResponseEntity.ok(requests); } - @Operation(summary = "특정 기간 내의 의뢰 목록 조회", description = "시작과 끝 날짜 사이의 모든 의뢰를 조회합니다.") + @Operation(summary = "업무 범위별 의뢰 목록 조회", description = "특정 업무 범위에 대한 모든 의뢰를 조회합니다.") + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "의뢰 목록이 성공적으로 조회됨") + }) + @GetMapping("/work-scope") + public ResponseEntity> getRequestsByWorkScope(@RequestParam String workScope) { + + List requests = requestService.findRequestsByWorkScope(workScope); + return ResponseEntity.ok(requests); + } + + @Operation(summary = "근무 형태별 의뢰 목록 조회", description = "근무 형태 범위에 대한 모든 의뢰를 조회합니다.") + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "의뢰 목록이 성공적으로 조회됨") + }) + @GetMapping("/work-type") + public ResponseEntity> getRequestsByWorkType(@RequestParam String workType) { + + List requests = requestService.findRequestsByWorkType(workType); + return ResponseEntity.ok(requests); + } + + @Operation(summary = "진행 분류별 의뢰 목록 조회", description = "진행 분류 범위에 대한 모든 의뢰를 조회합니다.") + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "의뢰 목록이 성공적으로 조회됨") + }) + @GetMapping("/progress-classfication") + public ResponseEntity> getRequestsByProgressClassification(@RequestParam String progressClassification) { + + List requests = requestService.findRequestsByProgressClassification(progressClassification); + return ResponseEntity.ok(requests); + } + + @Operation(summary = "프로젝트 주제(제목)별 의뢰 목록 조회", description = "프로젝트 주제(제목) 범위에 대한 모든 의뢰를 조회합니다.") + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "의뢰 목록이 성공적으로 조회됨") + }) + @GetMapping("/title") + public ResponseEntity> getRequestsByTitleContainingIgnoreCase(@RequestParam String title) { + + List requests = requestService.findRequestsByTitleContainingIgnoreCase(title); + return ResponseEntity.ok(requests); + } + + @Operation(summary = "특정 기간 내의 의뢰 목록 조회", description = "시작날짜 또는 끝 날짜를 포함하는 모든 의뢰를 조회합니다.") @ApiResponses({ @ApiResponse(responseCode = "200", description = "의뢰 목록이 성공적으로 조회됨") }) @@ -78,8 +122,23 @@ public ResponseEntity> getRequestsByAccountId( public ResponseEntity> getRequestsBetweenDates( @RequestParam LocalDateTime startDateTime, @RequestParam LocalDateTime endDateTime) { - List requests = - requestService.findAllRequestsBetweenStarDateTimeAndEndDateTime(startDateTime, endDateTime); + List requests = requestService.findRequestsByStartDateTimeLessThanEqualOrEndDateTimeGreaterThanEqual( + startDateTime, endDateTime); + return ResponseEntity.ok(requests); + } + + @Operation(summary = "원하는 직군별 의뢰 목록 조회", description = "원하는 직군 숫자보다 많이 모집하는 모든 의뢰를 조회합니다.") + @ApiResponses({ + @ApiResponse(responseCode = "200", description = "의뢰 목록이 성공적으로 조회됨") + }) + @GetMapping("/required") + public ResponseEntity> getRequestsByTitleContainingIgnoreCase( + @RequestParam int requiredClient, @RequestParam int requiredServer, @RequestParam int requiredDesign, + @RequestParam int requiredPlanner, @RequestParam int requiredAIEngineer) { + + List requests = requestService.findRequestsWithLargerRequirements( + requiredClient, requiredServer, requiredDesign, requiredPlanner, requiredAIEngineer + ); return ResponseEntity.ok(requests); } diff --git a/src/main/java/com/mtvs/devlinkbackend/request/dto/RequestRegistRequestDTO.java b/src/main/java/com/mtvs/devlinkbackend/request/dto/RequestRegistRequestDTO.java index 0b9b469..859fda4 100644 --- a/src/main/java/com/mtvs/devlinkbackend/request/dto/RequestRegistRequestDTO.java +++ b/src/main/java/com/mtvs/devlinkbackend/request/dto/RequestRegistRequestDTO.java @@ -1,6 +1,12 @@ package com.mtvs.devlinkbackend.request.dto; +import jakarta.persistence.Column; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; import lombok.*; +import org.hibernate.annotations.CreationTimestamp; +import org.hibernate.annotations.UpdateTimestamp; import java.time.LocalDateTime; @@ -9,8 +15,18 @@ @NoArgsConstructor @ToString public class RequestRegistRequestDTO { + private String workScope; + private String workType; + private String progressClassification; + private String companyName; private String title; private String content; + private Integer requiredClient; + private Integer requiredServer; + private Integer requiredDesign; + private Integer requiredPlanner; + private Integer requiredAIEngineer; private LocalDateTime startDateTime; private LocalDateTime endDateTime; -} + private Integer estimatedCost; +} \ No newline at end of file diff --git a/src/main/java/com/mtvs/devlinkbackend/request/dto/RequestUpdateRequestDTO.java b/src/main/java/com/mtvs/devlinkbackend/request/dto/RequestUpdateRequestDTO.java index 44d91ce..77a7f04 100644 --- a/src/main/java/com/mtvs/devlinkbackend/request/dto/RequestUpdateRequestDTO.java +++ b/src/main/java/com/mtvs/devlinkbackend/request/dto/RequestUpdateRequestDTO.java @@ -11,8 +11,18 @@ @ToString public class RequestUpdateRequestDTO { private Long requestId; + private String workScope; + private String workType; + private String progressClassification; + private String companyName; private String title; private String content; + private Integer requiredClient; + private Integer requiredServer; + private Integer requiredDesign; + private Integer requiredPlanner; + private Integer requiredAIEngineer; private LocalDateTime startDateTime; private LocalDateTime endDateTime; + private Integer estimatedCost; } \ No newline at end of file diff --git a/src/main/java/com/mtvs/devlinkbackend/request/entity/Request.java b/src/main/java/com/mtvs/devlinkbackend/request/entity/Request.java index ad9e334..3b6a643 100644 --- a/src/main/java/com/mtvs/devlinkbackend/request/entity/Request.java +++ b/src/main/java/com/mtvs/devlinkbackend/request/entity/Request.java @@ -24,18 +24,48 @@ public class Request { @Column(name = "REQUEST_ID") private Long requestId; + @Column(name = "WORK_SCOPE") + private String workScope; + + @Column(name = "WORK_TYPE") + private String workType; + + @Column(name = "PROGRESS_CLASSIFICATION") + private String progressClassification; + + @Column(name = "COMPANY_NAME") + private String companyName; + @Column(name = "TITLE", nullable = false) private String title; @Column(name = "CONTENT", nullable = false) private String content; + @Column(name = "REQUIRED_CLIENT") + private Integer requiredClient; + + @Column(name = "REQUIRED_SERVER") + private Integer requiredServer; + + @Column(name = "REQUIRED_DESIGN") + private Integer requiredDesign; + + @Column(name = "REQUIRED_PLANNER") + private Integer requiredPlanner; + + @Column(name = "REQUIRED_AIENGINEER") + private Integer requiredAIEngineer; + @Column(name = "START_DATETIME") private LocalDateTime startDateTime; @Column(name = "END_DATETIME") private LocalDateTime endDateTime; + @Column(name = "ESTIMATED_COST") + private Integer estimatedCost; + @Column(name = "ACCOUNT_ID", nullable = false) private String accountId; @@ -59,6 +89,60 @@ public Request(String title, String content, LocalDateTime startDateTime, LocalD this.accountId = accountId; } + public Request(String workScope, String workType, String progressClassification, String companyName, String title, String content, Integer requiredClient, Integer requiredServer, Integer requiredDesign, Integer requiredPlanner, Integer requiredAIEngineer, LocalDateTime startDateTime, LocalDateTime endDateTime, Integer estimatedCost, String accountId) { + this.workScope = workScope; + this.workType = workType; + this.progressClassification = progressClassification; + this.companyName = companyName; + this.title = title; + this.content = content; + this.requiredClient = requiredClient; + this.requiredServer = requiredServer; + this.requiredDesign = requiredDesign; + this.requiredPlanner = requiredPlanner; + this.requiredAIEngineer = requiredAIEngineer; + this.startDateTime = startDateTime; + this.endDateTime = endDateTime; + this.estimatedCost = estimatedCost; + this.accountId = accountId; + } + + public void setWorkScope(String workScope) { + this.workScope = workScope; + } + + public void setWorkType(String workType) { + this.workType = workType; + } + + public void setProgressClassification(String progressClassification) { + this.progressClassification = progressClassification; + } + + public void setRequiredClient(Integer requiredClient) { + this.requiredClient = requiredClient; + } + + public void setRequiredServer(Integer requiredServer) { + this.requiredServer = requiredServer; + } + + public void setRequiredDesign(Integer requiredDesign) { + this.requiredDesign = requiredDesign; + } + + public void setRequiredPlanner(Integer requiredPlanner) { + this.requiredPlanner = requiredPlanner; + } + + public void setRequiredAIEngineer(Integer requiredAIEngineer) { + this.requiredAIEngineer = requiredAIEngineer; + } + + public void setEstimatedCost(Integer estimatedCost) { + this.estimatedCost = estimatedCost; + } + public void setTitle(String title) { this.title = title; } diff --git a/src/main/java/com/mtvs/devlinkbackend/request/repository/RequestRepository.java b/src/main/java/com/mtvs/devlinkbackend/request/repository/RequestRepository.java index c8a2675..ce1b456 100644 --- a/src/main/java/com/mtvs/devlinkbackend/request/repository/RequestRepository.java +++ b/src/main/java/com/mtvs/devlinkbackend/request/repository/RequestRepository.java @@ -13,9 +13,28 @@ public interface RequestRepository extends JpaRepository { List findRequestsByAccountId(String accountId); - @Query("SELECT r FROM Request r WHERE r.startDateTime BETWEEN :startDateTime AND :endDateTime " + - "AND r.endDateTime BETWEEN :startDateTime AND :endDateTime") - List findRequestsWithinDateRange( - @Param("startDateTime") LocalDateTime startDateTime, - @Param("endDateTime") LocalDateTime endDateTime); + List findRequestsByWorkScope(String workScope); + + List findRequestsByWorkType(String workType); + + List findRequestsByProgressClassification(String progressClassification); + + List findRequestsByTitleContainingIgnoreCase(String title); + + List findRequestsByStartDateTimeLessThanEqualOrEndDateTimeGreaterThanEqual(LocalDateTime startDateTime, LocalDateTime endDateTime); + + // required 값들이 넘겨준 값보다 큰 row를 조회하는 쿼리 + @Query("SELECT r FROM Request r WHERE " + + "(:requiredClient IS NULL OR r.requiredClient > :requiredClient) AND " + + "(:requiredServer IS NULL OR r.requiredServer > :requiredServer) AND " + + "(:requiredDesign IS NULL OR r.requiredDesign > :requiredDesign) AND " + + "(:requiredPlanner IS NULL OR r.requiredPlanner > :requiredPlanner) AND " + + "(:requiredAIEngineer IS NULL OR r.requiredAIEngineer > :requiredAIEngineer)") + List findRequestsWithLargerRequirements( + @Param("requiredClient") Integer requiredClient, + @Param("requiredServer") Integer requiredServer, + @Param("requiredDesign") Integer requiredDesign, + @Param("requiredPlanner") Integer requiredPlanner, + @Param("requiredAIEngineer") Integer requiredAIEngineer + ); } diff --git a/src/main/java/com/mtvs/devlinkbackend/request/service/RequestService.java b/src/main/java/com/mtvs/devlinkbackend/request/service/RequestService.java index eaa46d6..0826783 100644 --- a/src/main/java/com/mtvs/devlinkbackend/request/service/RequestService.java +++ b/src/main/java/com/mtvs/devlinkbackend/request/service/RequestService.java @@ -22,10 +22,20 @@ public RequestService(RequestRepository requestRepository) { @Transactional public Request registRequest(RequestRegistRequestDTO requestRegistRequestDTO, String accountId) { return requestRepository.save(new Request( + requestRegistRequestDTO.getWorkScope(), + requestRegistRequestDTO.getWorkType(), + requestRegistRequestDTO.getProgressClassification(), + requestRegistRequestDTO.getCompanyName(), requestRegistRequestDTO.getTitle(), requestRegistRequestDTO.getContent(), + requestRegistRequestDTO.getRequiredClient(), + requestRegistRequestDTO.getRequiredServer(), + requestRegistRequestDTO.getRequiredDesign(), + requestRegistRequestDTO.getRequiredPlanner(), + requestRegistRequestDTO.getRequiredAIEngineer(), requestRegistRequestDTO.getStartDateTime(), requestRegistRequestDTO.getEndDateTime(), + requestRegistRequestDTO.getEstimatedCost(), accountId )); } @@ -38,8 +48,33 @@ public List findRequestsByAccountId(String accountId) { return requestRepository.findRequestsByAccountId(accountId); } - public List findAllRequestsBetweenStarDateTimeAndEndDateTime(LocalDateTime starDateTime, LocalDateTime endDateTime) { - return requestRepository.findRequestsWithinDateRange(starDateTime, endDateTime); + public List findRequestsByWorkScope(String workScope) { + return requestRepository.findRequestsByWorkScope(workScope); + } + + public List findRequestsByWorkType(String workType) { + return requestRepository.findRequestsByWorkType(workType); + } + + public List findRequestsByProgressClassification(String progressClassification) { + return requestRepository.findRequestsByProgressClassification(progressClassification); + } + + public List findRequestsByTitleContainingIgnoreCase(String title) { + return requestRepository.findRequestsByTitleContainingIgnoreCase(title); + } + + public List findRequestsByStartDateTimeLessThanEqualOrEndDateTimeGreaterThanEqual( + LocalDateTime starDateTime, LocalDateTime endDateTime) { + return requestRepository.findRequestsByStartDateTimeLessThanEqualOrEndDateTimeGreaterThanEqual(starDateTime, endDateTime); + } + + public List findRequestsWithLargerRequirements( + Integer requiredClient, Integer requiredServer, Integer requiredDesign, + Integer requiredPlanner, Integer requiredAIEngineer) { + + return requestRepository.findRequestsWithLargerRequirements( + requiredClient, requiredServer, requiredDesign, requiredPlanner, requiredAIEngineer); } @Transactional @@ -48,10 +83,19 @@ public Request updateRequest(RequestUpdateRequestDTO requestUpdateRequestDTO, St if (request.isPresent()) { Request foundRequest = request.get(); if(foundRequest.getAccountId().equals(accountId)) { + foundRequest.setWorkScope(requestUpdateRequestDTO.getWorkScope()); + foundRequest.setWorkType(requestUpdateRequestDTO.getWorkType()); + foundRequest.setProgressClassification(requestUpdateRequestDTO.getProgressClassification()); foundRequest.setTitle(requestUpdateRequestDTO.getTitle()); foundRequest.setContent(requestUpdateRequestDTO.getContent()); + foundRequest.setRequiredClient(requestUpdateRequestDTO.getRequiredClient()); + foundRequest.setRequiredServer(requestUpdateRequestDTO.getRequiredServer()); + foundRequest.setRequiredDesign(requestUpdateRequestDTO.getRequiredDesign()); + foundRequest.setRequiredPlanner(requestUpdateRequestDTO.getRequiredPlanner()); + foundRequest.setRequiredAIEngineer(requestUpdateRequestDTO.getRequiredAIEngineer()); foundRequest.setStartDateTime(requestUpdateRequestDTO.getStartDateTime()); foundRequest.setEndDateTime(requestUpdateRequestDTO.getEndDateTime()); + foundRequest.setEstimatedCost(requestUpdateRequestDTO.getEstimatedCost()); return foundRequest; } else throw new IllegalArgumentException("잘못된 accountId로 Request ID : " diff --git a/src/test/java/com/mtvs/devlinkbackend/crud/RequestCRUDTest.java b/src/test/java/com/mtvs/devlinkbackend/crud/RequestCRUDTest.java index 80268c0..e18e8e2 100644 --- a/src/test/java/com/mtvs/devlinkbackend/crud/RequestCRUDTest.java +++ b/src/test/java/com/mtvs/devlinkbackend/crud/RequestCRUDTest.java @@ -8,6 +8,7 @@ import org.junit.jupiter.api.Order; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; @@ -25,15 +26,73 @@ public class RequestCRUDTest { private static Stream newRequest() { return Stream.of( - Arguments.of(new RequestRegistRequestDTO("의뢰0", "내용0", LocalDateTime.now(), LocalDateTime.now()), "계정0"), - Arguments.of(new RequestRegistRequestDTO("의뢰00", "내용00", LocalDateTime.now(), LocalDateTime.now()), "계정00") + Arguments.of(new RequestRegistRequestDTO( + "업무범위0", + "근무형태0", + "진행분류0", + "회사이름0", + "의뢰0", + "내용0", + 3, + 3, + 3, + 3, + 3, + LocalDateTime.now(), + LocalDateTime.now(), + 1000000), "계정0"), + Arguments.of(new RequestRegistRequestDTO( + "업무범위1", + "근무형태1", + "진행분류1", + "회사이름1", + "의뢰1", + "내용1", + 2, + 3, + 1, + 1, + 3, + LocalDateTime.now(), + LocalDateTime.now(), + 1000000), "계정00") ); } private static Stream modifiedRequest() { return Stream.of( - Arguments.of(new RequestUpdateRequestDTO(1L,"의뢰0", "내용0", LocalDateTime.now(), LocalDateTime.now()), "계정1"), - Arguments.of(new RequestUpdateRequestDTO(2L,"의뢰00" , "내용00", LocalDateTime.now(), LocalDateTime.now()), "계정1") + Arguments.of(new RequestUpdateRequestDTO( + 1L, + "업무범위0", + "근무형태0", + "진행분류0", + "회사이름0", + "의뢰0", + "내용0", + 2, + 3, + 1, + 1, + 3, + LocalDateTime.now(), + LocalDateTime.now(), + 1000000), "계정1"), + Arguments.of(new RequestUpdateRequestDTO( + 2L, + "업무범위1", + "근무형태1", + "진행분류1", + "회사이름1", + "의뢰1", + "내용1", + 2, + 3, + 1, + 1, + 3, + LocalDateTime.now(), + LocalDateTime.now(), + 1000000), "계정1") ); } @@ -80,4 +139,54 @@ public void testDeleteRequest(long requestId) { Assertions.assertDoesNotThrow(() -> requestService.deleteRequest(requestId)); } + + @DisplayName("업무 범위에 따른 의뢰 조회 테스트") + @ValueSource( strings = {"업무범위1", "업무범위2"}) + @ParameterizedTest + @Order(2) + public void testFindRequestsByWorkScope(String workScope) { + Assertions.assertDoesNotThrow(() -> + System.out.println("Request = " + requestService.findRequestsByWorkScope(workScope))); + } + + @DisplayName("근무 형태에 따른 의뢰 조회 테스트") + @ValueSource( strings = {"근무형태1", "근무형태2"}) + @ParameterizedTest + @Order(2) + public void testFindRequestsByWorkType(String workType) { + Assertions.assertDoesNotThrow(() -> + System.out.println("Request = " + requestService.findRequestsByWorkType(workType))); + } + + @DisplayName("진행 분류에 따른 의뢰 조회 테스트") + @ValueSource( strings = {"진행분류1", "진행분류2"}) + @ParameterizedTest + @Order(2) + public void testFindRequestsByProgressClassification(String progressClassification) { + Assertions.assertDoesNotThrow(() -> + System.out.println("Request = " + requestService. + findRequestsByProgressClassification(progressClassification))); + } + + @DisplayName("프로젝트 주제(제목)에 따른 의뢰 조회 테스트") + @ValueSource( strings = {"제목1", "제목2"}) + @ParameterizedTest + @Order(2) + public void testFindRequestsByTitleContainingIgnoreCase(String title) { + Assertions.assertDoesNotThrow(() -> + System.out.println("Request = " + requestService.findRequestsByTitleContainingIgnoreCase(title))); + } + + @DisplayName("필요 직군보다 더 많이 모집하는 의뢰 조회 테스트") + @CsvSource({"2,2,3,1,3", "3,2,1,1,3"}) + @ParameterizedTest + @Order(2) + public void testFindRequestsWithLargerRequirements(Integer requiredClient, Integer requiredServer, + Integer requiredDesign, Integer requiredPlanner, + Integer requiredAIEngineer) { + Assertions.assertDoesNotThrow(() -> + System.out.println("Request = " + requestService.findRequestsWithLargerRequirements( + requiredClient, requiredServer, requiredDesign, requiredPlanner, requiredAIEngineer + ))); + } }