""" 연차 사용 캘린더 시각화. QCalendarWidget에 사용 연차일을 색칠로 표시. - 1.0일: 진한 색 - 0.5일(반차): 중간 색 - 0.25일(반반차): 옅은 색 """ from __future__ import annotations from datetime import datetime from PyQt5.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QCalendarWidget) from PyQt5.QtCore import Qt, QDate from PyQt5.QtGui import QTextCharFormat, QColor, QBrush from ui.styles import apply_dark_titlebar class LeaveCalendarView(QDialog): """연차 캘린더 시각화.""" def __init__(self, parent=None, db=None): super().__init__(parent) self.db = db self.setWindowTitle("📅 연차 캘린더") self.setModal(True) self.setMinimumSize(540, 480) self._build_ui() self._mark_dates() apply_dark_titlebar(self) def _build_ui(self): layout = QVBoxLayout() # 헤더: 잔여 + 범례 header = QHBoxLayout() balance = float(self.db.get_setting('leave_balance', '0') or 0) total = float(self.db.get_setting('annual_leave_total', '15') or 15) used = total - balance title = QLabel(f"🌴 잔여 {balance:.2f}일 / 총 {total:.0f}일 (사용 {used:.2f}일)") title.setStyleSheet("font-weight: bold; font-size: 13px;") header.addWidget(title) header.addStretch() layout.addLayout(header) # 범례 legend = QHBoxLayout() for label, color in [("🟩 종일(1.0)", "#4caf50"), ("🟨 반차(0.5)", "#ffc107"), ("🟪 반반차(0.25)", "#9c27b0")]: l = QLabel(label) l.setStyleSheet(f"padding: 2px 6px;") legend.addWidget(l) legend.addStretch() layout.addLayout(legend) # 캘린더 self.calendar = QCalendarWidget() self.calendar.setVerticalHeaderFormat(QCalendarWidget.NoVerticalHeader) self.calendar.clicked.connect(self._on_date_click) layout.addWidget(self.calendar, 1) # 선택 일자 정보 self.detail_label = QLabel("") self.detail_label.setStyleSheet("padding: 6px; color: #888;") layout.addWidget(self.detail_label) # 닫기 버튼 btn_row = QHBoxLayout() btn_row.addStretch() close_btn = QPushButton("닫기") close_btn.clicked.connect(self.close) btn_row.addWidget(close_btn) layout.addLayout(btn_row) self.setLayout(layout) def _mark_dates(self): """연차 사용 일자에 색상 표시.""" records = self.db.get_all_leave_records(limit=365) for r in records: try: d = datetime.strptime(r['date'], '%Y-%m-%d').date() except (ValueError, TypeError): continue qd = QDate(d.year, d.month, d.day) days = float(r.get('days') or 0) if days >= 1.0: color = QColor("#4caf50") elif days >= 0.5: color = QColor("#ffc107") else: color = QColor("#9c27b0") fmt = QTextCharFormat() fmt.setBackground(QBrush(color)) fmt.setForeground(QBrush(QColor("white"))) self.calendar.setDateTextFormat(qd, fmt) def _on_date_click(self, qdate): date_str = qdate.toString('yyyy-MM-dd') records = self.db.get_all_leave_records(limit=365) match = [r for r in records if r['date'] == date_str] if not match: self.detail_label.setText(f"{date_str} — 연차 사용 없음") return parts = [] for r in match: t = r.get('leave_type', 'annual') d = float(r.get('days') or 0) memo = r.get('memo') or '' parts.append(f"{t} {d}일" + (f" ({memo})" if memo else "")) self.detail_label.setText(f"📅 {date_str}: " + ", ".join(parts))