Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
package hs.kr.entrydsm.domain.application.interfaces

interface ApplicationContract :
QueryAllFirstRoundPassedApplicationContract
import hs.kr.entrydsm.domain.application.aggregates.Application
import java.util.UUID

interface ApplicationContract : QueryAllFirstRoundPassedApplicationContract {
fun getApplicationByUserId(userId: UUID): Application?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package hs.kr.entrydsm.domain.application.interfaces

import hs.kr.entrydsm.domain.application.aggregates.Application

interface ApplicationPdfGeneratorContract {
fun generate(application: Application, score: Any): ByteArray
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package hs.kr.entrydsm.domain.application.interfaces

import hs.kr.entrydsm.domain.application.aggregates.Application

interface IntroductionPdfGeneratorContract {
fun generate(applications: List<Application>): ByteArray
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,12 @@ interface QuerySchoolContract {
* @return 학교 정보
*/
fun querySchoolBySchoolCode(schoolCode: String): School?
}

/**
* 여러 학교 코드로 학교 목록을 조회합니다.
*
* @param schoolCodes 학교 코드 목록
* @return 학교 정보 목록
*/
fun querySchoolsByCodes(schoolCodes: List<String>): List<School>
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,12 @@ data class Status(
val isFirstRoundPass: Boolean = false,
val isSecondRoundPass: Boolean = false,
val receiptCode: Long,
)
) {
/**
* 원서가 제출되었는지 여부를 확인합니다.
* SUBMITTED 이상의 상태일 때 제출된 것으로 간주합니다.
*/
val isSubmitted: Boolean
get() = applicationStatus != ApplicationStatus.NOT_APPLIED &&
applicationStatus != ApplicationStatus.WRITING
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,22 @@ interface ApplicationQueryStatusContract {
*/
fun queryStatusByReceiptCode(receiptCode: Long): Status?

/**
* 접수번호로 원서 상태를 조회합니다. (getStatusByReceiptCode의 별칭)
*
* @param receiptCode 조회할 접수번호
* @return 조회된 상태 정보, 존재하지 않는 경우 null
*/
fun getStatusByReceiptCode(receiptCode: Long): Status? = queryStatusByReceiptCode(receiptCode)

/**
* 여러 접수번호로 원서 상태 목록을 조회합니다.
*
* @param receiptCodes 조회할 접수번호 목록
* @return 조회된 상태 정보 목록
*/
fun queryStatusesByReceiptCodes(receiptCodes: List<Long>): List<Status>

/**
* 캐시에서 접수번호로 원서 상태를 조회합니다.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,12 @@ interface ApplicationQueryUserContract {
* @return 조회된 사용자 정보
*/
fun queryUserByUserId(userId: UUID): User

/**
* 여러 사용자 ID로 사용자 정보 목록을 조회합니다.
*
* @param userIds 조회할 사용자들의 고유 식별자 목록
* @return 조회된 사용자 정보 목록
*/
fun queryUsersByIds(userIds: List<UUID>): List<User>
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,42 @@ import hs.kr.entrydsm.application.domain.admin.presentation.dto.request.CreateEd
import hs.kr.entrydsm.application.domain.admin.presentation.dto.response.CreateApplicationTypeResponse
import hs.kr.entrydsm.application.domain.admin.presentation.dto.response.CreateEducationalStatusResponse
import hs.kr.entrydsm.application.domain.admin.usecase.AdminUseCase
import hs.kr.entrydsm.application.domain.pdf.usecase.GetIntroductionPdfUseCase
import hs.kr.entrydsm.application.global.document.admin.AdminApiDocument
import org.springframework.http.HttpHeaders
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping
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.RestController
import java.nio.charset.StandardCharsets
import jakarta.servlet.http.HttpServletResponse

@RestController
@RequestMapping("/api/v1/admin")
class AdminController(
private val adminUseCase: AdminUseCase,
private val getIntroductionPdfUseCase: GetIntroductionPdfUseCase
) : AdminApiDocument {

@GetMapping("/pdf/introduction", produces = [MediaType.APPLICATION_PDF_VALUE])
override suspend fun getIntroductionPdf(response: HttpServletResponse): ResponseEntity<ByteArray> {
val pdfBytes = getIntroductionPdfUseCase.execute()

response.setHeader("Content-Disposition", "attachment; filename=\"${encodeFileName()}.pdf\"")

return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_PDF_VALUE)
.body(pdfBytes)
}

private fun encodeFileName(): String {
val fileName = "introduction"
return String(fileName.toByteArray(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)
}

@PostMapping("/application-types")
override fun createApplicationType(
@RequestBody request: CreateApplicationTypeRequest,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import hs.kr.entrydsm.domain.application.interfaces.ApplicationContract
import hs.kr.entrydsm.domain.status.interfaces.StatusContract
import kotlinx.coroutines.runBlocking
import org.springframework.stereotype.Component
import java.util.UUID

/**
* Application 도메인의 퍼시스턴스 어댑터입니다.
Expand All @@ -20,6 +21,19 @@ class ApplicationPersistenceAdapter(
private val applicationMapper: ApplicationMapper,
private val statusContract: StatusContract,
) : ApplicationContract {

/**
* 사용자 ID로 원서 정보를 조회합니다.
*
* @param userId 사용자 ID
* @return 해당 사용자의 원서 정보, 없으면 null
*/
override fun getApplicationByUserId(userId: UUID): Application? {
return applicationJpaRepository.findAllByUserId(userId)
.firstOrNull()
?.let { applicationMapper.toModel(it) }
}

/**
* 1차 전형 합격 Application을 모두 조회합니다.
*
Expand All @@ -41,4 +55,14 @@ class ApplicationPersistenceAdapter(
}
}
}

/**
* 제출된 모든 원서를 조회합니다.
*
* @return 제출된 모든 원서 목록
*/
fun querySubmittedApplications(): List<Application> {
return applicationJpaRepository.findAll()
.map { applicationMapper.toModel(it) }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package hs.kr.entrydsm.application.domain.excel.presentation

import hs.kr.entrydsm.application.domain.excel.usecase.PrintAdmissionTicketUseCase
import hs.kr.entrydsm.application.domain.excel.usecase.PrintApplicantCodesUseCase
import hs.kr.entrydsm.application.domain.excel.usecase.PrintApplicationCheckListUseCase
import hs.kr.entrydsm.application.domain.excel.usecase.PrintApplicationInfoUseCase
import hs.kr.entrydsm.application.global.document.excel.ExcelApiDocument
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import jakarta.servlet.http.HttpServletResponse

@RestController
@RequestMapping("/admin/excel")
class WebExcelAdapter(
private val printAdmissionTicketUseCase: PrintAdmissionTicketUseCase,
private val printApplicantCodesUseCase: PrintApplicantCodesUseCase,
private val printApplicationInfoUseCase: PrintApplicationInfoUseCase,
private val printApplicationCheckListUseCase: PrintApplicationCheckListUseCase
) : ExcelApiDocument {

@GetMapping("/admission-ticket")
override fun printAdmissionTicket(response: HttpServletResponse) {
printAdmissionTicketUseCase.execute(response)
}

@GetMapping("/applicant-codes")
override suspend fun printApplicantCodes(response: HttpServletResponse) {
printApplicantCodesUseCase.execute(response)
}

@GetMapping("/application-info")
override fun printApplicationInfo(response: HttpServletResponse) {
printApplicationInfoUseCase.execute(response)
}

@GetMapping("/check-list")
override fun printApplicationCheckList(response: HttpServletResponse) {
printApplicationCheckListUseCase.execute(response)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package hs.kr.entrydsm.application.domain.excel.usecase

import hs.kr.entrydsm.application.domain.application.domain.ApplicationPersistenceAdapter
import hs.kr.entrydsm.application.global.excel.generator.PrintAdmissionTicketGenerator
import hs.kr.entrydsm.domain.school.interfaces.SchoolContract
import hs.kr.entrydsm.domain.status.interfaces.ApplicationQueryStatusContract
import hs.kr.entrydsm.domain.user.interfaces.ApplicationQueryUserContract
import org.springframework.stereotype.Service
import jakarta.servlet.http.HttpServletResponse

@Service
class PrintAdmissionTicketUseCase(
private val printAdmissionTicketGenerator: PrintAdmissionTicketGenerator,
private val applicationPersistenceAdapter: ApplicationPersistenceAdapter,
private val schoolContract: SchoolContract,
private val applicationQueryStatusContract: ApplicationQueryStatusContract,
private val applicationQueryUserContract: ApplicationQueryUserContract
) {
fun execute(httpServletResponse: HttpServletResponse) {
val applications = applicationPersistenceAdapter.querySubmittedApplications()
val receiptCodes = applications.map { it.receiptCode }
val userIds = applications.map { it.userId }
val schoolCodes = applications.mapNotNull { it.schoolCode }.distinct()

val users = applicationQueryUserContract.queryUsersByIds(userIds)
val schools = schoolContract.querySchoolsByCodes(schoolCodes)
val statuses = applicationQueryStatusContract.queryStatusesByReceiptCodes(receiptCodes)

printAdmissionTicketGenerator.execute(
response = httpServletResponse,
applications = applications,
users = users,
schools = schools,
statuses = statuses
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package hs.kr.entrydsm.application.domain.excel.usecase

import hs.kr.entrydsm.application.global.excel.generator.PrintApplicantCodesGenerator
import hs.kr.entrydsm.domain.application.interfaces.QueryAllFirstRoundPassedApplicationContract
import hs.kr.entrydsm.domain.status.interfaces.ApplicationQueryStatusContract
import org.springframework.stereotype.Service
import jakarta.servlet.http.HttpServletResponse

@Service
class PrintApplicantCodesUseCase(
private val printApplicantCodesGenerator: PrintApplicantCodesGenerator,
private val queryAllFirstRoundPassedApplicationContract: QueryAllFirstRoundPassedApplicationContract,
private val applicationQueryStatusContract: ApplicationQueryStatusContract
) {
suspend fun execute(httpServletResponse: HttpServletResponse) {
val applications = queryAllFirstRoundPassedApplicationContract.queryAllFirstRoundPassedApplication()
val receiptCodes = applications.map { it.receiptCode }
val statuses = applicationQueryStatusContract.queryStatusesByReceiptCodes(receiptCodes)

printApplicantCodesGenerator.execute(httpServletResponse, applications, statuses)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package hs.kr.entrydsm.application.domain.excel.usecase

import hs.kr.entrydsm.application.domain.application.domain.ApplicationPersistenceAdapter
import hs.kr.entrydsm.application.global.excel.generator.PrintApplicationCheckListGenerator
import hs.kr.entrydsm.domain.school.interfaces.SchoolContract
import hs.kr.entrydsm.domain.status.interfaces.ApplicationQueryStatusContract
import hs.kr.entrydsm.domain.user.interfaces.ApplicationQueryUserContract
import org.springframework.stereotype.Service
import jakarta.servlet.http.HttpServletResponse

@Service
class PrintApplicationCheckListUseCase(
private val printApplicationCheckListGenerator: PrintApplicationCheckListGenerator,
private val applicationPersistenceAdapter: ApplicationPersistenceAdapter,
private val schoolContract: SchoolContract,
private val applicationQueryStatusContract: ApplicationQueryStatusContract,
private val applicationQueryUserContract: ApplicationQueryUserContract
) {
fun execute(httpServletResponse: HttpServletResponse) {
val applications = applicationPersistenceAdapter.querySubmittedApplications()
val receiptCodes = applications.map { it.receiptCode }
val userIds = applications.map { it.userId }
val schoolCodes = applications.mapNotNull { it.schoolCode }.distinct()

val users = applicationQueryUserContract.queryUsersByIds(userIds)
val schools = schoolContract.querySchoolsByCodes(schoolCodes)
val statuses = applicationQueryStatusContract.queryStatusesByReceiptCodes(receiptCodes)

printApplicationCheckListGenerator.printApplicationCheckList(
applications = applications,
users = users,
schools = schools,
statuses = statuses,
httpServletResponse = httpServletResponse
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package hs.kr.entrydsm.application.domain.excel.usecase

import hs.kr.entrydsm.application.domain.application.domain.ApplicationPersistenceAdapter
import hs.kr.entrydsm.application.global.excel.generator.PrintApplicationInfoGenerator
import hs.kr.entrydsm.domain.school.interfaces.SchoolContract
import hs.kr.entrydsm.domain.status.interfaces.ApplicationQueryStatusContract
import hs.kr.entrydsm.domain.user.interfaces.ApplicationQueryUserContract
import org.springframework.stereotype.Service
import jakarta.servlet.http.HttpServletResponse

@Service
class PrintApplicationInfoUseCase(
private val printApplicationInfoGenerator: PrintApplicationInfoGenerator,
private val applicationPersistenceAdapter: ApplicationPersistenceAdapter,
private val schoolContract: SchoolContract,
private val applicationQueryStatusContract: ApplicationQueryStatusContract,
private val applicationQueryUserContract: ApplicationQueryUserContract
) {
fun execute(httpServletResponse: HttpServletResponse) {
val applications = applicationPersistenceAdapter.querySubmittedApplications()
val receiptCodes = applications.map { it.receiptCode }
val userIds = applications.map { it.userId }
val schoolCodes = applications.mapNotNull { it.schoolCode }.distinct()

val users = applicationQueryUserContract.queryUsersByIds(userIds)
val schools = schoolContract.querySchoolsByCodes(schoolCodes)
val statuses = applicationQueryStatusContract.queryStatusesByReceiptCodes(receiptCodes)

printApplicationInfoGenerator.execute(
httpServletResponse = httpServletResponse,
applications = applications,
users = users,
schools = schools,
statuses = statuses
)
}
}
Loading