Skip to content

Commit

Permalink
️♻️ refactor: 공고 상태 변경 기능 분리 (#182)
Browse files Browse the repository at this point in the history
* refactor: 공고 상태 수정 API 분리

* fix: enum 관련 에러 처리 수정
  • Loading branch information
kimday0326 authored Feb 12, 2024
1 parent 6c53cbe commit 5b450bb
Show file tree
Hide file tree
Showing 13 changed files with 77 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
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;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
Expand All @@ -18,6 +19,7 @@
import com.sponus.sponusbe.domain.announcement.dto.request.AnnouncementUpdateRequest;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementCreateResponse;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementDetailResponse;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementStatusUpdateResponse;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementSummaryResponse;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementUpdateResponse;
import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementCategory;
Expand Down Expand Up @@ -108,6 +110,16 @@ public ApiResponse<AnnouncementUpdateResponse> updateAnnouncement(
));
}

@PatchMapping("/{announcementId}/status")
public ApiResponse<AnnouncementUpdateResponse> updateAnnouncementStatus(
@AuthOrganization Organization authOrganization,
@PathVariable Long announcementId,
@RequestBody @Valid AnnouncementStatusUpdateResponse request
) {
return ApiResponse.onSuccess(
announcementService.updateAnnouncementStatus(authOrganization, announcementId, request));
}

