- 변경/해지 상태 표시 및 취소 기능 추가 - 해지 신청 사전검사 및 경고 메시지 처리 구현 - 관리자 승인 이전 허용되는 취소 정책 지원
This commit is contained in:
@@ -23,6 +23,9 @@ public class ProcessingState implements ApprovalState {
|
||||
case DENY:
|
||||
handleDeny(approval, options);
|
||||
break;
|
||||
case CANCEL:
|
||||
handleCancel(approval, options);
|
||||
break;
|
||||
default:
|
||||
logger.warn("Invalid event {} for ProcessingState in approval {}", event, approval.getId());
|
||||
throw new UnsupportedOperationException("Invalid event for Processing state");
|
||||
@@ -91,6 +94,38 @@ public class ProcessingState implements ApprovalState {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 신청자 취소. 심사중(PROCESSING)이라도 <b>아직 아무도 승인하지 않은</b> 경우에 한해 허용한다.
|
||||
*
|
||||
* <p>관리자가 결재 상세를 열어보기만 해도 REQUESTED → PROCESSING 으로 바뀌므로(admin
|
||||
* {@code PortalApprovalManService.selectDetail}), 이 상태의 상당수는 실제로 결재가 진행된 것이
|
||||
* 아니라 열람만 된 건이다. 그런 건이 취소 불가로 남으면 해당 인증키의 후속 신청(변경/해지)이
|
||||
* 무기한 막힌다. 승인 이력이 하나라도 있으면 기존 정책대로 거절한다.</p>
|
||||
*/
|
||||
private void handleCancel(Approval approval, Map<String, Object> options) {
|
||||
boolean anyApproved = approval.getApprovers().stream()
|
||||
.anyMatch(approver -> ApproverStatus.APPROVED.equals(approver.getApproverStatus()));
|
||||
if (anyApproved) {
|
||||
logger.warn("Cancel rejected for approval {} - already approved by at least one approver", approval.getId());
|
||||
throw new UnsupportedOperationException("Cannot cancel approval already approved by an approver");
|
||||
}
|
||||
|
||||
String approverId = (String) options.getOrDefault(ApprovalConstants.APPROVER, "");
|
||||
if (!isAuthorizedApprover(approval, approverId, options)) {
|
||||
logger.warn("Unauthorized cancel attempt for approval {} by {}", approval.getId(), approverId);
|
||||
throw new UnauthorizedApprovalException("Unauthorized approver");
|
||||
}
|
||||
|
||||
approval.getApprovers().forEach(approver -> {
|
||||
approver.setApproverStatus(ApproverStatus.CANCELED);
|
||||
approver.setApprovedDate(LocalDateTime.now());
|
||||
});
|
||||
approval.setApprovalDate(LocalDateTime.now());
|
||||
getApprovalListener(options).rollback(approval);
|
||||
approval.setApprovalStatus(new CanceledState());
|
||||
logger.info("Approval {} cancelled in Processing state by {}", approval.getId(), approverId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ApprovalStatus.PROCESSING.toString();
|
||||
|
||||
Reference in New Issue
Block a user