Skip to content

Commit

Permalink
[FEAT] 프로젝트 취소 기능 구
Browse files Browse the repository at this point in the history
  • Loading branch information
happyjamy committed Feb 18, 2024
1 parent 9ecee3c commit 224024f
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
@SuppressWarnings("unused")
public interface ProjectSwagger {

@Operation(summary = "프로젝트 카드 생성", description = "회원이 프로젝트 카드를 생성할 때 사용하는 API"
)
@Operation(summary = "프로젝트 카드 생성", description = "회원이 프로젝트 카드를 생성할 때 사용하는 API")
@ApiResponses(value = {
@ApiResponse(responseCode = "201", description = "프로젝트 카드 생성 성공",
content = @Content(schema = @Schema(implementation = ProjectIdRes.class))),
Expand Down Expand Up @@ -51,8 +50,7 @@ ResponseEntity<ProjectIdRes> create(
ProjectCreateReq request
);

@Operation(summary = "프로젝트 카드 삭제", description = "회원이 프로젝트 카드를 삭제할 때 사용하는 API"
)
@Operation(summary = "프로젝트 카드 삭제", description = "회원이 프로젝트 카드를 삭제할 때 사용하는 API")
@ApiResponses(value = {
@ApiResponse(responseCode = "204", description = "프로젝트 카드 삭제 성공"),
@ApiResponse(responseCode = "400", description = "프로젝트를 삭제 할 수 없습니다.",
Expand Down Expand Up @@ -80,4 +78,33 @@ ResponseEntity<Void> delete(
@Parameter(hidden = true) Long userId,
@Parameter(description = "프로젝트 ID", required = true) Long id
);

@Operation(summary = "프로젝트 카드 취소", description = "회원이 프로젝트 카드를 임의로 취소 할때 사용하는 API")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "프로젝트 카드 취소 성공"),
@ApiResponse(responseCode = "400", description = "프로젝트를 취소 할 수 없습니다.",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = ErrorResponse.class),
examples = {
@ExampleObject(name = "E030107", value = SwaggerProjectErrorExamples.PROJECT_CANCEL_NOT_ALLOWED)
})),
@ApiResponse(responseCode = "404", description = "요청한 데이터가 존재하지 않음",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = ErrorResponse.class),
examples = {
@ExampleObject(name = "E030301", value = SwaggerProjectErrorExamples.PROJECT_NOT_FOUND),
@ExampleObject(name = "E020301", value = SwaggerUserErrorExamples.USER_NOT_FOUND)
})),
@ApiResponse(responseCode = "403", description = "프로젝트 카드 취소 권한이 없음",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = ErrorResponse.class),
examples = @ExampleObject(name = "E030201", value = SwaggerProjectErrorExamples.PROJECT_FORBIDDEN_OPERATION)))
})
ResponseEntity<ProjectIdRes> cancel(
@Parameter(hidden = true) Long userId,
@Parameter(description = "프로젝트 ID", required = true) Long id
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public class SwaggerProjectErrorExamples {
public static final String PROJECT_NOT_FOUND = "{\"timestamp\":\"2024-02-17T10:07:31.404Z\",\"statusCode\":404,\"code\":\"E030301\",\"message\":\"해당 프로젝트가 존재하지 않습니다.\"}";
public static final String PROJECT_FORBIDDEN_OPERATION = "{\"timestamp\":\"2024-02-17T10:07:31.404Z\",\"statusCode\":403,\"code\":\"E030201\",\"message\":\"해당 프로젝트에 대한 권한이 없습니다.\"}";
public static final String PROJECT_DELETION_NOT_ALLOWED = "{\"timestamp\":\"2024-02-17T10:07:31.404Z\",\"statusCode\":400,\"code\":\"E030106\",\"message\":\"매칭 중이거나 대기중인 프로젝트는 삭제할 수 없습니다.\"}";
public static final String PROJECT_CANCEL_NOT_ALLOWED = "{\"timestamp\":\"2024-02-17T10:07:31.404Z\",\"statusCode\":400,\"code\":\"E030107\",\"message\":\"이미 취소 되었거나 종료된 프로젝트는 취소할 수 없습니다.\"}";
private SwaggerProjectErrorExamples() {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import io.oeid.mogakgo.domain.project.exception.ProjectException;
import io.oeid.mogakgo.domain.project.infrastructure.ProjectJpaRepository;
import io.oeid.mogakgo.domain.project.presentation.dto.req.ProjectCreateReq;
import io.oeid.mogakgo.domain.project_join_req.infrastruture.ProjectJoinRequestJpaRepository;
import io.oeid.mogakgo.domain.user.domain.User;
import io.oeid.mogakgo.domain.user.exception.UserException;
import io.oeid.mogakgo.domain.user.infrastructure.UserJpaRepository;
Expand All @@ -26,6 +27,7 @@ public class ProjectService {
private final UserJpaRepository userJpaRepository;
private final ProjectJpaRepository projectJpaRepository;
private final GeoService geoService;
private final ProjectJoinRequestJpaRepository projectJoinRequestJpaRepository;

@Transactional
public Long create(Long userId, ProjectCreateReq request) {
Expand Down Expand Up @@ -57,6 +59,20 @@ public void delete(Long userId, Long projectId) {
project.delete(user);
}

public void cancel(Long userId, Long projectId) {
// 유저 존재 여부 체크
User user = getUser(userId);

// 프로젝트 존재 여부 체크
Project project = getProject(projectId);

// 매칭이 되었거나, 매칭 준비중이지만 요청이 있을때는 잔디력 감소를 위한 변수
boolean projectHasReq = projectJoinRequestJpaRepository.existsByProjectId(projectId);

// 프로젝트 취소
project.cancel(user, projectHasReq);
}

private User getUser(Long userId) {
return userJpaRepository.findById(userId)
.orElseThrow(() -> new UserException(USER_NOT_FOUND));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,20 @@ public void delete(User tokenUser) {
super.delete();
}

public void cancel(User tokenUser, boolean projectHasReq) {
validateAvailableCancel(tokenUser);
// 매칭이 되었거나, 매칭 준비중이지만 요청이 있을때는 잔디력 감소
if (projectHasReq) {
this.creator.decreaseJandiRate();
}
this.projectStatus = ProjectStatus.CANCELED;
}

private void validateAvailableCancel(User tokenUser) {
validateCreator(tokenUser);
this.projectStatus.validateAvailableCancel();
}

private void validateAvailableDelete(User tokenUser) {
validateCreator(tokenUser);
this.projectStatus.validateAvailableDelete();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.oeid.mogakgo.domain.project.domain.entity.enums;

import static io.oeid.mogakgo.exception.code.ErrorCode400.PROJECT_CANCEL_NOT_ALLOWED;
import static io.oeid.mogakgo.exception.code.ErrorCode400.PROJECT_DELETION_NOT_ALLOWED;

import io.oeid.mogakgo.domain.project.exception.ProjectException;
Expand All @@ -23,4 +24,10 @@ public void validateAvailableDelete() {
throw new ProjectException(PROJECT_DELETION_NOT_ALLOWED);
}
}

public void validateAvailableCancel() {
if (this == CANCELED || this == FINISHED) {
throw new ProjectException(PROJECT_CANCEL_NOT_ALLOWED);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
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;
Expand All @@ -22,7 +23,6 @@ public class ProjectController implements ProjectSwagger {

private final ProjectService projectService;

@Override
@PostMapping
public ResponseEntity<ProjectIdRes> create(
@UserId Long userId, @Valid @RequestBody ProjectCreateReq request
Expand All @@ -39,4 +39,12 @@ public ResponseEntity<Void> delete(
return ResponseEntity.noContent().build();
}

@PatchMapping("/{id}/cancel")
public ResponseEntity<ProjectIdRes> cancel(
@UserId Long userId, @PathVariable Long id
) {
projectService.cancel(userId, id);
return ResponseEntity.status(200).body(ProjectIdRes.from(id));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public enum ErrorCode400 implements ErrorCode {
INVALID_PROJECT_NULL_DATA("E030104", "프로젝트를 생성하기 위해 null 이여서는 안되는 데이터가 null 입니다."),
NOT_MATCH_MEET_LOCATION("E030105", "프로젝트 만남 장소가 유저가 동네인증 한 구역이 아닙니다."),
PROJECT_DELETION_NOT_ALLOWED("E030106", "매칭 중이거나 대기중인 프로젝트는 삭제할 수 없습니다."),
PROJECT_CANCEL_NOT_ALLOWED("E030107", "이미 취소 되었거나 종료된 프로젝트는 취소할 수 없습니다."),

USER_DEVELOP_LANGUAGE_BAD_REQUEST("E020101", "개발 언어는 3개까지만 등록 가능합니다."),
USER_WANTED_JOB_BAD_REQUEST("E020102", "희망 직무는 3개까지만 등록 가능합니다."),
Expand Down

0 comments on commit 224024f

Please sign in to comment.