v2.4.0: Phase 2 — meal time, past records, goals, CSV import, crash report
- Meal time dialog (right-click lunch/dinner button to enter actual times) - Calendar right-click context: add/edit/delete past records - Monthly goal settings + progress widget (overtime cap, avg daily) - CSV import (our standard format) with conflict policy - Global crash handler with Gitea Issues auto-report 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
d3a4efc173
commit
9ebf4ad961
+58
-5
@@ -652,6 +652,9 @@ class Database:
|
||||
'discord_notif_clock_in': 'true',
|
||||
'discord_notif_clock_out': 'true',
|
||||
'discord_notif_health': 'true',
|
||||
# v2.4.0
|
||||
'goal_overtime_max_monthly': '0', # 0=비활성, >0=분 단위 상한
|
||||
'goal_avg_hours_daily': '0', # 0=비활성
|
||||
}
|
||||
|
||||
conn = self.get_connection()
|
||||
@@ -1265,21 +1268,71 @@ class Database:
|
||||
|
||||
# ===== 외출 관련 메서드 =====
|
||||
|
||||
def add_break_record(self, work_record_id: int, date: str, break_out: str, reason: str = None) -> int:
|
||||
"""외출 기록 추가"""
|
||||
def add_break_record(self, work_record_id: int, date: str, break_out: str,
|
||||
reason: str = None, break_type: str = 'break') -> int:
|
||||
"""외출 기록 추가. break_type: 'break'(외출) / 'lunch' / 'dinner'."""
|
||||
conn = self.get_connection()
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute('''
|
||||
INSERT INTO break_records (work_record_id, date, break_out, reason)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', (work_record_id, date, break_out, reason))
|
||||
INSERT INTO break_records (work_record_id, date, break_out, reason, break_type)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
''', (work_record_id, date, break_out, reason, break_type))
|
||||
|
||||
record_id = cursor.lastrowid
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return record_id
|
||||
|
||||
def add_meal_record(self, date: str, start_time: str, end_time: str,
|
||||
meal_type: str = 'lunch') -> int:
|
||||
"""식사 시간 기록 (시작·종료 둘 다 알 때).
|
||||
|
||||
Args:
|
||||
date: 'YYYY-MM-DD'
|
||||
start_time, end_time: 'HH:MM:SS'
|
||||
meal_type: 'lunch' or 'dinner'
|
||||
Returns:
|
||||
새 break_record id
|
||||
"""
|
||||
from datetime import datetime as _dt
|
||||
# 분 계산
|
||||
start_dt = _dt.strptime(start_time, '%H:%M:%S')
|
||||
end_dt = _dt.strptime(end_time, '%H:%M:%S')
|
||||
if end_dt < start_dt:
|
||||
from datetime import timedelta as _td
|
||||
end_dt += _td(days=1)
|
||||
total_min = int((end_dt - start_dt).total_seconds() / 60)
|
||||
|
||||
rec = self.get_today_record() if date == _dt.now().date().isoformat() else None
|
||||
wid = rec['id'] if rec else None
|
||||
|
||||
conn = self.get_connection()
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('''
|
||||
INSERT INTO break_records (work_record_id, date, break_out, break_in,
|
||||
total_minutes, break_type)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
''', (wid, date, start_time, end_time, total_min, meal_type))
|
||||
rid = cursor.lastrowid
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return rid
|
||||
|
||||
def get_meal_minutes_today(self, meal_type: str = 'lunch') -> int:
|
||||
"""오늘의 식사 시간 합계 (분). 수동 입력된 경우만."""
|
||||
from datetime import date as _date
|
||||
today = _date.today().isoformat()
|
||||
conn = self.get_connection()
|
||||
cursor = conn.cursor()
|
||||
cursor.execute('''
|
||||
SELECT COALESCE(SUM(total_minutes), 0) FROM break_records
|
||||
WHERE date = ? AND break_type = ? AND total_minutes IS NOT NULL
|
||||
''', (today, meal_type))
|
||||
result = cursor.fetchone()[0] or 0
|
||||
conn.close()
|
||||
return int(result)
|
||||
|
||||
def update_break_return(self, break_id: int, break_in: str):
|
||||
"""외출 복귀 시간 업데이트"""
|
||||
conn = self.get_connection()
|
||||
|
||||
@@ -44,6 +44,10 @@ DB_PATH_OVERRIDE = 'db_path_override'
|
||||
# 백업
|
||||
LAST_BACKUP_DATE = 'last_backup_date'
|
||||
|
||||
# Crash Report (Gitea Issues 통합 — 옵션)
|
||||
GITEA_FEEDBACK_TOKEN = 'gitea_feedback_token' # PAT (저장소 issue 쓰기 권한)
|
||||
GITEA_FEEDBACK_ENABLED = 'gitea_feedback_enabled'
|
||||
|
||||
# === v2.3.0 신규 ===
|
||||
# 온보딩
|
||||
ONBOARDING_COMPLETED = 'onboarding_completed'
|
||||
@@ -57,6 +61,10 @@ OVERTIME_RATE = 'overtime_rate' # 1.5
|
||||
HEALTH_BREAK_ENABLED = 'health_break_enabled'
|
||||
HEALTH_BREAK_HOURS = 'health_break_hours' # 기본 4
|
||||
|
||||
# 목표
|
||||
GOAL_OVERTIME_MAX_MONTHLY = 'goal_overtime_max_monthly' # 월 연장근무 상한 (분)
|
||||
GOAL_AVG_HOURS_DAILY = 'goal_avg_hours_daily' # 일평균 목표 (시간, float)
|
||||
|
||||
# Discord 웹훅
|
||||
DISCORD_WEBHOOK_URL = 'discord_webhook_url'
|
||||
DISCORD_NOTIF_CLOCK_IN = 'discord_notif_clock_in'
|
||||
|
||||
+1
-1
@@ -4,4 +4,4 @@
|
||||
릴리스 시 이 값을 올린 후 git tag → push.
|
||||
CHANGELOG.md의 최상단 항목과 일치시킬 것.
|
||||
"""
|
||||
__version__ = '2.3.3'
|
||||
__version__ = '2.4.0'
|
||||
|
||||
Reference in New Issue
Block a user