""" CSV 내보내기 유틸리티 """ import csv from datetime import datetime from typing import List, Dict import os class CSVExporter: """CSV 내보내기 클래스""" @staticmethod def export_work_records(records: List[Dict], filename: str = None) -> str: """ 근무 기록을 CSV로 내보내기 Args: records: 근무 기록 리스트 filename: 저장할 파일명 (None이면 자동 생성) Returns: str: 저장된 파일 경로 """ if filename is None: timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"work_records_{timestamp}.csv" # CSV 파일 작성 with open(filename, 'w', newline='', encoding='utf-8-sig') as csvfile: fieldnames = [ '날짜', '출근시간', '퇴근시간', '점심시간', '총근무시간', '연장근무(분)', '적립(분)', '메모' ] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() for record in records: row = { '날짜': record.get('date', ''), '출근시간': record.get('clock_in', ''), '퇴근시간': record.get('clock_out', '미기록'), '점심시간': '사용' if record.get('lunch_break') else '미사용', '총근무시간': f"{record.get('total_hours', 0):.1f}시간", '연장근무(분)': record.get('overtime_minutes', 0), '적립(분)': record.get('overtime_earned', 0), '메모': record.get('memo', '') } writer.writerow(row) return filename @staticmethod def export_overtime_summary(db, filename: str = None) -> str: """ 연장근무 요약 내보내기 Args: db: Database 인스턴스 filename: 저장할 파일명 Returns: str: 저장된 파일 경로 """ if filename is None: timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") filename = f"overtime_summary_{timestamp}.csv" # 연장근무 내역 가져오기 overtime_history = db.get_overtime_history(limit=100) with open(filename, 'w', newline='', encoding='utf-8-sig') as csvfile: fieldnames = ['유형', '날짜', '시간(분)', '출근', '퇴근'] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() for item in overtime_history: row = { '유형': '적립' if item['type'] == 'earned' else '사용', '날짜': item.get('date', ''), '시간(분)': item.get('minutes', 0), '출근': item.get('clock_in', ''), '퇴근': item.get('clock_out', '') } writer.writerow(row) return filename @staticmethod def export_monthly_summary(db, year: int, month: int, filename: str = None) -> str: """ 월간 요약 내보내기 Args: db: Database 인스턴스 year: 년도 month: 월 filename: 저장할 파일명 Returns: str: 저장된 파일 경로 """ if filename is None: filename = f"monthly_summary_{year}{month:02d}.csv" stats = db.get_monthly_stats(year, month) with open(filename, 'w', newline='', encoding='utf-8-sig') as csvfile: writer = csv.writer(csvfile) # 요약 정보 writer.writerow([f"{year}년 {month}월 근무 요약"]) writer.writerow([]) writer.writerow(['항목', '값']) writer.writerow(['총 근무시간', f"{stats['total_hours']:.1f}시간"]) writer.writerow(['근무일수', f"{stats['work_days']}일"]) if stats['work_days'] > 0: avg = stats['total_hours'] / stats['work_days'] writer.writerow(['평균 근무시간', f"{avg:.1f}시간"]) overtime_hours = stats['total_overtime_minutes'] // 60 overtime_mins = stats['total_overtime_minutes'] % 60 writer.writerow(['총 연장근무', f"{overtime_hours}시간 {overtime_mins}분"]) writer.writerow([]) writer.writerow([]) # 상세 기록 writer.writerow(['날짜', '출근', '퇴근', '총근무시간', '연장근무']) for record in stats['records']: overtime_min = record.get('overtime_earned', 0) overtime_h = overtime_min // 60 overtime_m = overtime_min % 60 overtime_str = f"{overtime_h}시간 {overtime_m}분" if overtime_min > 0 else "-" writer.writerow([ record.get('date', ''), record.get('clock_in', ''), record.get('clock_out', '미기록'), f"{record.get('total_hours', 0):.1f}시간", overtime_str ]) return filename # 테스트 코드 if __name__ == "__main__": import sys import os sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from core.database import Database db = Database() # 테스트: 이번 달 기록 내보내기 now = datetime.now() filename = CSVExporter.export_monthly_summary(db, now.year, now.month) print(f"Exported to: {filename}")