From b0758d1c63db38867ef12ee89317524a7436129d Mon Sep 17 00:00:00 2001
From: Christian Heller <c.heller@plomlompom.de>
Date: Sat, 18 May 2024 07:01:07 +0200
Subject: [PATCH] Add Todo.effort.

---
 migrations/2_add_Todo_effort.sql      | 1 +
 migrations/{init_1.sql => init_2.sql} | 1 +
 plomtask/db.py                        | 2 +-
 plomtask/http.py                      | 5 +++++
 plomtask/todos.py                     | 6 ++++--
 templates/day.html                    | 1 +
 templates/todo.html                   | 5 +++++
 7 files changed, 18 insertions(+), 3 deletions(-)
 create mode 100644 migrations/2_add_Todo_effort.sql
 rename migrations/{init_1.sql => init_2.sql} (99%)

diff --git a/migrations/2_add_Todo_effort.sql b/migrations/2_add_Todo_effort.sql
new file mode 100644
index 0000000..0506431
--- /dev/null
+++ b/migrations/2_add_Todo_effort.sql
@@ -0,0 +1 @@
+ALTER TABLE todos ADD COLUMN effort REAL;
diff --git a/migrations/init_1.sql b/migrations/init_2.sql
similarity index 99%
rename from migrations/init_1.sql
rename to migrations/init_2.sql
index c30121f..17e2db5 100644
--- a/migrations/init_1.sql
+++ b/migrations/init_2.sql
@@ -108,6 +108,7 @@ CREATE TABLE todos (
     is_done BOOLEAN NOT NULL,
     day TEXT NOT NULL,
     comment TEXT NOT NULL DEFAULT "",
+    effort REAL,
     FOREIGN KEY (process) REFERENCES processes(id),
     FOREIGN KEY (day) REFERENCES days(id)
 );
diff --git a/plomtask/db.py b/plomtask/db.py
index 7962eab..0e7df15 100644
--- a/plomtask/db.py
+++ b/plomtask/db.py
@@ -7,7 +7,7 @@ from sqlite3 import connect as sql_connect, Cursor, Row
 from typing import Any, Self, TypeVar, Generic
 from plomtask.exceptions import HandledException, NotFoundException
 
-EXPECTED_DB_VERSION = 1
+EXPECTED_DB_VERSION = 2
 MIGRATIONS_DIR = 'migrations'
 FILENAME_DB_SCHEMA = f'init_{EXPECTED_DB_VERSION}.sql'
 PATH_DB_SCHEMA = f'{MIGRATIONS_DIR}/{FILENAME_DB_SCHEMA}'
diff --git a/plomtask/http.py b/plomtask/http.py
index c16fddd..d76ac05 100644
--- a/plomtask/http.py
+++ b/plomtask/http.py
@@ -262,11 +262,14 @@ class TaskHandler(BaseHTTPRequestHandler):
                 todo.save(self.conn)
         done_ids = self.form_data.get_all_int('done')
         comments = self.form_data.get_all_str('comment')
+        efforts = self.form_data.get_all_str('effort')
         for i, todo_id in enumerate(self.form_data.get_all_int('todo_id')):
             todo = Todo.by_id(self.conn, todo_id)
             todo.is_done = todo_id in done_ids
             if len(comments) > 0:
                 todo.comment = comments[i]
+            if len(efforts) > 0:
+                todo.effort = float(efforts[i]) if efforts[i] else None
             todo.save(self.conn)
             for condition in todo.enables:
                 condition.save(self.conn)
@@ -293,6 +296,8 @@ class TaskHandler(BaseHTTPRequestHandler):
                 continue
             child = Todo.by_id(self.conn, child_id)
             todo.add_child(child)
+        effort = self.form_data.get_str('effort', ignore_strict=True)
+        todo.effort = float(effort) if effort else None
         todo.set_conditions(self.conn, self.form_data.get_all_int('condition'))
         todo.set_enables(self.conn, self.form_data.get_all_int('enables'))
         todo.set_disables(self.conn, self.form_data.get_all_int('disables'))
diff --git a/plomtask/todos.py b/plomtask/todos.py
index 0313e55..7cbe989 100644
--- a/plomtask/todos.py
+++ b/plomtask/todos.py
@@ -23,7 +23,7 @@ class Todo(BaseModel[int], ConditionsRelations):
     """Individual actionable."""
     # pylint: disable=too-many-instance-attributes
     table_name = 'todos'
-    to_save = ['process_id', 'is_done', 'date', 'comment']
+    to_save = ['process_id', 'is_done', 'date', 'comment', 'effort']
     to_save_relations = [('todo_conditions', 'todo', 'conditions'),
                          ('todo_enables', 'todo', 'enables'),
                          ('todo_disables', 'todo', 'disables'),
@@ -32,7 +32,8 @@ class Todo(BaseModel[int], ConditionsRelations):
 
     # pylint: disable=too-many-arguments
     def __init__(self, id_: int | None, process: Process,
-                 is_done: bool, date: str, comment: str = '') -> None:
+                 is_done: bool, date: str, comment: str = '',
+                 effort: None | float = None) -> None:
         super().__init__(id_)
         if process.id_ is None:
             raise NotFoundException('Process of Todo without ID (not saved?)')
@@ -40,6 +41,7 @@ class Todo(BaseModel[int], ConditionsRelations):
         self._is_done = is_done
         self.date = date
         self.comment = comment
+        self.effort = effort
         self.children: list[Todo] = []
         self.parents: list[Todo] = []
         self.conditions: list[Condition] = []
diff --git a/templates/day.html b/templates/day.html
index 8929058..ac0a64a 100644
--- a/templates/day.html
+++ b/templates/day.html
@@ -41,6 +41,7 @@ td.todo_line {
 
 <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>
+<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">
 {% 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 %}
diff --git a/templates/todo.html b/templates/todo.html
index 71f2e1b..6817cb9 100644
--- a/templates/todo.html
+++ b/templates/todo.html
@@ -23,6 +23,11 @@
 <td><input type="checkbox" name="done" {% if todo.is_done %}checked {% endif %} {% if not todo.is_doable %}disabled {% endif %}/><br /></td>
 </tr>
 
+<tr>
+<th>effort</th>
+<td><input type="number" name="effort" step=0.1 size=5 placeholder={{todo.process.effort.newest }} value={{ todo.effort }} /><br /></td>
+</tr>
+
 <tr>
 <th>comment</th>
 <td><input name="comment" value="{{todo.comment|e}}"/></td>
-- 
2.30.2