fix(holiday): live hot-path now banks overtime from minute 1 on holidays
3 bugs found and fixed: A. update_display() 1Hz 루프에 is_non_working_day 분기 누락 - 휴일/주말 출근 시 '남은 시간 8h'부터 카운트다운 → 실제 휴일 추가근무 시작 안 됨 - 수정: is_non_working_day=True면 calculate_holiday_overtime로 즉시 음수 remaining 표시 - 그룹 타이틀: '주말 근무 (전체 적립)' / '공휴일 근무 (전체 적립)' - 진행바: 휴일은 100% 고정 (의미 없음) - 예상 퇴근: '휴일 근무 (정해진 퇴근시각 없음)' B. check_clock_out_soon 알림이 휴일에도 fire - 휴일엔 정해진 퇴근시각이 없으니 무의미한 알림 - 수정: orchestrator.tick(is_holiday=True)면 스킵 - 점심/저녁/장시간 휴식 알림은 휴일에도 유지 (식사·건강은 휴일에도 챙김) C. 자동복구 퇴근 3곳이 (work_minutes // 30) * 30 하드코딩 - main_window.py:1385, 1512, 1581 — 사용자 overtime_unit (15/30/60) 무시 - 수정: 모두 settings에서 unit_minutes 읽어 calculate_holiday_overtime/calculate_overtime에 전달 리팩터링: 4곳에 중복되던 휴일 연장 계산 로직을 TimeCalculator.calculate_holiday_overtime로 추출. Tests: - tests/test_time_calculator.py: 9개 신규 (TestHolidayOvertime) - _integration_test.py: S52A 휴일 hot-path 회귀 시나리오
This commit is contained in:
@@ -236,6 +236,36 @@ class TimeCalculator:
|
||||
normal_clock_out = self.calculate_clock_out_time(clock_in, include_lunch, include_dinner)
|
||||
return normal_clock_out + timedelta(minutes=target_overtime_minutes)
|
||||
|
||||
def calculate_holiday_overtime(self, clock_in: datetime, current_time: datetime,
|
||||
include_lunch: bool = False,
|
||||
include_dinner: bool = False,
|
||||
break_minutes: int = 0,
|
||||
unit_minutes: int = 30) -> Tuple[int, int]:
|
||||
"""
|
||||
휴일/주말 근무: 모든 시간을 연장근무로 계산.
|
||||
|
||||
Args:
|
||||
clock_in: 출근 시간
|
||||
current_time: 현재(또는 퇴근) 시간
|
||||
include_lunch/dinner: 식사 시간 차감 여부
|
||||
break_minutes: 외출 시간 (분) — 연장근무에서 제외
|
||||
unit_minutes: 적립 단위 (15/30/60)
|
||||
|
||||
Returns:
|
||||
(실제 연장 분, 적립 분) — 둘 다 0 이상.
|
||||
"""
|
||||
elapsed_minutes = int((current_time - clock_in).total_seconds() / 60)
|
||||
if include_lunch:
|
||||
elapsed_minutes -= self.lunch_duration_minutes
|
||||
if include_dinner:
|
||||
elapsed_minutes -= self.dinner_duration_minutes
|
||||
elapsed_minutes -= break_minutes
|
||||
elapsed_minutes = max(0, elapsed_minutes)
|
||||
|
||||
unit = unit_minutes if unit_minutes > 0 else 30
|
||||
earned = (elapsed_minutes // unit) * unit
|
||||
return elapsed_minutes, earned
|
||||
|
||||
def is_weekend(self, date_obj: datetime) -> bool:
|
||||
"""
|
||||
주말 여부 확인
|
||||
|
||||
Reference in New Issue
Block a user