Skip to content

Commit

Permalink
refactor: (#286) Holiday Aggregate 리팩토링
Browse files Browse the repository at this point in the history
  • Loading branch information
softpeanut committed Jan 9, 2023
1 parent 2734152 commit a2fa3bb
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package team.comit.simtong.domain.holiday.usecase

import team.comit.simtong.domain.holiday.exception.HolidayExceptions
import team.comit.simtong.domain.holiday.model.Holiday
import team.comit.simtong.domain.holiday.model.HolidayStatus
import team.comit.simtong.domain.holiday.model.Holiday.Companion.checkNotExceededAnnualLimit
import team.comit.simtong.domain.holiday.model.HolidayType
import team.comit.simtong.domain.holiday.spi.CommandHolidayPort
import team.comit.simtong.domain.holiday.spi.HolidayQueryUserPort
Expand All @@ -17,8 +17,9 @@ import java.time.LocalDate
* 연차 지정을 담당하는 AppointAnnualUseCase
*
* @author Chokyunghyeon
* @author kimbeomjin
* @date 2022/12/17
* @version 1.0.0
* @version 1.2.5
**/
@UseCase
class AppointAnnualUseCase(
Expand All @@ -36,32 +37,20 @@ class AppointAnnualUseCase(
val user = queryUserPort.queryUserById(securityPort.getCurrentUserId())
?: throw UserExceptions.NotFound()

queryHolidayPort.queryHolidayByDateAndUserId(date, user.id)?.run {
when (type) {
HolidayType.ANNUAL ->
throw HolidayExceptions.AlreadyExists("해당 날짜는 이미 연차입니다.")

HolidayType.HOLIDAY -> if (status == HolidayStatus.COMPLETED) {
throw HolidayExceptions.AlreadyExists("해당 날짜는 이미 휴무일입니다.")
}
}
if (queryHolidayPort.existsHolidayByDateAndUserIdAndType(date, user.id, HolidayType.ANNUAL)) {
throw HolidayExceptions.AlreadyExists("해당 날짜는 이미 연차입니다.")
}

val countAnnual = queryHolidayPort.countHolidayByYearAndUserIdAndType(date.year, user.id, HolidayType.ANNUAL)
val annualCount = queryHolidayPort.countHolidayByYearAndUserIdAndType(date.year, user.id, HolidayType.ANNUAL)

if (countAnnual >= Holiday.ANNUAL_LEAVE_LIMIT) {
throw HolidayExceptions.AnnualLeaveLimitExcess()
}
checkNotExceededAnnualLimit(annualCount)

commandHolidayPort.save(
Holiday(
Holiday.createAnnual(
date = date,
userId = user.id,
spotId = user.spotId,
type = HolidayType.ANNUAL,
status = HolidayStatus.COMPLETED
spotId = user.spotId
)
)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package team.comit.simtong.domain.holiday.usecase

import team.comit.simtong.domain.holiday.exception.HolidayExceptions
import team.comit.simtong.domain.holiday.model.Holiday
import team.comit.simtong.domain.holiday.model.HolidayStatus
import team.comit.simtong.domain.holiday.model.Holiday.Companion.checkNotExceededHolidayLimit
import team.comit.simtong.domain.holiday.model.HolidayType
import team.comit.simtong.domain.holiday.spi.CommandHolidayPort
import team.comit.simtong.domain.holiday.spi.HolidayQueryUserPort
Expand All @@ -18,8 +18,9 @@ import java.time.LocalDate
* 휴무일 지정을 담당하는 AppointHolidayUseCase
*
* @author Chokyunghyeon
* @author kimbeomjin
* @date 2022/12/03
* @version 1.0.0
* @version 1.2.5
**/
@UseCase
class AppointHolidayUseCase(
Expand All @@ -34,8 +35,9 @@ class AppointHolidayUseCase(
val user = queryUserPort.queryUserById(securityPort.getCurrentUserId())
?: throw UserExceptions.NotFound()

val holidayPeriod = queryHolidayPeriodPort.queryHolidayPeriodByYearAndMonthAndSpotId(date.year, date.monthValue, user.spotId)
?: throw HolidayExceptions.NotFound("휴무표 작성 기간이 등록되지 않았습니다.")
val holidayPeriod = queryHolidayPeriodPort.queryHolidayPeriodByYearAndMonthAndSpotId(
date.year, date.monthValue, user.spotId
) ?: throw HolidayExceptions.NotFound("휴무표 작성 기간이 등록되지 않았습니다.")

val today = LocalDate.now()

Expand All @@ -47,21 +49,16 @@ class AppointHolidayUseCase(
throw HolidayExceptions.AlreadyExists("해당 날짜는 이미 휴무일입니다.")
}

val countHoliday = queryHolidayPort.countHolidayByWeekAndUserIdAndType(date, user.id, HolidayType.HOLIDAY)
val holidayCount = queryHolidayPort.countHolidayByWeekAndUserIdAndType(date, user.id, HolidayType.HOLIDAY)

if (countHoliday >= Holiday.WEEK_HOLIDAY_LIMIT) {
throw HolidayExceptions.WeekHolidayLimitExcess()
}
checkNotExceededHolidayLimit(holidayCount)

commandHolidayPort.save(
Holiday(
Holiday.createHoliday(
date = date,
userId = user.id,
type = HolidayType.HOLIDAY,
spotId = user.spotId,
status = HolidayStatus.WRITTEN
spotId = user.spotId
)
)
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package team.comit.simtong.domain.holiday.usecase

import team.comit.simtong.domain.holiday.exception.HolidayExceptions
import team.comit.simtong.domain.holiday.model.HolidayStatus
import team.comit.simtong.domain.holiday.model.HolidayType
import team.comit.simtong.domain.holiday.spi.CommandHolidayPort
import team.comit.simtong.domain.holiday.spi.HolidaySecurityPort
Expand All @@ -14,8 +13,9 @@ import java.time.LocalDate
* 휴무일 또는 연차 취소 요청을 담당하는 CancelHolidayUseCase
*
* @author Chokyunghyeon
* @author kimbeomjin
* @date 2022/12/04
* @version 1.0.0
* @version 1.2.5
**/
@UseCase
class CancelHolidayUseCase(
Expand All @@ -31,8 +31,8 @@ class CancelHolidayUseCase(
?: throw HolidayExceptions.NotFound()

when (holiday.type) {
HolidayType.HOLIDAY -> if (holiday.status == HolidayStatus.COMPLETED) {
throw HolidayExceptions.CannotChange("결정된 휴무일는 취소할 수 없습니다.")
HolidayType.HOLIDAY -> if (holiday.isCompleted()) {
throw HolidayExceptions.CannotChange("결정된 휴무일은 취소할 수 없습니다.")
}

HolidayType.ANNUAL -> if (holiday.date <= LocalDate.now()) {
Expand All @@ -42,5 +42,4 @@ class CancelHolidayUseCase(

commandHolidayPort.delete(holiday)
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package team.comit.simtong.domain.holiday.usecase

import team.comit.simtong.domain.holiday.exception.HolidayExceptions
import team.comit.simtong.domain.holiday.model.Holiday
import team.comit.simtong.domain.holiday.model.HolidayType
import team.comit.simtong.domain.holiday.spi.CommandHolidayPort
import team.comit.simtong.domain.holiday.spi.HolidayQueryUserPort
Expand All @@ -19,7 +18,7 @@ import java.util.UUID
*
* @author kimbeomjin
* @date 2022/12/23
* @version 1.0.0
* @version 1.2.5
**/
@UseCase
class ChangeEmployeeHolidayUseCase(
Expand All @@ -36,18 +35,14 @@ class ChangeEmployeeHolidayUseCase(
val holiday = queryHolidayPort.queryHolidayByDateAndUserId(beforeDate, userId)
?: throw HolidayExceptions.NotFound()

if (admin.spotId != holiday.spotId) {
if (!holiday.isSameSpot(admin.spotId)) {
throw HolidayExceptions.CannotChange("같은 지점 직원의 휴무일만 변경할 수 있습니다.")
}

val countHoliday = queryHolidayPort.countHolidayByWeekAndUserIdAndType(afterDate, userId, HolidayType.HOLIDAY)

if (countHoliday >= Holiday.WEEK_HOLIDAY_LIMIT) {
throw HolidayExceptions.WeekHolidayLimitExcess()
}
val holidayCount = queryHolidayPort.countHolidayByWeekAndUserIdAndType(afterDate, userId, HolidayType.HOLIDAY)

commandHolidayPort.save(
holiday.copy(date = afterDate)
holiday.change(holidayCount, afterDate)
)
commandHolidayPort.delete(holiday)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package team.comit.simtong.domain.holiday.usecase

import team.comit.simtong.domain.holiday.dto.QueryEmployeeHolidayResponse
import team.comit.simtong.domain.holiday.model.HolidayQueryType
import team.comit.simtong.domain.holiday.model.HolidayType
import team.comit.simtong.domain.holiday.spi.HolidayQueryUserPort
import team.comit.simtong.domain.holiday.spi.HolidaySecurityPort
import team.comit.simtong.domain.holiday.spi.QueryHolidayPort
Expand All @@ -20,7 +19,7 @@ import java.util.UUID
*
* @author kimbeomjin
* @date 2022/12/22
* @version 1.0.0
* @version 1.2.5
**/
@ReadOnlyUseCase
class QueryEmployeeHolidayUseCase(
Expand All @@ -33,28 +32,13 @@ class QueryEmployeeHolidayUseCase(
val currentUserId = securityPort.getCurrentUserId()
val user = queryUserPort.queryUserById(currentUserId) ?: throw UserExceptions.NotFound()

val holidays = when (HolidayQueryType.valueOf(typeName)) {
HolidayQueryType.HOLIDAY -> queryHolidayPort.queryHolidaysByYearAndMonthAndTeamId(
year = year, month = month,
type = HolidayType.HOLIDAY,
spotId = user.spotId,
teamId = teamId
)

HolidayQueryType.ANNUAL -> queryHolidayPort.queryHolidaysByYearAndMonthAndTeamId(
year = year, month = month,
type = HolidayType.ANNUAL,
spotId = user.spotId,
teamId = teamId
)

HolidayQueryType.ALL -> queryHolidayPort.queryHolidaysByYearAndMonthAndTeamId(
year = year, month = month,
type = null,
spotId = user.spotId,
teamId = teamId
)
}
val holidays = queryHolidayPort.queryHolidaysByYearAndMonthAndTeamId(
year = year,
month = month,
type = HolidayQueryType.valueOf(typeName).toHolidayType(),
spotId = user.spotId,
teamId = teamId
)

val response = holidays.map {
QueryEmployeeHolidayResponse.Holiday(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ class QueryIndividualHolidayUseCase(
private val securityPort: HolidaySecurityPort
) {

fun execute(
request: QueryIndividualRequest
) : QueryIndividualHolidaysResponse {
fun execute(request: QueryIndividualRequest) : QueryIndividualHolidaysResponse {
val currentUserId = securityPort.getCurrentUserId()

val holidays = queryHolidayPort.queryHolidaysByPeriodAndUserIdAndStatus(
Expand All @@ -43,5 +41,4 @@ class QueryIndividualHolidayUseCase(

return QueryIndividualHolidaysResponse(response)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ import team.comit.simtong.global.annotation.ReadOnlyUseCase
* 남은 연차 개수 확인을 담당하는 QueryRemainAnnualUseCase
*
* @author Chokyunghyeon
* @author kimbeomjin
* @date 2022/12/20
* @version 1.0.0
* @version 1.2.5
**/
@ReadOnlyUseCase
class QueryRemainAnnualUseCase(
Expand All @@ -23,9 +24,8 @@ class QueryRemainAnnualUseCase(
fun execute(year: Int): Long {
val currentUserId = securityPort.getCurrentUserId()

val countAnnual = queryHolidayPort.countHolidayByYearAndUserIdAndType(year, currentUserId, HolidayType.ANNUAL)
val annualCount = queryHolidayPort.countHolidayByYearAndUserIdAndType(year, currentUserId, HolidayType.ANNUAL)

return Holiday.ANNUAL_LEAVE_LIMIT - countAnnual
return Holiday.calculateRemainedAnnualCount(annualCount)
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package team.comit.simtong.domain.holiday.usecase

import team.comit.simtong.domain.holiday.model.HolidayStatus
import team.comit.simtong.domain.holiday.model.HolidayType
import team.comit.simtong.domain.holiday.spi.CommandHolidayPort
import team.comit.simtong.domain.holiday.spi.HolidayQueryUserPort
Expand All @@ -15,7 +14,7 @@ import team.comit.simtong.global.annotation.UseCase
*
* @author kimbeomjin
* @date 2022/12/21
* @version 1.0.0
* @version 1.2.5
**/
@UseCase
class ShareHolidayUseCase(
Expand All @@ -34,9 +33,7 @@ class ShareHolidayUseCase(
)

val completedHolidays = holidays.map {
it.copy(
status = HolidayStatus.COMPLETED
)
it.share()
}

commandHolidayPort.saveAll(completedHolidays)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package team.comit.simtong.domain.holiday.model

import team.comit.simtong.domain.holiday.exception.HolidayExceptions
import team.comit.simtong.global.DomainProperties.getProperty
import team.comit.simtong.global.DomainPropertiesPrefix
import team.comit.simtong.global.annotation.Aggregate
Expand All @@ -11,8 +12,9 @@ import java.util.UUID
* 휴무일의 Root Aggregate를 담당하는 Holiday
*
* @author Chokyunghyeon
* @author kimbeomjin
* @date 2022/12/02
* @version 1.0.0
* @version 1.2.5
**/
@Aggregate
data class Holiday(
Expand All @@ -33,5 +35,46 @@ data class Holiday(

val ANNUAL_LEAVE_LIMIT: Long = getProperty(DomainPropertiesPrefix.ANNUAL_LEAVE_LIMIT).toLong()

fun createHoliday(
date: LocalDate,
userId: UUID,
type: HolidayType = HolidayType.HOLIDAY,
spotId: UUID,
status: HolidayStatus = HolidayStatus.WRITTEN
) = Holiday(date, userId, type, spotId, status)

fun createAnnual(
date: LocalDate,
userId: UUID,
type: HolidayType = HolidayType.ANNUAL,
spotId: UUID,
status: HolidayStatus = HolidayStatus.COMPLETED
) = Holiday(date, userId, type, spotId, status)

fun calculateRemainedAnnualCount(annualCount: Long) = ANNUAL_LEAVE_LIMIT - annualCount

fun checkNotExceededHolidayLimit(holidayCount: Long) {
if (holidayCount >= WEEK_HOLIDAY_LIMIT) {
throw HolidayExceptions.WeekHolidayLimitExcess()
}
}

fun checkNotExceededAnnualLimit(annualCount: Long) {
if (annualCount >= ANNUAL_LEAVE_LIMIT) {
throw HolidayExceptions.AnnualLeaveLimitExcess()
}
}
}

fun share() = this.copy(status = HolidayStatus.COMPLETED)

fun isSameSpot(spotId: UUID) = this.spotId == spotId

fun isCompleted() = this.status == HolidayStatus.COMPLETED

fun change(holidayCount: Long, to: LocalDate): Holiday {
checkNotExceededHolidayLimit(holidayCount)

return this.copy(date = to)
}
}
Loading

0 comments on commit a2fa3bb

Please sign in to comment.