X-Git-Url: https://plomlompom.com/repos/foo.html?a=blobdiff_plain;f=plomtask%2Ftodos.py;h=008f7a275ab42aa9bbbcfed1933c81f491854211;hb=81e1ac998001bedd8a739e6458c7ed30e474c0da;hp=69a19c94f1e5b172dd14be0fa72fc4a4e7752fe1;hpb=80025e0b2d278a44852b6a397184d1f71c2075fe;p=plomtask
diff --git a/plomtask/todos.py b/plomtask/todos.py
index 69a19c9..008f7a2 100644
--- a/plomtask/todos.py
+++ b/plomtask/todos.py
@@ -23,6 +23,7 @@ class TodoNode:
class Todo(BaseModel[int], ConditionsRelations):
"""Individual actionable."""
# pylint: disable=too-many-instance-attributes
+ # pylint: disable=too-many-public-methods
table_name = 'todos'
to_save = ['process_id', 'is_done', 'date', 'comment', 'effort',
'calendarize']
@@ -91,6 +92,8 @@ class Todo(BaseModel[int], ConditionsRelations):
sub_step_nodes = list(step_node.steps.values())
sub_step_nodes.sort(key=key_order_func)
for sub_node in sub_step_nodes:
+ if sub_node.is_suppressed:
+ continue
n_slots = len([n for n in sub_step_nodes
if n.process == sub_node.process])
filled_slots = len([t for t in satisfier.children
@@ -107,6 +110,8 @@ class Todo(BaseModel[int], ConditionsRelations):
todo.save(db_conn)
steps_tree = process.get_steps(db_conn)
for step_node in steps_tree.values():
+ if step_node.is_suppressed:
+ continue
todo.add_child(walk_steps(todo, step_node))
todo.save(db_conn)
return todo
@@ -150,6 +155,16 @@ class Todo(BaseModel[int], ConditionsRelations):
"""Collect all Todos for Day of date."""
return cls.by_date_range(db_conn, (date, date))
+ @classmethod
+ def total_effort_at_date(cls, db_conn: DatabaseConnection, date: str
+ ) -> float:
+ """Sum all .performed_effort of Todos at Day of date."""
+ total_effort = 0.0
+ days_todos = cls.by_date(db_conn, date)
+ for todo in days_todos:
+ total_effort += todo.performed_effort
+ return total_effort
+
@property
def is_doable(self) -> bool:
"""Decide whether .is_done settable based on children, Conditions."""
@@ -173,6 +188,15 @@ class Todo(BaseModel[int], ConditionsRelations):
return False
return True
+ @property
+ def performed_effort(self) -> float:
+ """Return performed effort, i.e. self.effort or default if done.."""
+ if self.effort is not None:
+ return self.effort
+ if self.is_done:
+ return self.effort_then
+ return 0
+
@property
def process_id(self) -> int | str | None:
"""Needed for super().save to save Processes as attributes."""
@@ -240,6 +264,18 @@ class Todo(BaseModel[int], ConditionsRelations):
return make_node(self)
+ @property
+ def tree_effort(self) -> float:
+ """Return sum of performed efforts of self and all descendants."""
+
+ def walk_tree(node: Todo) -> float:
+ local_effort = 0.0
+ for child in node.children:
+ local_effort += walk_tree(child)
+ return node.performed_effort + local_effort
+
+ return walk_tree(self)
+
def add_child(self, child: Todo) -> None:
"""Add child to self.children, avoid recursion, update parenthoods."""