+ def get_steps(self, db_conn: DatabaseConnection, external_owner:
+ Process | None = None) -> dict[int, dict[str, object]]:
+ """Return tree of depended-on explicit and implicit ProcessSteps."""
+
+ def make_node(step: ProcessStep) -> dict[str, object]:
+ is_explicit = False
+ if external_owner is not None:
+ is_explicit = step.owner_id == external_owner.id_
+ process = self.__class__.by_id(db_conn, step.step_process_id)
+ step_steps = process.get_steps(db_conn, external_owner)
+ return {'process': process, 'parent_id': step.parent_step_id,
+ 'is_explicit': is_explicit, 'steps': step_steps}
+
+ def walk_steps(node_id: int, node: dict[str, Any]) -> None:
+ explicit_children = [s for s in self.explicit_steps
+ if s.parent_step_id == node_id]
+ for child in explicit_children:
+ node['steps'][child.id_] = make_node(child)
+ node['seen'] = node_id in seen_step_ids
+ seen_step_ids.add(node_id)
+ for id_, step in node['steps'].items():
+ walk_steps(id_, step)
+
+ steps: dict[int, dict[str, object]] = {}
+ seen_step_ids: Set[int] = set()
+ if external_owner is None:
+ external_owner = self
+ for step in [s for s in self.explicit_steps
+ if s.parent_step_id is None]:
+ assert step.id_ is not None # for mypy
+ steps[step.id_] = make_node(step)
+ for step_id, step_node in steps.items():
+ walk_steps(step_id, step_node)
+ return steps
+
+ def set_conditions(self, db_conn: DatabaseConnection, ids: list[int],
+ trgt: str = 'conditions') -> None:
+ """Set self.[target] to Conditions identified by ids."""
+ trgt_list = getattr(self, trgt)
+ while len(trgt_list) > 0:
+ trgt_list.pop()
+ for id_ in ids:
+ trgt_list += [Condition.by_id(db_conn, id_)]