v2.2.4: implement auto_overtime + overtime_unit + notif_before_minutes; remove 3 dead settings
Implemented (previously UI-only with no business effect): - auto_overtime: when OFF, prompt user on clock-out before banking - overtime_unit: 15/30/60-min truncation choice now actually applied - notification_before_minutes: 30-min hardcode -> user-configurable 1~120 Removed dead keys (no readers in business logic): - auto_detect_boot, notification_enabled, annual_leave_used Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
b91b229731
commit
14d88656fe
+3
-5
@@ -520,21 +520,19 @@ class Database:
|
||||
'work_minutes': '480',
|
||||
'lunch_duration_minutes': '60',
|
||||
'dinner_duration_minutes': '60',
|
||||
'auto_detect_boot': 'true',
|
||||
'auto_lunch': 'false',
|
||||
'auto_overtime': 'true',
|
||||
'theme': 'light',
|
||||
'notification_enabled': 'true',
|
||||
'notification_before_minutes': '30',
|
||||
'notification_clock_out': 'true',
|
||||
'notification_lunch': 'true',
|
||||
'notification_overtime': 'true',
|
||||
'notification_health': 'true',
|
||||
'annual_leave_total': '15',
|
||||
'annual_leave_days': '15', # UI에서 사용하는 키 (annual_leave_total과 동기화)
|
||||
'annual_leave_used': '0',
|
||||
'annual_leave_days': '15', # annual_leave_total과 자동 동기화
|
||||
'workday_boundary_hour': '6',
|
||||
'overtime_unit': '30',
|
||||
'time_format': '24'
|
||||
'time_format': '24',
|
||||
}
|
||||
|
||||
conn = self.get_connection()
|
||||
|
||||
+11
-2
@@ -65,8 +65,17 @@ class Notifier(QObject):
|
||||
return
|
||||
time_diff = clock_out_time - current_time
|
||||
|
||||
# 30분 이내, 아직 알림 안 했으면
|
||||
if 0 < time_diff.total_seconds() <= 1800 and not self.notified_30min:
|
||||
# 사용자 설정 N분 이내 알림 (기본 30, 설정에서 1~120 범위)
|
||||
threshold_min = 30
|
||||
if self.db is not None:
|
||||
try:
|
||||
threshold_min = int(self.db.get_setting('notification_before_minutes', '30') or '30')
|
||||
threshold_min = max(1, min(120, threshold_min))
|
||||
except (ValueError, TypeError):
|
||||
threshold_min = 30
|
||||
threshold_sec = threshold_min * 60
|
||||
|
||||
if 0 < time_diff.total_seconds() <= threshold_sec and not self.notified_30min:
|
||||
minutes_left = int(time_diff.total_seconds() / 60)
|
||||
self.notification_signal.emit(
|
||||
tr('notif.clock_out_soon.title'),
|
||||
|
||||
@@ -13,14 +13,12 @@ DINNER_DURATION_MINUTES = 'dinner_duration_minutes'
|
||||
WORKDAY_BOUNDARY_HOUR = 'workday_boundary_hour'
|
||||
|
||||
# 자동화
|
||||
AUTO_DETECT_BOOT = 'auto_detect_boot'
|
||||
AUTO_LUNCH = 'auto_lunch'
|
||||
AUTO_OVERTIME = 'auto_overtime'
|
||||
AUTO_BREAK_ON_LOCK = 'auto_break_on_lock'
|
||||
CLOCK_IN_ON_UNLOCK = 'clock_in_on_unlock' # 첫 잠금 해제를 출근으로 사용 (PC 안 끄는 사용자용)
|
||||
|
||||
# 알림
|
||||
NOTIFICATION_ENABLED = 'notification_enabled'
|
||||
NOTIFICATION_BEFORE_MINUTES = 'notification_before_minutes'
|
||||
NOTIF_CLOCK_OUT = 'notification_clock_out'
|
||||
NOTIF_LUNCH = 'notification_lunch'
|
||||
@@ -30,7 +28,6 @@ NOTIF_HEALTH = 'notification_health'
|
||||
# 연차
|
||||
ANNUAL_LEAVE_TOTAL = 'annual_leave_total'
|
||||
ANNUAL_LEAVE_DAYS = 'annual_leave_days'
|
||||
ANNUAL_LEAVE_USED = 'annual_leave_used'
|
||||
LEAVE_BALANCE = 'leave_balance'
|
||||
INITIAL_OVERTIME_MINUTES = 'initial_overtime_minutes'
|
||||
INITIAL_LEAVE_USED_HOURS = 'initial_leave_used_hours'
|
||||
|
||||
@@ -135,17 +135,19 @@ class TimeCalculator:
|
||||
|
||||
def calculate_overtime(self, clock_in: datetime, clock_out: datetime,
|
||||
include_lunch: bool = False, include_dinner: bool = False,
|
||||
break_minutes: int = 0) -> Tuple[int, int]:
|
||||
break_minutes: int = 0,
|
||||
unit_minutes: int = 30) -> Tuple[int, int]:
|
||||
"""
|
||||
연장근무 시간 계산 (실제 시간, 30분 단위 적립)
|
||||
연장근무 시간 계산 (실제 시간, unit_minutes 단위 적립)
|
||||
Args:
|
||||
clock_in: 출근 시간
|
||||
clock_out: 퇴근 시간
|
||||
include_lunch: 점심시간 포함 여부
|
||||
include_dinner: 저녁시간 포함 여부
|
||||
break_minutes: 외출 시간 (분) - 연장근무 계산에서 제외
|
||||
unit_minutes: 적립 단위 (분, 기본 30). 사용자 설정 OVERTIME_UNIT.
|
||||
Returns:
|
||||
Tuple[int, int]: (실제 연장근무 분, 30분 단위 적립 분)
|
||||
Tuple[int, int]: (실제 연장근무 분, unit_minutes 단위 적립 분)
|
||||
"""
|
||||
expected_clock_out = self.calculate_clock_out_time(clock_in, include_lunch, include_dinner, break_minutes)
|
||||
|
||||
@@ -155,8 +157,8 @@ class TimeCalculator:
|
||||
overtime_duration = clock_out - expected_clock_out
|
||||
overtime_minutes = int(overtime_duration.total_seconds() / 60)
|
||||
|
||||
# 30분 단위로 절삭
|
||||
overtime_earned = (overtime_minutes // 30) * 30
|
||||
unit = unit_minutes if unit_minutes > 0 else 30
|
||||
overtime_earned = (overtime_minutes // unit) * unit
|
||||
|
||||
return overtime_minutes, overtime_earned
|
||||
|
||||
|
||||
+1
-1
@@ -4,4 +4,4 @@
|
||||
릴리스 시 이 값을 올린 후 git tag → push.
|
||||
CHANGELOG.md의 최상단 항목과 일치시킬 것.
|
||||
"""
|
||||
__version__ = '2.2.3'
|
||||
__version__ = '2.2.4'
|
||||
|
||||
Reference in New Issue
Block a user