home · contact · privacy
For Todos, on Save check for auto-deletion by .effort < 0, and on removal check if...
authorChristian Heller <c.heller@plomlompom.de>
Mon, 20 May 2024 23:50:36 +0000 (01:50 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Mon, 20 May 2024 23:50:36 +0000 (01:50 +0200)
plomtask/todos.py
templates/day.html
tests/todos.py

index 0fea23445ac1881a18ea87eca95cba7f03510f95..b3d50e9d4942c57cb5b4ef16892401df4eb7f6f7 100644 (file)
@@ -105,6 +105,15 @@ class Todo(BaseModel[int], ConditionsRelations):
                 return False
         return True
 
                 return False
         return True
 
+    @property
+    def is_deletable(self) -> bool:
+        """Decide whether self be deletable (not if preserve-worthy values)."""
+        if self.comment:
+            return False
+        if self.effort and self.effort >= 0:
+            return False
+        return True
+
     @property
     def process_id(self) -> int | str | None:
         """Needed for super().save to save Processes as attributes."""
     @property
     def process_id(self) -> int | str | None:
         """Needed for super().save to save Processes as attributes."""
@@ -201,8 +210,17 @@ class Todo(BaseModel[int], ConditionsRelations):
         self.children.remove(child)
         child.parents.remove(self)
 
         self.children.remove(child)
         child.parents.remove(self)
 
+    def save(self, db_conn: DatabaseConnection) -> None:
+        """On save calls, also check if auto-deletion by effort < 0."""
+        if self.effort and self.effort < 0 and self.is_deletable:
+            self.remove(db_conn)
+            return
+        super().save(db_conn)
+
     def remove(self, db_conn: DatabaseConnection) -> None:
         """Remove from DB, including relations."""
     def remove(self, db_conn: DatabaseConnection) -> None:
         """Remove from DB, including relations."""
+        if not self.is_deletable:
+            raise HandledException('Cannot remove non-deletable Todo.')
         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:
index 4c77705b514b6aec0821b336fea107fcaea3cd1f..9af375419911c05d44a0fc99dcdc3f63d2e821bd 100644 (file)
@@ -33,15 +33,22 @@ td.todo_line {
 {% macro show_node_undone(node, indent) %}
 {% if not node.todo.is_done %}
 <tr>
 {% macro show_node_undone(node, indent) %}
 {% if not node.todo.is_done %}
 <tr>
+{% if not node.seen %}
 <input type="hidden" name="todo_id" value="{{node.todo.id_}}" />
 <input type="hidden" name="todo_id" value="{{node.todo.id_}}" />
+{% endif %}
 
 {% for condition in conditions_present %}
 <td class="cond_line_{{loop.index0 % 3}} {% if not condition.is_active %}min_width{% endif %}">{% if condition in node.todo.conditions %}{% if not condition.is_active %}O{% endif %}{% endif %}</td>
 {% endfor %}
 
 <td class="todo_line">-&gt;</td>
 
 {% for condition in conditions_present %}
 <td class="cond_line_{{loop.index0 % 3}} {% if not condition.is_active %}min_width{% endif %}">{% if condition in node.todo.conditions %}{% if not condition.is_active %}O{% endif %}{% endif %}</td>
 {% endfor %}
 
 <td class="todo_line">-&gt;</td>
-<td class="todo_line"><input name="done" type="checkbox" value="{{node.todo.id_}}" {% if node.todo.is_done %}checked disabled{% endif %} {% if not node.todo.is_doable %}disabled{% endif %}/></td>
+{% if node.seen %}
+<td class="todo_line"></td>
+<td class="todo_line">{% if node.todo.effort %}{{ node.todo.effort }}{% endif %}</td>
+{% else %}
+<td class="todo_line"><input name="done" type="checkbox" value="{{node.todo.id_}}" {% if not node.todo.is_doable %}disabled{% endif %}/></td>
 <td class="todo_line"><input name="effort" type="number" step=0.1 size=5 placeholder={{node.todo.process.effort.newest }} value={{node.todo.effort}} /></td>
 <td class="todo_line"><input name="effort" type="number" step=0.1 size=5 placeholder={{node.todo.process.effort.newest }} value={{node.todo.effort}} /></td>
+{% endif %}
 <td class="todo_line">
 {% for i in range(indent) %}&nbsp; {% endfor %} +
 {% if node.seen %}({% endif %}<a href="todo?id={{node.todo.id_}}">{{node.todo.process.title.newest|e}}</a>{% if node.seen %}){% endif %}
 <td class="todo_line">
 {% for i in range(indent) %}&nbsp; {% endfor %} +
 {% if node.seen %}({% endif %}<a href="todo?id={{node.todo.id_}}">{{node.todo.process.title.newest|e}}</a>{% if node.seen %}){% endif %}
@@ -52,7 +59,13 @@ td.todo_line {
 <td class="cond_line_{{(conditions_present|length - loop.index) % 3}} {% if condition in node.todo.enables or condition in node.todo.disables %}min_width{% endif %}">{% if condition in node.todo.enables %}+{% elif condition in node.todo.disables %}!{% endif %}</td>
 {% endfor %}
 
 <td class="cond_line_{{(conditions_present|length - loop.index) % 3}} {% if condition in node.todo.enables or condition in node.todo.disables %}min_width{% endif %}">{% if condition in node.todo.enables %}+{% elif condition in node.todo.disables %}!{% endif %}</td>
 {% endfor %}
 
-<td><input name="comment" value="{{node.todo.comment|e}}" /></td>
+<td>
+{% if node.seen %}
+{{node.todo.comment|e}}
+{% else %}
+<input name="comment" value="{{node.todo.comment|e}}" />
+{% endif %}
+</td>
 
 </tr>
 {% endif %}
 
 </tr>
 {% endif %}
index 059bd9f4fb47fac79a710b8421995f3f4b869da1..6ce5d6955be068355285c1532e12cd3ffb9e4204 100644 (file)
@@ -218,6 +218,26 @@ class TestsWithDB(TestCaseWithDB):
             Todo.by_id(self.db_conn, todo_1.id_)
         self.assertEqual(todo_0.children, [])
         self.assertEqual(todo_2.parents, [])
             Todo.by_id(self.db_conn, todo_1.id_)
         self.assertEqual(todo_0.children, [])
         self.assertEqual(todo_2.parents, [])
+        todo_2.comment = 'foo'
+        with self.assertRaises(HandledException):
+            todo_2.remove(self.db_conn)
+        todo_2.comment = ''
+        todo_2.effort = 5
+        with self.assertRaises(HandledException):
+            todo_2.remove(self.db_conn)
+
+    def test_Todo_autoremoval(self) -> None:
+        """"Test automatic removal for Todo.effort < 0."""
+        todo_1 = Todo(None, self.proc, False, self.date1)
+        todo_1.save(self.db_conn)
+        todo_1.comment = 'foo'
+        todo_1.effort = -0.1
+        todo_1.save(self.db_conn)
+        Todo.by_id(self.db_conn, todo_1.id_)
+        todo_1.comment = ''
+        todo_1.save(self.db_conn)
+        with self.assertRaises(NotFoundException):
+            Todo.by_id(self.db_conn, todo_1.id_)
 
 
 class TestsWithServer(TestCaseWithServer):
 
 
 class TestsWithServer(TestCaseWithServer):