"""TASK table handler.""" from xer_mcp.parser.table_handlers.base import TableHandler from xer_mcp.parser.table_handlers.project import convert_date class TaskHandler(TableHandler): """Handler for TASK table in XER files.""" @property def table_name(self) -> str: return "TASK" def parse_row(self, fields: list[str], values: list[str]) -> dict | None: """Parse a TASK row.""" if len(values) < len(fields): values = values + [""] * (len(fields) - len(values)) data = dict(zip(fields, values, strict=False)) # Parse driving_path_flag (Y/N -> bool) driving_flag = data.get("driving_path_flag", "N") driving_path = driving_flag.upper() == "Y" if driving_flag else False # Parse total_float_hr_cnt float_str = data.get("total_float_hr_cnt", "") total_float = float(float_str) if float_str else None # Parse milestone_type # First check explicit milestone_type field (MS_Start -> 'start', MS_Finish -> 'finish') # Then derive from task_type (TT_Mile -> 'start', TT_FinMile -> 'finish') raw_milestone_type = data.get("milestone_type", "") task_type = data.get("task_type", "") milestone_type = None if raw_milestone_type: if raw_milestone_type == "MS_Start": milestone_type = "start" elif raw_milestone_type == "MS_Finish": milestone_type = "finish" elif task_type == "TT_Mile": milestone_type = "start" elif task_type == "TT_FinMile": milestone_type = "finish" return { "task_id": data.get("task_id", ""), "proj_id": data.get("proj_id", ""), "wbs_id": data.get("wbs_id") or None, "task_code": data.get("task_code", ""), "task_name": data.get("task_name", ""), "task_type": data.get("task_type", ""), "status_code": data.get("status_code") or None, "target_start_date": convert_date(data.get("target_start_date")), "target_end_date": convert_date(data.get("target_end_date")), "early_start_date": convert_date(data.get("early_start_date")), "early_end_date": convert_date(data.get("early_end_date")), "act_start_date": convert_date(data.get("act_start_date")), "act_end_date": convert_date(data.get("act_end_date")), "total_float_hr_cnt": total_float, "driving_path_flag": driving_path, "milestone_type": milestone_type, }