Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
meltapplee committed Aug 30, 2024
2 parents 80a4b34 + 0e0db5b commit 48e8d35
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ class ApplicationPersistenceAdapter(
applicationRepository.deleteByIdAndApplicationKind(applicationId, applicationKind)
}

override fun deleteAll() =
applicationRepository.deleteAll()

override fun deleteAllByApplicationKind(applicationKind: ApplicationKind) {
applicationRepository.deleteAllByApplicationKind(applicationKind)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ interface ApplicationRepository : Repository<ApplicationJapEntity, UUID> {

fun findByUserId(userId: UUID): ApplicationJapEntity

fun deleteAll()

fun deleteAllByApplicationKind(applicationKind: ApplicationKind)

fun findByUserIdAndStatusAndApplicationKind(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ import java.util.UUID
interface DeleteApplicationPort {
fun deleteByIdAndApplicationKind(applicationId: UUID, applicationKind: ApplicationKind)

fun deleteAll()

fun deleteAllByApplicationKind(applicationKind: ApplicationKind)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package dsm.pick2024.domain.weekendmeal.service

import dsm.pick2024.domain.weekendmeal.domain.WeekendMeal
import dsm.pick2024.domain.weekendmeal.enums.Status
import dsm.pick2024.domain.weekendmeal.persistence.WeekendMealPersistenceAdapter
import dsm.pick2024.domain.weekendmeal.enums.Status.NO
import dsm.pick2024.domain.weekendmeal.enums.Status.OK
import dsm.pick2024.domain.weekendmeal.port.`in`.PrintExcelWeekendMealUseCase
import dsm.pick2024.domain.weekendmeal.port.out.QueryWeekendMealPort
import java.time.LocalDate
import org.apache.poi.ss.usermodel.BorderStyle
import org.apache.poi.ss.usermodel.CellStyle
import org.apache.poi.ss.usermodel.FillPatternType
Expand All @@ -15,68 +18,132 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import javax.servlet.http.HttpServletResponse
import kotlin.time.times
import org.apache.poi.ss.usermodel.HorizontalAlignment
import org.apache.poi.ss.usermodel.VerticalAlignment
import org.apache.poi.ss.util.CellRangeAddress

@Service
class PrintAllExcelWeekendMealService(
private val weekendMealPersistenceAdapter: WeekendMealPersistenceAdapter
private val weekendMealPort: QueryWeekendMealPort
) : PrintExcelWeekendMealUseCase {

@Transactional(readOnly = true)
override fun execute(response: HttpServletResponse) {
val month = LocalDate.now().monthValue + 1
val workbook: Workbook = XSSFWorkbook()
val sheet: Sheet =
workbook.createSheet("주말급식-신청명단").apply {
defaultColumnWidth = 30
}

// Header
val headerCellStyle: CellStyle =
workbook.createCellStyle().apply {
setBorderStyle(BorderStyle.THIN)
fillForegroundColor = IndexedColors.BLACK1.index
fillPattern = FillPatternType.SOLID_FOREGROUND
setFont(
workbook.createFont().apply {
color = IndexedColors.WHITE.index
}
)
}
// 주말급식 정보
val userList: List<WeekendMeal> = weekendMealPort.findAll().sortedWith(
compareBy({ it.grade }, { it.classNum }, { it.num })
)

val headerNames = arrayOf("이름", "학년", "", "번호")
// 반별 그룹화
val groupedByGradeClass = userList.groupBy { it.grade to it.classNum }

val headerRow: Row = sheet.createRow(0)
headerNames.forEachIndexed { i, header ->
headerRow.createCell(i).apply {
setCellValue(header)
cellStyle = headerCellStyle
val sheet: Sheet = workbook.createSheet("주말급식-신청명단").apply {
// 기본 열 너비 설정 (반별로 4개의 열)
val columnWidths = arrayOf(10, 10, 10, 15)
(0 until 16).forEach { index ->
setColumnWidth(index, columnWidths[index % 4] * 256)
}
}

// Body
val bodyCellStyle: CellStyle =
workbook.createCellStyle().apply {
setBorderStyle(BorderStyle.THIN)
// Title Style
val titleCellStyle: CellStyle = workbook.createCellStyle().apply {
setBorderStyle(BorderStyle.NONE)
fillForegroundColor = IndexedColors.WHITE.index
alignment = HorizontalAlignment.CENTER
setFont(
workbook.createFont().apply {
color = IndexedColors.BLACK.index
fontHeightInPoints = 20
}
)
}

// Header Style
val headerCellStyle: CellStyle = workbook.createCellStyle().apply {
setBorderStyle(BorderStyle.THIN)
fillForegroundColor = IndexedColors.GREY_25_PERCENT.index
fillPattern = FillPatternType.SOLID_FOREGROUND
alignment = HorizontalAlignment.CENTER
verticalAlignment = VerticalAlignment.CENTER
setFont(
workbook.createFont().apply {
color = IndexedColors.BLACK.index
bold = true
}
)
}

// Body Style
val bodyCellStyle: CellStyle = workbook.createCellStyle().apply {
setBorderStyle(BorderStyle.THIN)
alignment = HorizontalAlignment.CENTER
verticalAlignment = VerticalAlignment.CENTER
}

val titleRow: Row = sheet.createRow(0)
val titleCell = titleRow.createCell(0)
titleCell.cellStyle = titleCellStyle
titleCell.setCellValue("$month 월 주말급식 신청자 명단")
sheet.addMergedRegion(CellRangeAddress(0, 0, 0, 15))

// 데이터가 작성될 행 번호
var nowRow = 1

// 학년별로 반복
(1..3).forEach { grade ->
// Header 작성 (반별로 가로로 배치)
val headerRow: Row = sheet.createRow(nowRow)
(1..4).forEach { classNum ->
val headerNames = listOf("학번", "이름", "주말급식", "금액")
headerNames.forEachIndexed { index, header ->
val cell = headerRow.createCell((classNum - 1) * 4 + index)
cell.setCellValue(header)
cell.cellStyle = headerCellStyle
}
}

val userList: List<WeekendMeal> = weekendMealPersistenceAdapter.findByStatus(Status.OK).sortedWith(
compareBy({ it.grade }, { it.classNum }, { it.num })
)
// 학년 별 행 이동
nowRow++

// 최대 학생 수(학년 별 한 반의)
val maxClassSize = (1..4).map { classNum ->
groupedByGradeClass[grade to classNum]?.size ?: 0
}.maxOrNull() ?: 0

// 반별 데이터 배치
(0 until maxClassSize).forEach { index ->
val row: Row = sheet.createRow(nowRow + index)

(1..4).forEach { classNum ->
val users = groupedByGradeClass[grade to classNum] ?: emptyList()

if (index < users.size) {
val user = users[index]
row.createCell((classNum - 1) * 4)
.setCellValue(user.grade * 1000 + user.classNum * 100 + user.num.toDouble())
row.createCell((classNum - 1) * 4 + 1).setCellValue(user.userName)
row.createCell((classNum - 1) * 4 + 2).setCellValue(statusChange(user.status)?.toString() ?: "")
row.createCell((classNum - 1) * 4 + 3).setCellValue("-")

userList.forEachIndexed { index, user ->
val bodyRow: Row = sheet.createRow(index + 1)
bodyRow.createCell(0).setCellValue(user.userName)
bodyRow.createCell(1).setCellValue(user.grade.toDouble())
bodyRow.createCell(2).setCellValue(user.classNum.toDouble())
bodyRow.createCell(3).setCellValue(user.num.toDouble())
bodyRow.forEach { cell ->
cell.cellStyle = bodyCellStyle
row.forEach { cell ->
cell.cellStyle = bodyCellStyle
}
}
}
}

// 다음 학년으로 넘어가기 전에 행 띄우기
nowRow += maxClassSize + 1
}

// File
val fileName = "weekendMeal_apply.spreadsheet_download"
response.contentType = "application/weekendMeal_apply.spreadsheet.sheet"
response.setHeader("Content-Disposition", "attachment;filename=$fileName.xlsx")
// 파일 생성
val fileName = "weekendMeal.xlsx"
response.contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
response.setHeader("Content-Disposition", "attachment;filename=$fileName")

val servletOutputStream = response.outputStream

workbook.write(servletOutputStream)
Expand All @@ -91,4 +158,11 @@ class PrintAllExcelWeekendMealService(
borderTop = style
borderBottom = style
}

private fun statusChange(status: Status): Int? {
return when (status) {
OK -> 1
NO -> null
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package dsm.pick2024.infrastructure.schedule

import dsm.pick2024.domain.afterschool.port.out.DeleteAfterSchoolStudentPort
import dsm.pick2024.domain.application.enums.ApplicationKind
import dsm.pick2024.domain.application.port.out.DeleteApplicationPort
import dsm.pick2024.domain.attendance.port.`in`.ResetAttendanceUseCase
import dsm.pick2024.domain.classroom.port.out.DeleteClassRoomPort
Expand All @@ -24,8 +23,7 @@ class ScheduleService(
@Scheduled(cron = "0 30 20 * * ?", zone = "Asia/Seoul")
fun deleteTable() {
deleteClassRoomPort.deleteAll()
deleteApplicationPort.deleteAllByApplicationKind(ApplicationKind.EARLY_RETURN)
deleteApplicationPort.deleteAllByApplicationKind(ApplicationKind.APPLICATION)
deleteApplicationPort.deleteAll()
deleteAfterSchoolStudentPort.deleteAll()
}

Expand Down

0 comments on commit 48e8d35

Please sign in to comment.