Skip to content

Commit

Permalink
Merge pull request #129 from Bamdoliro/feat/#119
Browse files Browse the repository at this point in the history
[새기능] 특례입학 원서 폼 및 접수증 만들기
  • Loading branch information
jyj1289 authored Sep 8, 2024
2 parents d0d5dce + 1c97996 commit ee2ea32
Show file tree
Hide file tree
Showing 13 changed files with 926 additions and 3 deletions.
21 changes: 21 additions & 0 deletions src/docs/asciidoc/form.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,27 @@ include::{snippets}/form-controller-test/수험표를_발급받을_때_원서를
===== 불합격한 경우
include::{snippets}/form-controller-test/수험표를_발급받을_때_불합격자라면_에러가_발생한다/http-response.adoc[]

=== 접수증 발급
원서를 최종 제출한 유저는 접수증을 발급받을 수 있습니다.

==== 요청 형식

===== Request Header
include::{snippets}/form-controller-test/접수증을_발급받는다/request-headers.adoc[]

==== 요청
include::{snippets}/form-controller-test/접수증을_발급받는다/http-request.adoc[]

==== 응답

===== 정상 응답
include::{snippets}/form-controller-test/접수증을_발급받는다/http-response.adoc[]

===== 원서를 접수하지 않은 경우
include::{snippets}/form-controller-test/접수증을_발급받을_때_원서를_접수하지_않았다면_에러가_발생한다/http-response.adoc[]

===== 최종 제출이 아닌 경우
include::{snippets}/form-controller-test/접수증을_발급받을_때_원서상태가_최종제출이_아니라면_에러가_발생한다/http-response.adoc[]

=== 2차 전형 점수 양식 다운로드
어드민은 2차 전형 점수 양식을 다운로드 받을 수 있습니다.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,15 @@ private List<String> getRequiredTemplates(Form form) {
Templates.DOCUMENT,
Templates.WRITTEN_OATH
);
} else if (form.getType().isSpecialAdmission()) {
return List.of(
Templates.FORM,
Templates.GRADE_TABLE,
Templates.DOCUMENT,
Templates.WRITTEN_OATH,
Templates.SPECIAL_ADMISSION,
Templates.CONFIRMATION
);
}

