home · contact · privacy
Overhaul as_dict generation to avoid endless nesting of objects.
[plomtask] / plomtask / todos.py
index af45f720ca6e2011fb52bd5af18582a2feca76f1..705bd725e2ff662ab4f9f2e370e61169a413ff03 100644 (file)
@@ -1,7 +1,7 @@
 """Actionables."""
 from __future__ import annotations
 from dataclasses import dataclass
 """Actionables."""
 from __future__ import annotations
 from dataclasses import dataclass
-from typing import Any
+from typing import Any, Set
 from sqlite3 import Row
 from plomtask.db import DatabaseConnection, BaseModel
 from plomtask.processes import Process, ProcessStepsNode
 from sqlite3 import Row
 from plomtask.db import DatabaseConnection, BaseModel
 from plomtask.processes import Process, ProcessStepsNode
@@ -23,6 +23,7 @@ class TodoNode:
 class Todo(BaseModel[int], ConditionsRelations):
     """Individual actionable."""
     # pylint: disable=too-many-instance-attributes
 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']
     table_name = 'todos'
     to_save = ['process_id', 'is_done', 'date', 'comment', 'effort',
                'calendarize']
@@ -33,6 +34,9 @@ class Todo(BaseModel[int], ConditionsRelations):
                          ('todo_children', 'parent', 'children', 0),
                          ('todo_children', 'child', 'parents', 1)]
     to_search = ['comment']
                          ('todo_children', 'parent', 'children', 0),
                          ('todo_children', 'child', 'parents', 1)]
     to_search = ['comment']
+    days_to_update: Set[str] = set()
+    children: list[Todo]
+    parents: list[Todo]
 
     # pylint: disable=too-many-arguments
     def __init__(self, id_: int | None,
 
     # pylint: disable=too-many-arguments
     def __init__(self, id_: int | None,
@@ -50,8 +54,8 @@ class Todo(BaseModel[int], ConditionsRelations):
         self.date = valid_date(date)
         self.comment = comment
         self.effort = effort
         self.date = valid_date(date)
         self.comment = comment
         self.effort = effort
-        self.children: list[Todo] = []
-        self.parents: list[Todo] = []
+        self.children = []
+        self.parents = []
         self.calendarize = calendarize
         if not self.id_:
             self.calendarize = self.process.calendarize
         self.calendarize = calendarize
         if not self.id_:
             self.calendarize = self.process.calendarize
@@ -128,11 +132,9 @@ class Todo(BaseModel[int], ConditionsRelations):
         assert isinstance(todo.id_, int)
         for t_id in db_conn.column_where('todo_children', 'child',
                                          'parent', todo.id_):
         assert isinstance(todo.id_, int)
         for t_id in db_conn.column_where('todo_children', 'child',
                                          'parent', todo.id_):
-            # pylint: disable=no-member
             todo.children += [cls.by_id(db_conn, t_id)]
         for t_id in db_conn.column_where('todo_children', 'parent',
                                          'child', todo.id_):
             todo.children += [cls.by_id(db_conn, t_id)]
         for t_id in db_conn.column_where('todo_children', 'parent',
                                          'child', todo.id_):
-            # pylint: disable=no-member
             todo.parents += [cls.by_id(db_conn, t_id)]
         for name in ('conditions', 'blockers', 'enables', 'disables'):
             table = f'todo_{name}'
             todo.parents += [cls.by_id(db_conn, t_id)]
         for name in ('conditions', 'blockers', 'enables', 'disables'):
             table = f'todo_{name}'
@@ -258,7 +260,7 @@ class Todo(BaseModel[int], ConditionsRelations):
         """Return sum of performed efforts of self and all descendants."""
 
         def walk_tree(node: Todo) -> float:
         """Return sum of performed efforts of self and all descendants."""
 
         def walk_tree(node: Todo) -> float:
-            local_effort = 0
+            local_effort = 0.0
             for child in node.children:
                 local_effort += walk_tree(child)
             return node.performed_effort + local_effort
             for child in node.children:
                 local_effort += walk_tree(child)
             return node.performed_effort + local_effort
@@ -296,12 +298,17 @@ class Todo(BaseModel[int], ConditionsRelations):
         if self.effort and self.effort < 0 and self.is_deletable:
             self.remove(db_conn)
             return
         if self.effort and self.effort < 0 and self.is_deletable:
             self.remove(db_conn)
             return
+        if self.id_ is None:
+            self.__class__.days_to_update.add(self.date)
         super().save(db_conn)
         super().save(db_conn)
+        for condition in self.enables + self.disables + self.conditions:
+            condition.save(db_conn)
 
     def remove(self, db_conn: DatabaseConnection) -> None:
         """Remove from DB, including relations."""
         if not self.is_deletable:
             raise HandledException('Cannot remove non-deletable Todo.')
 
     def remove(self, db_conn: DatabaseConnection) -> None:
         """Remove from DB, including relations."""
         if not self.is_deletable:
             raise HandledException('Cannot remove non-deletable Todo.')
+        self.__class__.days_to_update.add(self.date)
         children_to_remove = self.children[:]
         parents_to_remove = self.parents[:]
         for child in children_to_remove:
         children_to_remove = self.children[:]
         parents_to_remove = self.parents[:]
         for child in children_to_remove: