From f34d7d9e433ca39ab90aee86cebe5d49ee6a3e99 Mon Sep 17 00:00:00 2001 From: jeyong Date: Wed, 18 Mar 2026 00:57:56 +0900 Subject: [PATCH 1/2] Fix work minutes calculation to handle same start and end times --- src/main/kotlin/com/moa/entity/SalaryType.kt | 5 +++-- src/main/kotlin/com/moa/service/WorkdayService.kt | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/com/moa/entity/SalaryType.kt b/src/main/kotlin/com/moa/entity/SalaryType.kt index 8af6a1e..8383572 100644 --- a/src/main/kotlin/com/moa/entity/SalaryType.kt +++ b/src/main/kotlin/com/moa/entity/SalaryType.kt @@ -72,8 +72,9 @@ object SalaryCalculator { /** * 출근 시간과 퇴근 시간 사이의 총 근무 시간을 분(minute) 단위로 계산합니다. * - * 퇴근 시간이 출근 시간보다 빠르거나 같은 경우, 익일 퇴근(야간 교대근무 등)으로 간주하여 + * 퇴근 시간이 출근 시간보다 빠른 경우에만, 익일 퇴근(야간 교대근무 등)으로 간주하여 * 자동으로 24시간(1440분)을 더하여 계산합니다. + * 출근 시간과 퇴근 시간이 같으면 0분으로 계산합니다. * * @param clockIn 출근 시간 * @param clockOut 퇴근 시간 @@ -81,7 +82,7 @@ object SalaryCalculator { */ fun calculateWorkMinutes(clockIn: LocalTime, clockOut: LocalTime): Long { val minutes = Duration.between(clockIn, clockOut).toMinutes() - return if (minutes <= 0) minutes + 24 * 60 else minutes + return if (minutes < 0) minutes + 24 * 60 else minutes } /** diff --git a/src/main/kotlin/com/moa/service/WorkdayService.kt b/src/main/kotlin/com/moa/service/WorkdayService.kt index 395e7ff..382383f 100644 --- a/src/main/kotlin/com/moa/service/WorkdayService.kt +++ b/src/main/kotlin/com/moa/service/WorkdayService.kt @@ -372,7 +372,7 @@ class WorkdayService( val clockIn = schedule.clockIn ?: return DailyWorkStatusType.NONE val clockOut = schedule.clockOut ?: return DailyWorkStatusType.NONE val now = LocalDateTime.now() - val endAt = if (clockOut.isAfter(clockIn)) { + val endAt = if (!clockOut.isBefore(clockIn)) { date.atTime(clockOut) } else { date.plusDays(1).atTime(clockOut) @@ -401,7 +401,7 @@ class WorkdayService( } return when { - clockOut.isAfter(clockIn) -> minOf(now, clockOut) + !clockOut.isBefore(clockIn) -> minOf(now, clockOut) else -> now } } From 50c91eb420d78cf9fbb5dcd0f11142e0828bc117 Mon Sep 17 00:00:00 2001 From: jeyong Date: Wed, 18 Mar 2026 00:58:02 +0900 Subject: [PATCH 2/2] Add tests for zero earnings and work minutes when start and end times are the same --- .../com/moa/entity/SalaryCalculatorTest.kt | 9 +++++++++ .../com/moa/service/EarningsCalculatorTest.kt | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/test/kotlin/com/moa/entity/SalaryCalculatorTest.kt b/src/test/kotlin/com/moa/entity/SalaryCalculatorTest.kt index c3cbb6d..6dbc380 100644 --- a/src/test/kotlin/com/moa/entity/SalaryCalculatorTest.kt +++ b/src/test/kotlin/com/moa/entity/SalaryCalculatorTest.kt @@ -177,6 +177,15 @@ class SalaryCalculatorTest { assertThat(result).isEqualTo(240L) } + @Test + fun `calculateWorkMinutes - 시작시간과 종료시간이 같으면 0분을 반환한다`() { + val result = SalaryCalculator.calculateWorkMinutes( + LocalTime.of(9, 0), + LocalTime.of(9, 0), + ) + assertThat(result).isEqualTo(0L) + } + // --- 실제 수입 계산 --- @Test diff --git a/src/test/kotlin/com/moa/service/EarningsCalculatorTest.kt b/src/test/kotlin/com/moa/service/EarningsCalculatorTest.kt index 6a263f7..beb021a 100644 --- a/src/test/kotlin/com/moa/service/EarningsCalculatorTest.kt +++ b/src/test/kotlin/com/moa/service/EarningsCalculatorTest.kt @@ -159,6 +159,23 @@ class EarningsCalculatorTest { assertThat(result!!.toLong()).isLessThan(dailyRate) } + @Test + fun `출퇴근 시간이 같으면 0원을 반환한다`() { + stubPayroll() + val policy = createPolicy() + + val result = sut.calculateDailyEarnings( + memberId = MEMBER_ID, + date = DATE, + policy = policy, + type = DailyWorkScheduleType.WORK, + clockInTime = LocalTime.of(9, 0), + clockOutTime = LocalTime.of(9, 0), + ) + + assertThat(result).isEqualByComparingTo(BigDecimal.ZERO) + } + // --- getDefaultMonthlySalary --- @Test