return List.of(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.bamdoliro.maru.application.form;

import com.bamdoliro.maru.domain.form.domain.Form;
import com.bamdoliro.maru.domain.form.exception.InvalidFormStatusException;
import com.bamdoliro.maru.domain.form.service.FormFacade;
import com.bamdoliro.maru.domain.user.domain.User;
import com.bamdoliro.maru.infrastructure.pdf.GeneratePdfService;
import com.bamdoliro.maru.infrastructure.s3.FileService;
import com.bamdoliro.maru.infrastructure.s3.constants.FolderConstant;
import com.bamdoliro.maru.infrastructure.thymeleaf.ProcessTemplateService;
import com.bamdoliro.maru.infrastructure.thymeleaf.Templates;
import com.bamdoliro.maru.shared.annotation.UseCase;
import com.bamdoliro.maru.shared.constants.Schedule;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.ByteArrayResource;

import java.io.ByteArrayOutputStream;
import java.util.Map;

import static com.bamdoliro.maru.shared.constants.Schedule.ANNOUNCEMENT_OF_FIRST_PASS;

@RequiredArgsConstructor
@UseCase
public class GenerateProofOfApplicationUseCase {

private final FormFacade formFacade;
private final ProcessTemplateService processTemplateService;
private final GeneratePdfService generatePdfService;
private final FileService fileService;

public ByteArrayResource execute(User user) {
Form form = formFacade.getForm(user);
validateFormStatus(form);

Map<String, Object> formMap = Map.of(
"form", form,
"year", Schedule.getAdmissionYear(),
"announcement_of_first_pass", Schedule.toLocaleString(ANNOUNCEMENT_OF_FIRST_PASS),
"identificationPictureUri", fileService.getPresignedUrl(FolderConstant.IDENTIFICATION_PICTURE, user.getUuid().toString()).getDownloadUrl()
);
String html = processTemplateService.execute(Templates.PROOF_OF_APPLICATION, formMap);
ByteArrayOutputStream outputStream = generatePdfService.execute(html);

return new ByteArrayResource(outputStream.toByteArray());
}

private void validateFormStatus(Form form) {
if (!form.isFinalSubmitted() && !form.isApproved() && !form.isReceived()) {
throw new InvalidFormStatusException();
}
}
}
8 changes: 5 additions & 3 deletions src/main/java/com/bamdoliro/maru/domain/form/domain/Form.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,11 @@ public boolean isRejected() {
return status.equals(FormStatus.REJECTED);
}

public boolean isSubmitted() {
return status.equals(FormStatus.SUBMITTED);
}
public boolean isSubmitted() { return status.equals(FormStatus.SUBMITTED); }

public boolean isFinalSubmitted() { return status.equals(FormStatus.FINAL_SUBMITTED); }

public boolean isApproved() { return status.equals(FormStatus.APPROVED); }

public boolean isReceived() {
return isFirstPassed() != null || status.equals(FormStatus.RECEIVED);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ public class Templates {
public static final String RECOMMENDATION = "recommendation";
public static final String NO_SMOKING = "no-smoking";
public static final String ADMISSION_TICKET = "admission-ticket";
public static final String PROOF_OF_APPLICATION = "proof-of-application";
public static final String GRADE_TABLE = "grade-table";
public static final String WRITTEN_OATH = "written-oath";
public static final String SPECIAL_ADMISSION = "special-admission";
public static final String CONFIRMATION = "confirmation";
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class FormController {
private final QueryFirstFormResultUseCase queryFirstFormResultUseCase;
private final QueryFinalFormResultUseCase queryFinalFormResultUseCase;
private final GenerateAdmissionTicketUseCase generateAdmissionTicketUseCase;
private final GenerateProofOfApplicationUseCase generateProofOfApplicationUseCase;
private final DownloadSecondRoundScoreFormatUseCase downloadSecondRoundScoreFormatUseCase;
private final UpdateSecondRoundScoreUseCase updateSecondRoundScoreUseCase;
private final ExportFinalPassedFormUseCase exportFinalPassedFormUseCase;
Expand Down Expand Up @@ -223,6 +224,15 @@ public ResponseEntity<Resource> generateAdmissionTicket(
.body(generateAdmissionTicketUseCase.execute(user));
}

@GetMapping("/proof-of-application")
public ResponseEntity<Resource> generateProfOfApplication(
@AuthenticationPrincipal(authority = Authority.USER) User user
) {
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_PDF)
.body(generateProofOfApplicationUseCase.execute(user));
}

@GetMapping("/second-round/format")
public ResponseEntity<Resource> downloadSecondRoundScoreFormatUseCase(
@AuthenticationPrincipal(authority = Authority.ADMIN) User user
Expand Down
124 changes: 124 additions & 0 deletions src/main/resources/templates/confirmation.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" lang="ko">
<head>
<meta charset="UTF-8"/>
<style>
@page {
size: A4;
margin: 70px;
}

* {
font-family: SUIT, sans-serif;
margin: 0;
padding: 0;
box-sizing: border-box;
}

table {
border: none;
border-collapse: collapse;
width: 100%;
font-size: 14px;
text-align: center;
line-height: normal;
}
tr {
vertical-align: middle;
}

td {
padding: 8px 0;
}

th {
background-color: #ECF2FA;
font-weight: 500;
padding: 8px 0;
}
.format {
font-size: 13px;
font-weight: bold;
}
.ba {
border: #000000 1px solid;
}

.title {
font-weight: bold;
font-size: 36px;
line-height: 48px;
text-align: center;
letter-spacing: 40px;
margin-left: 74px;
}
.subtitle {
font-size: 22px;
line-height: 2;
}
.left {
text-align: left;
}

.right {
text-align: right;
}

.center {
text-align: center;
}

.text-box {
padding: 15px 10px;
vertical-align: text-top;
}

.middle {
font-size: 18px;
line-height: 160%;
}

.indent {
text-indent: 18px;
font-size: 21px;
word-break: keep-all;
line-height: 2;
}
.padding {
padding: 16px;
}
</style>
<title>원서</title>
</head>
<body>
<table>
<p class="format">[서식6]</p>
<div style="height: 14px"></div>
<td class="ba text-box middle left padding" colspan="4">
<div style="height: 72px"></div>
<div class="title">확인서</div>
<div style="height: 64px"></div>
<p class="subtitle center">성&nbsp;&nbsp;&nbsp;&nbsp;명 :</p>
<p class="subtitle center" style="margin-left: 164px">생년월일 :&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;년 &nbsp;&nbsp;&nbsp;&nbsp;월 &nbsp;&nbsp;&nbsp;&nbsp;일</p>
<div style="height: 44px;"></div>
<p class="indent">○ 주&nbsp;&nbsp;&nbsp;소 : </p>
<p class="indent">○ 연락처 : </p>
<p class="indent">○ 외국 학교명 : </p>
<div style="height: 16px;"></div>
<p class="indent" style="margin-left: 40px">(시트명 :&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;, 행 번호 :&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)</p>
<div style="height: 32px;"></div>
<p class="indent">위 학생의 특례 신입학 학적 서류는 외국 학교의 재적학교장이 발급한 학적 서류임을 확인하며,
만약 위·변조 서류로 확인될 경우에는 입학 취소 등 모든 행정처분에 따를 것을 확인합니다.</p>
<div style="height: 32px;"></div>
<p class="middle center" th:text="${#dates.format(#dates.createNow(),'YYYY년 MM월 dd일')}">년&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;월&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;일</p>
<div style="height: 42px;"></div>
<div class="indent"><span style="margin-right: 80px">확생과의 관계(보호자) :</span>
<span style="margin-right: 80px">성명 :</span>
<span>서명 또는 (인)</span>
</div>
<div style="height: 42px"></div>
</td>
</tr>
</table>
</body>
</html>
Loading

0 comments on commit ee2ea32

Please sign in to comment.