Skip to content

Commit d2a862b

Browse files
authored
feature/KD-73: 자격증 신청 관리 메뉴와 졸업 논문 관리 메뉴에서 승인된 사용자 승인 취소 기능 추가 (#330)
* feature/KD-73: 자격증 신청 관리 메뉴와 졸업 논문 관리 메뉴에서 승인된 사용자 승인 취소 기능 추가 * refactor: GraduationUserAdminController assignee 수정 * test: 테스트 코드 추가
1 parent 9887688 commit d2a862b

File tree

11 files changed

+187
-0
lines changed

11 files changed

+187
-0
lines changed

aics-admin/src/main/java/kgu/developers/admin/graduationUser/application/GraduationUserAdminFacade.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserBatchApproveRequest;
55
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserBatchCreateRequest;
66
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserBatchDeleteRequest;
7+
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserBatchDisapproveRequest;
78
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserCreateRequest;
89
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserBatchApproveResponse;
910
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserBatchCreateResponse;
1011
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserBatchDeleteResponse;
12+
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserBatchDisapproveResponse;
1113
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserDetailResponse;
1214
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserPersistResponse;
1315
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserStatusResponse;
@@ -190,4 +192,36 @@ public GraduationUserBatchApproveResponse approveGraduationUsers(GraduationUserB
190192

191193
return GraduationUserBatchApproveResponse.from(approvedUserIds);
192194
}
195+
196+
public GraduationUserBatchDisapproveResponse disapproveGraduationUsers(GraduationUserBatchDisapproveRequest request) {
197+
List<GraduationUser> users = request.ids().stream()
198+
.map(graduationUserQueryService::getById)
199+
.toList();
200+
201+
List<Long> disapprovedUserIds = new ArrayList<>();
202+
203+
for(GraduationUser user: users) {
204+
if(user.getGraduationType() == GraduationType.CERTIFICATE) {
205+
if(user.getCertificateId() == null) continue;
206+
boolean disapproved = certificateCommandService.disapprove(user.getCertificateId());
207+
if(disapproved) disapprovedUserIds.add(user.getId());
208+
} else if(user.getGraduationType() == GraduationType.THESIS) {
209+
boolean midThesisdisapproved = false;
210+
boolean finalThesisdisapproved = false;
211+
212+
if(user.getMidThesisId() != null) {
213+
midThesisdisapproved = thesisCommandService.disapprove(user.getMidThesisId());
214+
}
215+
216+
if(user.getFinalThesisId() != null) {
217+
finalThesisdisapproved = thesisCommandService.disapprove(user.getFinalThesisId());
218+
}
219+
220+
if(midThesisdisapproved || finalThesisdisapproved)
221+
disapprovedUserIds.add(user.getId());
222+
}
223+
}
224+
225+
return GraduationUserBatchDisapproveResponse.from(disapprovedUserIds);
226+
}
193227
}

aics-admin/src/main/java/kgu/developers/admin/graduationUser/presentation/GraduationUserAdminController.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserBatchApproveRequest;
1313
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserBatchCreateRequest;
1414
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserBatchDeleteRequest;
15+
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserBatchDisapproveRequest;
1516
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserCreateRequest;
1617
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserBatchApproveResponse;
1718
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserBatchCreateResponse;
1819
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserBatchDeleteResponse;
20+
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserBatchDisapproveResponse;
1921
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserDetailResponse;
2022
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserPersistResponse;
2123
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserSummaryPageResponse;
@@ -148,4 +150,16 @@ ResponseEntity<GraduationUserBatchApproveResponse> approveGraduationUsers(
148150
required = true
149151
) @Valid @RequestBody GraduationUserBatchApproveRequest request
150152
);
153+
154+
@Operation(summary = "졸업 대상자 일괄 승인 취소 API", description = """
155+
- Description : 이 API는 선택한 여러 졸업 대상자의 제출을 일괄 승인 취소합니다.
156+
- Assignee : 황호찬
157+
""")
158+
@ApiResponse(responseCode = "200")
159+
ResponseEntity<GraduationUserBatchDisapproveResponse> disapproveGraduationUsers(
160+
@Parameter(
161+
description = "승인 취소할 졸업 대상자 ID 목록",
162+
required = true
163+
) @Valid @RequestBody GraduationUserBatchDisapproveRequest request
164+
);
151165
}

