# event_type_handler.py from datetime import datetime from dateutil.relativedelta import relativedelta from typing import List, Dict, Tuple from calendar_entry import CalendarEntry from config import EventConfig from date_service import DateService class EventTypeHandler: """Handles event type-specific business rules and categorization""" @staticmethod def get_duration_for_type(event_type: str, start_date: datetime) -> datetime: """Calculate end date for event type based on business rules""" if event_type == "EZ pauschal": return start_date + EventConfig.get_ez_pauschal_duration() else: # For other types, duration is determined by user input return start_date @staticmethod def categorize_events(entries: List[CalendarEntry]) -> Dict[str, List[Tuple[datetime, datetime, str]]]: """Categorize calendar entries by type for processing""" categorized = {} for entry in entries: if entry.keyword not in categorized: categorized[entry.keyword] = [] categorized[entry.keyword].append(( entry.start_date, entry.end_date, entry.id )) return categorized @staticmethod def validate_event_type(event_type: str) -> bool: """Validate that event type is supported""" return EventConfig.is_valid_keyword(event_type) @staticmethod def get_event_type_display_name(event_type: str) -> str: """Get display name for event type""" display_names = { "EZ 100%": "Erziehungszeit 100%", "EZ 50%": "Erziehungszeit 50%", "EZ pauschal": "Erziehungszeit pauschal", "Sonstige": "Sonstige Ausfallzeiten" } return display_names.get(event_type, event_type) @staticmethod def calculate_accounted_time(entry: CalendarEntry) -> str: """Calculate the accounted time for an entry based on its type and corrected dates""" if not entry.corrected_start_date or not entry.corrected_end_date: return "" start_dt = entry.corrected_start_date end_dt = entry.corrected_end_date if end_dt < start_dt: return "" if entry.keyword == "Sonstige": # For "Sonstige", show days delta_days = DateService.calculate_days_between(start_dt, end_dt) return f"{delta_days} Tage" else: # For EZ types, show months total_months = DateService.calculate_months_between(start_dt, end_dt) if entry.keyword == "EZ 50%": # Half-time projects count as half months total_months = (total_months + 1) // 2 # Round up return f"{total_months} Monate" @staticmethod def should_hide_end_date_input(event_type: str) -> bool: """Determine if end date input should be hidden for this event type""" return event_type == "EZ pauschal" @staticmethod def get_event_type_description(event_type: str) -> str: """Get description for event type""" descriptions = { "EZ 100%": "Vollzeit Erziehungszeit - vollständige Unterbrechung der Arbeit", "EZ 50%": "Teilzeit Erziehungszeit - 50% Arbeitszeit", "EZ pauschal": "Pauschale Erziehungszeit - automatisch 2 Jahre", "Sonstige": "Andere Ausfallzeiten wie Krankheit, Weiterbildung, etc." } return descriptions.get(event_type, "") @staticmethod def get_processing_order() -> List[str]: """Get the order in which event types should be processed""" return ["EZ 100%", "EZ 50%", "EZ pauschal", "Sonstige"] @staticmethod def is_full_time_event(event_type: str) -> bool: """Check if event type represents full-time absence""" return event_type in ["EZ 100%", "EZ pauschal"] @staticmethod def is_part_time_event(event_type: str) -> bool: """Check if event type represents part-time absence""" return event_type == "EZ 50%" @staticmethod def is_other_event(event_type: str) -> bool: """Check if event type represents other absence""" return event_type == "Sonstige"