The list_milestones tool was only returning start milestones (TT_Mile) and missing all finish milestones. P6 uses two task types for milestones: - TT_Mile = Start Milestone - TT_FinMile = Finish Milestone Changes: - Update query_milestones() to include both TT_Mile and TT_FinMile - Derive milestone_type from task_type when not explicitly set: - TT_Mile -> 'start' - TT_FinMile -> 'finish' - Add unit tests for milestone_type derivation from task_type This fixes the E-J Electric schedule returning 5 milestones instead of 62.
63 lines
2.5 KiB
Python
63 lines
2.5 KiB
Python
"""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,
|
|
}
|