aics-admin/src/main/java/kgu/developers/admin/graduationUser/presentation/GraduationUserAdminControllerImpl.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserBatchApproveRequest;
99
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserBatchCreateRequest;
1010
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserBatchDeleteRequest;
11+
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserBatchDisapproveRequest;
1112
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserCreateRequest;
1213
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserBatchApproveResponse;
1314
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserBatchCreateResponse;
1415
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserBatchDeleteResponse;
16+
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserBatchDisapproveResponse;
1517
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserDetailResponse;
1618
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserPersistResponse;
1719
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserSummaryPageResponse;
@@ -124,4 +126,13 @@ public ResponseEntity<GraduationUserBatchApproveResponse> approveGraduationUsers
124126
GraduationUserBatchApproveResponse response = graduationUserAdminFacade.approveGraduationUsers(request);
125127
return ResponseEntity.ok(response);
126128
}
129+
130+
@Override
131+
@PatchMapping("/batch/disapprove")
132+
public ResponseEntity<GraduationUserBatchDisapproveResponse> disapproveGraduationUsers(
133+
@Valid @RequestBody GraduationUserBatchDisapproveRequest request
134+
) {
135+
GraduationUserBatchDisapproveResponse response = graduationUserAdminFacade.disapproveGraduationUsers(request);
136+
return ResponseEntity.ok(response);
137+
}
127138
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package kgu.developers.admin.graduationUser.presentation.request;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import jakarta.validation.constraints.NotEmpty;
5+
import jakarta.validation.constraints.Positive;
6+
import lombok.Builder;
7+
8+
import java.util.List;
9+
10+
@Builder
11+
public record GraduationUserBatchDisapproveRequest(
12+
@Schema(description = "승인 취소할 졸업 대상자 ID 목록", example = "[1, 2, 3]")
13+
@NotEmpty(message = "승인 취소할 대상자를 선택해주세요.")
14+
List<@Positive(message = "잘못된 ID 형식입니다.") Long> ids
15+
) {
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package kgu.developers.admin.graduationUser.presentation.response;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import lombok.Builder;
5+
6+
import java.util.List;
7+
8+
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
9+
10+
@Builder
11+
public record GraduationUserBatchDisapproveResponse(
12+
@Schema(description = "승인 취소 처리된 졸업 대상자 ID 목록", example = "[1, 2, 3, 4, 5]", requiredMode = REQUIRED)
13+
List<Long> disapprovedIds
14+
) {
15+
public static GraduationUserBatchDisapproveResponse from(List<Long> disapprovedUserIds) {
16+
return GraduationUserBatchDisapproveResponse.builder()
17+
.disapprovedIds(disapprovedUserIds)
18+
.build();
19+
}
20+
}

aics-admin/src/testFixtures/java/graduationUser/application/GraduationUserAdminFacadeTest.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserBatchApproveRequest;
55
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserBatchCreateRequest;
66
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserBatchDeleteRequest;
7+
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserBatchDisapproveRequest;
78
import kgu.developers.admin.graduationUser.presentation.request.GraduationUserCreateRequest;
89
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserBatchCreateResponse;
10+
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserBatchDisapproveResponse;
911
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserDetailResponse;
1012
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserPersistResponse;
1113
import kgu.developers.admin.graduationUser.presentation.response.GraduationUserSummaryPageResponse;
@@ -313,4 +315,64 @@ public void approveGraduationUsers_Success() {
313315
assertEquals(true,fakeCertificateRepository.findApprovalByIdAndDeletedAtIsNull(1L).get());
314316
}
315317

318+
@Test
319+
@DisplayName("disapproveGraduationUsers는 여러 GraduationUser의 제출 승인을 취소한다.")
320+
public void disapproveGraduationUsers_Success() {
321+
// given
322+
// 먼저 승인된 상태로 만듦
323+
fakeCertificateRepository.save(Certificate.of(1L, 1L, 1L, true, null, null, null));
324+
fakeThesisRepository.save(Thesis.of(1L, 1L, 1L, true, null, null, null));
325+
fakeThesisRepository.save(Thesis.of(2L, 1L, 2L, true, null, null, null));
326+
327+
List<Long> graduationUserIds = Arrays.asList(1L, 2L);
328+
GraduationUserBatchDisapproveRequest request = GraduationUserBatchDisapproveRequest.builder()
329+
.ids(graduationUserIds)
330+
.build();
331+
332+
// when
333+
GraduationUserBatchDisapproveResponse response = graduationUserAdminFacade.disapproveGraduationUsers(request);
334+
335+
// then
336+
assertEquals(2, response.disapprovedIds().size());
337+
assertEquals(false, fakeCertificateRepository.findApprovalByIdAndDeletedAtIsNull(1L).get());
338+
assertEquals(false, fakeThesisRepository.findApprovalByIdAndDeletedAtIsNull(1L).get());
339+
assertEquals(false, fakeThesisRepository.findApprovalByIdAndDeletedAtIsNull(2L).get());
340+
}
341+
342+
@Test
343+
@DisplayName("disapproveGraduationUsers는 이미 승인이 취소된 유저는 결과 목록에 포함하지 않는다.")
344+
public void disapproveGraduationUsers_AlreadyDisapproved() {
345+
// given
346+
// 이미 승인 취소 상태로 만듦
347+
fakeCertificateRepository.save(Certificate.of(1L, 1L, 1L, false, null, null, null));
348+
349+
List<Long> graduationUserIds = List.of(1L);
350+
GraduationUserBatchDisapproveRequest request = GraduationUserBatchDisapproveRequest.builder()
351+
.ids(graduationUserIds)
352+
.build();
353+
354+
// when
355+
GraduationUserBatchDisapproveResponse response = graduationUserAdminFacade.disapproveGraduationUsers(request);
356+
357+
// then
358+
assertEquals(0, response.disapprovedIds().size());
359+
assertEquals(false, fakeCertificateRepository.findApprovalByIdAndDeletedAtIsNull(1L).get());
360+
}
361+
362+
@Test
363+
@DisplayName("disapproveGraduationUsers는 제출물이 없는 유저는 무시한다.")
364+
public void disapproveGraduationUsers_NoSubmission() {
365+
// given
366+
// graduationUser3은 자격증이나 논문 ID가 없는 상태
367+
List<Long> graduationUserIds = List.of(3L);
368+
GraduationUserBatchDisapproveRequest request = GraduationUserBatchDisapproveRequest.builder()
369+
.ids(graduationUserIds)
370+
.build();
371+
372+
// when
373+
GraduationUserBatchDisapproveResponse response = graduationUserAdminFacade.disapproveGraduationUsers(request);
374+
375+
// then
376+
assertEquals(0, response.disapprovedIds().size());
377+
}
316378
}

