Skip to content
Merged
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
27 changes: 8 additions & 19 deletions src/main/kotlin/com/moa/service/WorkdayService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,7 @@ class WorkdayService(
DailyWorkScheduleType.VACATION -> {
val policy = resolveMonthlyRepresentativePolicyOrNull(memberId, date.year, date.monthValue)
?: throw NotFoundException()
validateVacationInput(date, existingSchedule, policy)
resolveVacationTimes(req, policy)
resolveVacationTimes(date, req, existingSchedule, policy)
}

DailyWorkScheduleType.NONE -> null to null
Expand Down Expand Up @@ -313,25 +312,10 @@ class WorkdayService(
}
}

private fun validateVacationInput(
date: LocalDate,
savedSchedule: DailyWorkSchedule?,
policy: WorkPolicyVersion,
) {
if (savedSchedule?.type == DailyWorkScheduleType.VACATION) return

val schedule = resolveSchedule(savedSchedule, policy, date)
val isDefaultWorkSchedule = schedule.type == DailyWorkScheduleType.WORK &&
schedule.clockIn == policy.clockInTime &&
schedule.clockOut == policy.clockOutTime

if (!isDefaultWorkSchedule) {
throw BadRequestException(ErrorCode.INVALID_WORKDAY_INPUT)
}
}

private fun resolveVacationTimes(
date: LocalDate,
req: WorkdayUpsertRequest,
savedSchedule: DailyWorkSchedule?,
policy: WorkPolicyVersion,
): Pair<LocalTime, LocalTime> {
if (req.clockInTime != null && req.clockOutTime != null) {
Expand All @@ -340,6 +324,11 @@ class WorkdayService(
return clockIn to clockOut
}

val schedule = resolveSchedule(savedSchedule, policy, date)
if (schedule.clockIn != null && schedule.clockOut != null) {
return schedule.clockIn to schedule.clockOut
}

return policy.clockInTime to policy.clockOutTime
Comment on lines +327 to 332
Copy link

Copilot AI Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolveVacationTimes no longer enforces the validation that previously existed in validateVacationInput. With the current logic, if the request omits times, the method will (a) use savedSchedule times even when the saved schedule is a non-default/custom WORK schedule, and (b) fall back to policy times even when resolveSchedule(...) resolves to NONE (e.g., a non-workday). This is a concrete behavior change from the removed guard that threw BadRequestException(ErrorCode.INVALID_WORKDAY_INPUT) when the date was not the default work schedule. If that constraint is still required, reintroduce the equivalent check here (e.g., only allow implicit vacation times when the resolved schedule is default WORK with policy times, or when the existing saved schedule is already VACATION).

Suggested change
val schedule = resolveSchedule(savedSchedule, policy, date)
if (schedule.clockIn != null && schedule.clockOut != null) {
return schedule.clockIn to schedule.clockOut
}
return policy.clockInTime to policy.clockOutTime
if (
savedSchedule?.type == DailyWorkScheduleType.VACATION &&
savedSchedule.clockInTime != null &&
savedSchedule.clockOutTime != null
) {
return savedSchedule.clockInTime to savedSchedule.clockOutTime
}
val schedule = resolveSchedule(savedSchedule, policy, date)
if (
savedSchedule == null &&
schedule.type == DailyWorkScheduleType.WORK &&
schedule.clockIn != null &&
schedule.clockOut != null
) {
return schedule.clockIn to schedule.clockOut
}
throw BadRequestException(ErrorCode.INVALID_WORKDAY_INPUT)

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

@jeyongsong jeyongsong Apr 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This behavior change is intentional.
We explicitly removed validateVacationInput so VACATION can be upserted even when the date is not a default workday or when a custom saved schedule already exists.
Time resolution now follows this order: request values, existing/resolved schedule values, then policy default times.

}

Expand Down
Loading