diff --git a/src/main/java/com/gongjakso/server/domain/apply/controller/ApplyController.java b/src/main/java/com/gongjakso/server/domain/apply/controller/ApplyController.java index db7fbbf0..479c1188 100644 --- a/src/main/java/com/gongjakso/server/domain/apply/controller/ApplyController.java +++ b/src/main/java/com/gongjakso/server/domain/apply/controller/ApplyController.java @@ -1,8 +1,6 @@ package com.gongjakso.server.domain.apply.controller; -import com.gongjakso.server.domain.apply.dto.ApplyReq; -import com.gongjakso.server.domain.apply.dto.ApplicationRes; -import com.gongjakso.server.domain.apply.dto.ApplyRes; +import com.gongjakso.server.domain.apply.dto.*; import com.gongjakso.server.domain.apply.service.ApplyService; import com.gongjakso.server.global.common.ApplicationResponse; import com.gongjakso.server.global.security.PrincipalDetails; @@ -44,8 +42,28 @@ public ApplicationResponse updateNotRecruitStatus(@AuthenticationPrincipal return applyService.updateRecruit(applyId,false); } // 특정 지원자 지원서 가져오는 api - @GetMapping("/{apply_id}/application") - public ApplicationResponse findApplication(@AuthenticationPrincipal PrincipalDetails principalDetails,@PathVariable("apply_id") Long applyId){ - return applyService.findApplication(applyId); + @GetMapping("/{post_id}/{apply_id}/application") + public ApplicationResponse findApplication(@AuthenticationPrincipal PrincipalDetails principalDetails,@PathVariable("apply_id") Long applyId,@PathVariable("post_id") Long postId){ + return applyService.findApplication(applyId,postId); + } + //공고 카테고리 요청 api + @GetMapping("/{post_id}/category") + public ApplicationResponse getCategory(@PathVariable("post_id") Long postId){ + return applyService.findPostCategory(postId); + } +// //공고 마감 요청 api +// @PatchMapping("/{post_id}/close") +// public ApplicationResponse updatePostStatusToClose(@AuthenticationPrincipal PrincipalDetails principalDetails, @PathVariable("post_id") Long postId){ +// return applyService.updatePostState(postId,"close"); +// } +// //공고 취소 요청 api +// @PatchMapping("/{post_id}/cancel") +// public ApplicationResponse updatePostStatusToCancel(@AuthenticationPrincipal PrincipalDetails principalDetails, @PathVariable("post_id") Long postId){ +// return applyService.updatePostState(postId,"cancel"); +// } + //공고 기간 연장 요청 api + @PatchMapping("/{post_id}/extension") + public ApplicationResponse updatePostPeriod(@AuthenticationPrincipal PrincipalDetails principalDetails, @PathVariable("post_id") Long postId, @RequestBody PeriodReq req){ + return applyService.updatePostPeriod(postId,req); } } diff --git a/src/main/java/com/gongjakso/server/domain/apply/dto/ApplicationRes.java b/src/main/java/com/gongjakso/server/domain/apply/dto/ApplicationRes.java index e582246a..6a6a7c14 100644 --- a/src/main/java/com/gongjakso/server/domain/apply/dto/ApplicationRes.java +++ b/src/main/java/com/gongjakso/server/domain/apply/dto/ApplicationRes.java @@ -3,13 +3,16 @@ import com.gongjakso.server.domain.apply.entity.Apply; import lombok.Builder; +import java.util.List; + @Builder public record ApplicationRes( + Boolean is_decision, String application, - String recruit_part -// String[] category + String recruit_part, + List category ) { - public static ApplicationRes of(Apply apply){ - return new ApplicationRes(apply.getApplication(), apply.getRecruit_part()); + public static ApplicationRes of(Apply apply,List category){ + return new ApplicationRes(apply.getIs_decision(),apply.getApplication(), apply.getRecruit_part(),category); } } diff --git a/src/main/java/com/gongjakso/server/domain/apply/dto/ApplyReq.java b/src/main/java/com/gongjakso/server/domain/apply/dto/ApplyReq.java index 8adbfe15..bb13b372 100644 --- a/src/main/java/com/gongjakso/server/domain/apply/dto/ApplyReq.java +++ b/src/main/java/com/gongjakso/server/domain/apply/dto/ApplyReq.java @@ -8,9 +8,11 @@ public record ApplyReq( String application, String recruit_part, + String recruit_role, String type, Boolean is_pass, - Boolean is_open + Boolean is_open, + Boolean is_decision ) { public Apply toEntity(Member member, Post post_id){ return Apply.builder() @@ -18,9 +20,11 @@ public Apply toEntity(Member member, Post post_id){ .post(post_id) .application(application) .recruit_part(recruit_part) + .recruit_role(recruit_role) .type(PostType.valueOf(type)) .is_pass(false) .is_open(false) + .is_decision(false) .build(); } } diff --git a/src/main/java/com/gongjakso/server/domain/apply/dto/CategoryRes.java b/src/main/java/com/gongjakso/server/domain/apply/dto/CategoryRes.java new file mode 100644 index 00000000..42344b8f --- /dev/null +++ b/src/main/java/com/gongjakso/server/domain/apply/dto/CategoryRes.java @@ -0,0 +1,12 @@ +package com.gongjakso.server.domain.apply.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +public record CategoryRes( + List category +) { +} diff --git a/src/main/java/com/gongjakso/server/domain/apply/dto/PeriodReq.java b/src/main/java/com/gongjakso/server/domain/apply/dto/PeriodReq.java new file mode 100644 index 00000000..7f7ef49e --- /dev/null +++ b/src/main/java/com/gongjakso/server/domain/apply/dto/PeriodReq.java @@ -0,0 +1,6 @@ +package com.gongjakso.server.domain.apply.dto; + +public record PeriodReq( + int addDateNum +) { +} diff --git a/src/main/java/com/gongjakso/server/domain/apply/entity/Apply.java b/src/main/java/com/gongjakso/server/domain/apply/entity/Apply.java index 00684095..422a0774 100644 --- a/src/main/java/com/gongjakso/server/domain/apply/entity/Apply.java +++ b/src/main/java/com/gongjakso/server/domain/apply/entity/Apply.java @@ -32,6 +32,9 @@ public class Apply extends BaseTimeEntity { @Column(name = "recruit_part",nullable = false,columnDefinition = "varchar(50)") private String recruit_part; + @Column(name = "recruit_role",columnDefinition = "varchar(50)") + private String recruit_role; + @Enumerated(EnumType.STRING) private PostType type; @@ -41,15 +44,20 @@ public class Apply extends BaseTimeEntity { @Column(name = "is_open", columnDefinition = "boolean" ) private Boolean is_open; + @Column(name = "is_decision", columnDefinition = "boolean" ) + private Boolean is_decision; + @Builder - public Apply(Long applyId, Member member,Post post, String application,String recruit_part,PostType type, Boolean is_pass,Boolean is_open){ + public Apply(Long applyId, Member member,Post post, String application,String recruit_part,String recruit_role,PostType type, Boolean is_pass,Boolean is_open,Boolean is_decision){ this.applyId=applyId; this.member=member; this.post=post; this.application=application; this.recruit_part=recruit_part; + this.recruit_role=recruit_role; this.type=type; this.is_pass=is_pass; this.is_open=is_open; + this.is_decision=is_decision; } } diff --git a/src/main/java/com/gongjakso/server/domain/apply/repository/ApplyRepository.java b/src/main/java/com/gongjakso/server/domain/apply/repository/ApplyRepository.java index c9872998..8994bc51 100644 --- a/src/main/java/com/gongjakso/server/domain/apply/repository/ApplyRepository.java +++ b/src/main/java/com/gongjakso/server/domain/apply/repository/ApplyRepository.java @@ -1,6 +1,7 @@ package com.gongjakso.server.domain.apply.repository; import com.gongjakso.server.domain.apply.entity.Apply; +import com.gongjakso.server.domain.member.entity.Member; import com.gongjakso.server.domain.post.entity.Post; import org.springframework.data.jpa.repository.JpaRepository; @@ -9,4 +10,5 @@ public interface ApplyRepository extends JpaRepository { long countApplyByPost(Post post); List findAllByPost(Post post); + boolean existsApplyByMemberAndPost(Member member,Post post); } \ No newline at end of file diff --git a/src/main/java/com/gongjakso/server/domain/apply/service/ApplyService.java b/src/main/java/com/gongjakso/server/domain/apply/service/ApplyService.java index 51956e55..3322d229 100644 --- a/src/main/java/com/gongjakso/server/domain/apply/service/ApplyService.java +++ b/src/main/java/com/gongjakso/server/domain/apply/service/ApplyService.java @@ -1,20 +1,24 @@ package com.gongjakso.server.domain.apply.service; -import com.gongjakso.server.domain.apply.dto.ApplyList; -import com.gongjakso.server.domain.apply.dto.ApplyReq; -import com.gongjakso.server.domain.apply.dto.ApplicationRes; -import com.gongjakso.server.domain.apply.dto.ApplyRes; +import com.gongjakso.server.domain.apply.dto.*; import com.gongjakso.server.domain.apply.entity.Apply; import com.gongjakso.server.domain.apply.repository.ApplyRepository; import com.gongjakso.server.domain.member.entity.Member; +import com.gongjakso.server.domain.post.entity.Category; import com.gongjakso.server.domain.post.entity.Post; +import com.gongjakso.server.domain.post.enumerate.CategoryType; +import com.gongjakso.server.domain.post.repository.CategoryRepository; import com.gongjakso.server.domain.post.repository.PostRepository; import com.gongjakso.server.global.common.ApplicationResponse; +import com.gongjakso.server.global.exception.ApplicationException; +import com.gongjakso.server.global.exception.ErrorCode; import lombok.RequiredArgsConstructor; import org.springframework.transaction.annotation.Transactional; import org.springframework.stereotype.Service; import org.webjars.NotFoundException; +import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -24,18 +28,29 @@ public class ApplyService { private final ApplyRepository applyRepository; private final PostRepository postRepository; + private final CategoryRepository categoryRepository; public Apply save(Member member, Long post_id, ApplyReq req){ Post post = postRepository.findByPostId(post_id); if (post == null) { - // Handle the case where the Post entity with the given post_id is not found - throw new NotFoundException("Post not found with id: " + post_id); + throw new ApplicationException(ErrorCode.NOT_FOUND_POST_EXCEPTION); + }else { + //재지원 판단 + if(!applyRepository.existsApplyByMemberAndPost(member, post)){ + //지원 기간인지 판단 + if(post.getEndDate().isBefore(LocalDateTime.now())){ + throw new ApplicationException(ErrorCode.NOT_APPLY_EXCEPTION); + }else { + Apply apply = req.toEntity(member, post); + return applyRepository.save(apply); + } + }else { + throw new ApplicationException(ErrorCode.ALREADY_APPLY_EXCEPTION); + } } - Apply apply = req.toEntity(member, post); - return applyRepository.save(apply); } public ApplicationResponse findApply(Long post_id){ - Post post = postRepository.findById(post_id).orElseThrow(()->new NotFoundException("Post not found with id: " + post_id)); + Post post = postRepository.findById(post_id).orElseThrow(()->new ApplicationException(ErrorCode.NOT_FOUND_POST_EXCEPTION)); int current_person = (int) applyRepository.countApplyByPost(post); List applies = applyRepository.findAllByPost(post); List applyLists = applies.stream() @@ -44,31 +59,109 @@ public ApplicationResponse findApply(Long post_id){ ApplyRes applyRes = ApplyRes.of(post,current_person,applyLists); return ApplicationResponse.ok(applyRes); } + public ApplicationResponse findPostCategory(Long post_id){ + Post post = postRepository.findByPostId(post_id); + if (post == null) { + throw new ApplicationException(ErrorCode.NOT_FOUND_POST_EXCEPTION); + }else { + List categoryList = categoryRepository.findCategoryByPost(post); + List list = new ArrayList<>(); + if(categoryList!=null){ + for (Category category : categoryList){ + for(int i=0;i updateOpen(Long apply_id){ - Apply apply = applyRepository.findById(apply_id).orElseThrow(()->new NotFoundException("Apply not found with id: " + apply_id)); + Apply apply = applyRepository.findById(apply_id).orElseThrow(()->new ApplicationException(ErrorCode.NOT_FOUND_APPLY_EXCEPTION)); apply.setIs_open(true); return ApplicationResponse.ok(); } public ApplicationResponse updateRecruit(Long apply_id, Boolean isRecruit){ - Apply apply = applyRepository.findById(apply_id).orElseThrow(()->new NotFoundException("Apply not found with id: " + apply_id)); - apply.setIs_pass(isRecruit); - return ApplicationResponse.ok(); + Apply apply = applyRepository.findById(apply_id).orElseThrow(()->new ApplicationException(ErrorCode.NOT_FOUND_APPLY_EXCEPTION)); + if(!apply.getIs_decision()){ + apply.setIs_pass(isRecruit); + apply.setIs_decision(true); + Post post = apply.getPost(); + //지원 파트 size 감소 + Category category = categoryRepository.findCategoryByPostAndCategoryType(post, CategoryType.valueOf(apply.getRecruit_part())); + System.out.println("null"+",post:"+post+",categroy:"+apply.getRecruit_part()); + if(category.getSize()-1<=0){ + throw new ApplicationException(ErrorCode.OVER_APPLY_EXCEPTION); + }else { + category.setSize(category.getSize()-1); + return ApplicationResponse.ok(); + } + }else { + throw new ApplicationException(ErrorCode.ALREADY_DECISION_EXCEPION); + } + + } +// public ApplicationResponse updatePostState(Long post_id,String state){ +// Post post = postRepository.findById(post_id).orElseThrow(()->new ApplicationException(ErrorCode.NOT_FOUND_POST_EXCEPTION)); +// //공고 상태가 모집 중인지 판단 +// if(post.getStatus()==RECRUITING){ +// if(state.equals("close")){ +// post.setStatus(PostStatus.CLOSE); +// return ApplicationResponse.ok(); +// } else { +// post.setStatus(PostStatus.CANCEL); +// return ApplicationResponse.ok(); +// } +// }else { +// throw new ApplicationException(ErrorCode.NOT_RECRUITING_EXCEPION); +// } +// } + public ApplicationResponse updatePostPeriod(Long post_id, PeriodReq req) { + Post post = postRepository.findById(post_id).orElseThrow(()->new ApplicationException(ErrorCode.NOT_FOUND_POST_EXCEPTION)); + LocalDateTime extendedPeriod = post.getEndDate().plusDays(req.addDateNum()); +// //공고 상태가 모집 중인지 판단 +// if(post.getStatus()==RECRUITING){ + post.setEndDate(extendedPeriod); + return ApplicationResponse.ok(); +// }else { +// throw new ApplicationException(ErrorCode.NOT_RECRUITING_EXCEPION); +// } } - public ApplicationResponse findApplication(Long apply_id){ - Apply apply = applyRepository.findById(apply_id).orElseThrow(()->new NotFoundException("Apply not found with id: " + apply_id)); -// ApplicationRes applicationRes = ApplicationRes.builder().application(apply.getApplication()).recruit_part(apply.getRecruit_part()).build(); - ApplicationRes applicationRes = ApplicationRes.of(apply); + + public ApplicationResponse findApplication(Long apply_id,Long post_id){ + Apply apply = applyRepository.findById(apply_id).orElseThrow(()->new ApplicationException(ErrorCode.NOT_FOUND_APPLY_EXCEPTION)); + Post post = postRepository.findById(post_id).orElseThrow(()->new ApplicationException(ErrorCode.NOT_FOUND_POST_EXCEPTION)); + List categoryList = categoryRepository.findCategoryByPost(post); + List list = new ArrayList<>(); + if(categoryList!=null) { + for (Category category : categoryList) { + for (int i = 0; i < category.getSize(); i++) { + list.add(String.valueOf(category.getCategoryType())); + } + } + }else { + throw new ApplicationException(ErrorCode.NOT_FOUND_CATEGORY_EXCEPTION); + } + ApplicationRes applicationRes = ApplicationRes.of(apply,list); return ApplicationResponse.ok(applicationRes); } } diff --git a/src/main/java/com/gongjakso/server/domain/post/entity/Category.java b/src/main/java/com/gongjakso/server/domain/post/entity/Category.java index ada2ac51..141cbfc2 100644 --- a/src/main/java/com/gongjakso/server/domain/post/entity/Category.java +++ b/src/main/java/com/gongjakso/server/domain/post/entity/Category.java @@ -3,12 +3,10 @@ import com.gongjakso.server.domain.post.enumerate.CategoryType; import com.gongjakso.server.global.common.BaseTimeEntity; import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; @Getter +@Setter @Entity @Table(name = "category") @NoArgsConstructor(access = AccessLevel.PROTECTED) diff --git a/src/main/java/com/gongjakso/server/domain/post/entity/Post.java b/src/main/java/com/gongjakso/server/domain/post/entity/Post.java index 4ef2375a..4cb5c8c3 100644 --- a/src/main/java/com/gongjakso/server/domain/post/entity/Post.java +++ b/src/main/java/com/gongjakso/server/domain/post/entity/Post.java @@ -11,12 +11,11 @@ import jakarta.persistence.Id; import jakarta.persistence.Table; import java.time.LocalDateTime; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; + +import lombok.*; @Getter +@Setter @Entity @Table(name = "post") @NoArgsConstructor(access = AccessLevel.PROTECTED) diff --git a/src/main/java/com/gongjakso/server/domain/post/enumerate/CategoryType.java b/src/main/java/com/gongjakso/server/domain/post/enumerate/CategoryType.java index cb8304b3..516ddd12 100644 --- a/src/main/java/com/gongjakso/server/domain/post/enumerate/CategoryType.java +++ b/src/main/java/com/gongjakso/server/domain/post/enumerate/CategoryType.java @@ -1,4 +1,5 @@ package com.gongjakso.server.domain.post.enumerate; public enum CategoryType { + PLAN,DESIGN,FE,BE,ETC,LATER } diff --git a/src/main/java/com/gongjakso/server/domain/post/repository/CategoryRepository.java b/src/main/java/com/gongjakso/server/domain/post/repository/CategoryRepository.java index 4972d2b5..0f88f4f0 100644 --- a/src/main/java/com/gongjakso/server/domain/post/repository/CategoryRepository.java +++ b/src/main/java/com/gongjakso/server/domain/post/repository/CategoryRepository.java @@ -1,8 +1,13 @@ package com.gongjakso.server.domain.post.repository; import com.gongjakso.server.domain.post.entity.Category; +import com.gongjakso.server.domain.post.entity.Post; +import com.gongjakso.server.domain.post.enumerate.CategoryType; import org.springframework.data.jpa.repository.JpaRepository; -public interface CategoryRepository extends JpaRepository { +import java.util.List; +public interface CategoryRepository extends JpaRepository { + List findCategoryByPost(Post post); + Category findCategoryByPostAndCategoryType(Post post, CategoryType categoryType); } diff --git a/src/main/java/com/gongjakso/server/global/exception/ErrorCode.java b/src/main/java/com/gongjakso/server/global/exception/ErrorCode.java index 55f5e931..e973472e 100644 --- a/src/main/java/com/gongjakso/server/global/exception/ErrorCode.java +++ b/src/main/java/com/gongjakso/server/global/exception/ErrorCode.java @@ -26,7 +26,17 @@ public enum ErrorCode { KAKAO_TOKEN_EXCEPTION(HttpStatus.INTERNAL_SERVER_ERROR, 3000, "토큰 발급에서 오류가 발생했습니다."), KAKAO_USER_EXCEPTION(HttpStatus.INTERNAL_SERVER_ERROR, 3001, "카카오 프로필 정보를 가져오는 과정에서 오류가 발생했습니디."), WRONG_TOKEN_EXCEPTION(HttpStatus.UNAUTHORIZED, 3002, "유효하지 않은 토큰입니다."), - LOGOUT_TOKEN_EXCEPTION(HttpStatus.UNAUTHORIZED, 3003, "로그아웃된 토큰입니다"); + LOGOUT_TOKEN_EXCEPTION(HttpStatus.UNAUTHORIZED, 3003, "로그아웃된 토큰입니다"), + + //4000: Apply Error + NOT_APPLY_EXCEPTION(HttpStatus.BAD_REQUEST,4000,"지원 기간 지났습니다"), + NOT_FOUND_POST_EXCEPTION(HttpStatus.NOT_FOUND,4001,"존재하지 않는 글입니다."), + NOT_FOUND_APPLY_EXCEPTION(HttpStatus.NOT_FOUND,4002,"존재하지 않는 지원서입니다."), + ALREADY_APPLY_EXCEPTION(HttpStatus.BAD_REQUEST,4003,"이미 지원했습니다."), + ALREADY_DECISION_EXCEPION(HttpStatus.BAD_REQUEST,4004,"이미 지원 결정했습니다."), + NOT_RECRUITING_EXCEPION(HttpStatus.BAD_REQUEST,4005,"이 공고는 모집 중이 아닙니다."), + NOT_FOUND_CATEGORY_EXCEPTION(HttpStatus.NOT_FOUND,4006,"카테고리가 없습니다"), + OVER_APPLY_EXCEPTION(HttpStatus.NOT_FOUND,4007,"지원 파트 정원이 찼습니다."); private final HttpStatus httpStatus; private final Integer code;