aics-domain/src/main/java/kgu/developers/domain/certificate/application/command/CertificateCommandService.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,14 @@ public boolean approve(Long certificateId) {
6262
certificateRepository.save(certificate);
6363
return true;
6464
}
65+
66+
public boolean disapprove(Long certificateId) {
67+
Certificate certificate = certificateRepository.findByIdAndDeletedAtIsNull(certificateId)
68+
.orElseThrow(CertificateNotFoundException::new);
69+
70+
if (!certificate.isApproved()) return false;
71+
certificate.disapprove();
72+
certificateRepository.save(certificate);
73+
return true;
74+
}
6575
}

aics-domain/src/main/java/kgu/developers/domain/certificate/domain/Certificate.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,8 @@ public boolean isApproved() {
5858
public void approve() {
5959
this.approval = true;
6060
}
61+
62+
public void disapprove() {
63+
this.approval = false;
64+
}
6165
}

aics-domain/src/main/java/kgu/developers/domain/thesis/application/command/ThesisCommandService.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,14 @@ public boolean approve(Long thesisId) {
6767
thesisRepository.save(thesis);
6868
return true;
6969
}
70+
71+
public boolean disapprove(Long thesisId) {
72+
Thesis thesis = thesisRepository.findByIdAndDeletedAtIsNull(thesisId)
73+
.orElseThrow(ThesisNotFoundException::new);
74+
75+
if (!thesis.isApproved()) return false;
76+
thesis.disapprove();
77+
thesisRepository.save(thesis);
78+
return true;
79+
}
7080
}

aics-domain/src/main/java/kgu/developers/domain/thesis/domain/Thesis.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,8 @@ public boolean isApproved() {
5555
public void approve() {
5656
this.approval = true;
5757
}
58+
59+
public void disapprove() {
60+
this.approval = false;
61+
}
5862
}

0 commit comments

Comments
 (0)