KINDNICK e4011d9fc3 v2.3.0: Phase 1 + E1 — onboarding wizard, salary, inline edit, today card, health break, Discord webhook
Added (6 user-friendly features):
- Onboarding wizard (5 steps, forced on first launch, re-runnable from Help menu)
- Salary estimation (optional, hourly wage + overtime multiplier)
- Inline clock-in/out time editing (click label to edit)
- Today summary card (post-clockout, auto-hide on next clock-in)
- Health break reminder (continuous N-hour at desk warning)
- Discord webhook notifications (clock-in/out/health, mobile push, no server)

Database:
- break_records.break_type column ('break'/'lunch'/'dinner')
- notification_log table (dedupe + analytics)
- Auto-complete onboarding for existing users (work_records exists)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 18:01:48 +09:00

51 lines
1.5 KiB
Python

"""
급여 추정 (옵션).
포괄임금제 회사면 사용 안 함. 시급 + 연장수당 가산률만 받아서 단순 계산.
"""
from __future__ import annotations
from typing import List, Dict
def estimate_pay(records: List[Dict], hourly_wage: float,
overtime_rate: float = 1.5) -> Dict[str, float]:
"""근무 기록 리스트로부터 추정 급여 계산.
Args:
records: [{'total_hours': float, 'overtime_minutes': int}, ...]
hourly_wage: 시급(원)
overtime_rate: 연장수당 가산률 (기본 1.5배 - 한국 노동법)
Returns:
{'base': 기본급, 'overtime': 연장수당, 'total': 합계}
"""
if hourly_wage <= 0:
return {'base': 0.0, 'overtime': 0.0, 'total': 0.0}
base_hours = 0.0
overtime_hours = 0.0
for r in records:
total = float(r.get('total_hours') or 0)
ot_min = int(r.get('overtime_minutes') or 0)
ot_hours = ot_min / 60.0
# 정규 근무 = 총 - 연장
regular = max(0.0, total - ot_hours)
base_hours += regular
overtime_hours += ot_hours
base = base_hours * hourly_wage
overtime = overtime_hours * hourly_wage * overtime_rate
return {
'base': base,
'overtime': overtime,
'total': base + overtime,
'base_hours': base_hours,
'overtime_hours': overtime_hours,
}
def format_won(amount: float) -> str:
"""원화 포맷팅. 1234567 → '1,234,567원'."""
return f"{int(round(amount)):,}"