@GetMapping("/category")
public ApiResponse<List<AnnouncementSummaryResponse>> getAnnouncementByCategory(
@RequestParam(value = "category", required = false) AnnouncementCategory category,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.sponus.sponusbe.domain.announcement.dto.request;

import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementCategory;
import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementStatus;
import com.sponus.sponusbe.domain.announcement.entity.enums.AnnouncementType;

import lombok.Builder;
Expand All @@ -11,7 +10,6 @@ public record AnnouncementUpdateRequest(
String title,
AnnouncementType type,
AnnouncementCategory category,
String content,
AnnouncementStatus status
String content
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.sponus.sponusbe.domain.announcement.dto.response;

import jakarta.validation.constraints.NotBlank;

public record AnnouncementStatusUpdateResponse(
@NotBlank(message = "[ERROR] 공고 상태 입력은 필수 입니다.")
String status
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,15 @@ public void increaseViewCount() {
this.viewCount++;
}

public void updateInfo(String title, AnnouncementType type, AnnouncementCategory category, String content,
AnnouncementStatus status) {
public void updateInfo(String title, AnnouncementType type, AnnouncementCategory category, String content) {
this.title = title == null ? this.title : title;
this.type = type == null ? this.type : type;
this.category = category == null ? this.category : category;
this.content = content == null ? this.content : content;
this.status = (status != null) ? status : this.status;
}

public void updateStatus(AnnouncementStatus status) {
this.status = status;
}

public void updateViewCount(long viewCount) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
package com.sponus.sponusbe.domain.announcement.entity.enums;

import com.sponus.sponusbe.domain.announcement.exception.AnnouncementErrorCode;
import com.sponus.sponusbe.domain.announcement.exception.AnnouncementException;

public enum AnnouncementStatus {
OPENED, CLOSED
OPENED, CLOSED;

public static AnnouncementStatus of(String input) {
try {
return AnnouncementStatus.valueOf(input.toUpperCase());
} catch (Exception e) {
throw new AnnouncementException(AnnouncementErrorCode.INVALID_ANNOUNCEMENT_STATUS);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public enum AnnouncementErrorCode implements BaseErrorCode {
INVALID_ORGANIZATION(HttpStatus.BAD_REQUEST, "ANC4002", "해당 단체의 공고가 아닙니다."),
CLOSED_ANNOUNCEMENT_STATUS(HttpStatus.BAD_REQUEST, "ANC4003", "마감된 공고는 수정할 수 없습니다."),
ANNOUNCEMENT_NOT_IN_PROGRESS(HttpStatus.BAD_REQUEST, "ANC4004", "진행 중인 공고가 아닙니다."),
INVALID_ANNOUNCEMENT_STATUS(HttpStatus.BAD_REQUEST, "ANC4005", "유효하지 않은 공고 상태입니다."),
ANNOUNCEMENT_NOT_FOUND(HttpStatus.NOT_FOUND, "ANC4040", "해당 공고가 존재하지 않습니다.");

private final HttpStatus httpStatus;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.sponus.sponusbe.domain.announcement.dto.request.AnnouncementUpdateRequest;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementCreateResponse;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementDetailResponse;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementStatusUpdateResponse;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementSummaryResponse;
import com.sponus.sponusbe.domain.announcement.dto.response.AnnouncementUpdateResponse;
import com.sponus.sponusbe.domain.announcement.entity.Announcement;
Expand Down Expand Up @@ -85,11 +86,11 @@ public void deleteAnnouncement(Organization organization, Long announcementId) {

public AnnouncementUpdateResponse updateAnnouncement(
Organization authOrganization,
Long proposeId,
Long announcementId,
AnnouncementUpdateRequest request,
List<MultipartFile> images
) {
final Announcement announcement = announcementRepository.findById(proposeId)
final Announcement announcement = announcementRepository.findById(announcementId)
.orElseThrow(() -> new AnnouncementException(AnnouncementErrorCode.ANNOUNCEMENT_NOT_FOUND));

if (announcement.getStatus() != AnnouncementStatus.OPENED)
Expand All @@ -101,15 +102,26 @@ public AnnouncementUpdateResponse updateAnnouncement(
request.title(),
request.type(),
request.category(),
request.content(),
request.status()
request.content()
);

// 공고는 이미지가 필수이므로, 이미지가 없는 경우에는 업데이트하지 않음
if (images != null)
updateAnnouncementImages(announcement, images);

announcementRepository.save(announcement);
return AnnouncementUpdateResponse.from(announcement);
}

public AnnouncementUpdateResponse updateAnnouncementStatus(
Organization authOrganization,
Long announcementId,
AnnouncementStatusUpdateResponse request) {
final Announcement announcement = announcementRepository.findById(announcementId)
.orElseThrow(() -> new AnnouncementException(AnnouncementErrorCode.ANNOUNCEMENT_NOT_FOUND));
if (!isOrganizationsAnnouncement(authOrganization.getId(), announcement))
throw new AnnouncementException(AnnouncementErrorCode.INVALID_ORGANIZATION);

announcement.updateStatus(AnnouncementStatus.of(request.status()));
return AnnouncementUpdateResponse.from(announcement);
}

Expand Down Expand Up @@ -146,5 +158,4 @@ private void updateAnnouncementImages(Announcement announcement, List<MultipartF
announcementImage.setAnnouncement(announcement);
});
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ public ApiResponse<Void> acceptPropose(
proposeService.updateProposeStatus(
authOrganization,
proposeId,
request.status()
);
request);
return ApiResponse.onSuccess(null);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.sponus.sponusbe.domain.propose.dto.request;

import com.sponus.sponusbe.domain.propose.entity.ProposeStatus;

import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.NotBlank;

public record ProposeStatusUpdateRequest(
@NotNull(message = "[ERROR] 제안 상태 입력은 필수 입니다.")
ProposeStatus status
@NotBlank(message = "[ERROR] 제안 상태 입력은 필수 입니다.")
String status
) {
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
package com.sponus.sponusbe.domain.propose.entity;

import com.sponus.sponusbe.domain.propose.exception.ProposeErrorCode;
import com.sponus.sponusbe.domain.propose.exception.ProposeException;

public enum ProposeStatus {
// 제안을 보낸 측: PENDING
// 제안을 받은 측: VIEWED, ACCEPTED, REJECTED, SUSPENDED, ACCEPTED_AND_PAID
PENDING, VIEWED, ACCEPTED, REJECTED, SUSPENDED, ACCEPTED_AND_PAID,
// 열람됨
PENDING, VIEWED, ACCEPTED, REJECTED, SUSPENDED, ACCEPTED_AND_PAID;

public static ProposeStatus of(String input) {
try {
return ProposeStatus.valueOf(input.toUpperCase());
} catch (Exception e) {
throw new ProposeException(ProposeErrorCode.INVALID_PROPOSE_STATUS);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public enum ProposeErrorCode implements BaseErrorCode {
INVALID_PROPOSING_ORGANIZATION(HttpStatus.BAD_REQUEST, "PROP4002", "해당 단체가 작성한 제안이 아닙니다."),
INVALID_PROPOSED_ORGANIZATION(HttpStatus.BAD_REQUEST, "PROP4003", "제안을 받은 단체만 접근이 가능합니다."),
PROPOSE_STATUS_NOT_PENDING(HttpStatus.BAD_REQUEST, "PROP4004", "수락 대기 중인 제안만 수정이 가능합니다."),
INVALID_PROPOSE_STATUS(HttpStatus.BAD_REQUEST, "PROP4005", "유효하지 않은 제안 상태입니다."),
PROPOSE_NOT_FOUND(HttpStatus.NOT_FOUND, "PROP4040", "해당 제안이 존재하지 않습니다.");

private final HttpStatus httpStatus;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.sponus.sponusbe.domain.notification.service.FirebaseService;
import com.sponus.sponusbe.domain.organization.entity.Organization;
import com.sponus.sponusbe.domain.propose.dto.request.ProposeCreateRequest;
import com.sponus.sponusbe.domain.propose.dto.request.ProposeStatusUpdateRequest;
import com.sponus.sponusbe.domain.propose.dto.request.ProposeUpdateRequest;
import com.sponus.sponusbe.domain.propose.dto.response.ProposeCreateResponse;
import com.sponus.sponusbe.domain.propose.dto.response.ProposeDetailGetResponse;
Expand Down Expand Up @@ -102,13 +103,13 @@ public void deletePropose(Organization authOrganization, Long proposeId) {
proposeRepository.delete(propose);
}

public void updateProposeStatus(Organization authOrganization, Long proposeId, ProposeStatus status) {
public void updateProposeStatus(Organization authOrganization, Long proposeId, ProposeStatusUpdateRequest status) {
final Propose propose = proposeRepository.findById(proposeId)
.orElseThrow(() -> new ProposeException(ProposeErrorCode.PROPOSE_NOT_FOUND));
// 제안을 "받은" 단체만 가능
if (!isProposedOrganization(authOrganization.getId(), propose))
throw new ProposeException(ProposeErrorCode.INVALID_PROPOSED_ORGANIZATION);
propose.updateStatus(status);
propose.updateStatus(ProposeStatus.of(status.status()));
}

private Announcement getAvailableAnnouncement(Long announcementId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public ResponseEntity<ApiResponse<String>> handleAllException(Exception e) {

@ExceptionHandler({CustomException.class})
public ResponseEntity<ApiResponse<Void>> handleCustomException(CustomException e) {
log.warn(">>>>> Custom Exception : {}", e.getMessage());
BaseErrorCode errorCode = e.getErrorCode();
log.warn(">>>>> Custom Exception : {}", errorCode.getMessage());
return ResponseEntity.status(errorCode.getHttpStatus()).body(errorCode.getErrorResponse());
}

Expand Down Expand Up @@ -65,16 +65,4 @@ protected ResponseEntity<ApiResponse<Map<String, String>>> handleMethodArgumentN
failedValidations);
return ResponseEntity.status(ex.getStatusCode()).body(errorResponse);
}
//
// @ExceptionHandler({SecurityCustomException.class})
// public ResponseEntity<ApiResponse<String>> handleAuthenticationException(Exception e) {
// log.error(">>>>> Security Server Error : ", e);
// BaseErrorCode errorCode = SecurityErrorCode.INTERNAL_TOKEN_SERVER_ERROR;
// ApiResponse<String> errorResponse = ApiResponse.onFailure(
// errorCode.getCode(),
// errorCode.getMessage(),
// e.getMessage()
// );
// return ResponseEntity.internalServerError().body(errorResponse);
// }
}

0 comments on commit 5b450bb

Please sign in to comment.