From 0f70b22c0f0e2983edc0a60309f49636db75da6b Mon Sep 17 00:00:00 2001
From: Christian Heller <c.heller@plomlompom.de>
Date: Sun, 10 Dec 2023 18:43:56 +0100
Subject: [PATCH] Improve todo accounting.

---
 todo.py | 66 ++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 39 insertions(+), 27 deletions(-)

diff --git a/todo.py b/todo.py
index 4449232..8da5f9e 100644
--- a/todo.py
+++ b/todo.py
@@ -22,13 +22,15 @@ td { border: 1px solid black; }
 
 form_footer = '\n</form>'
 
-old_days_tmpl = """
+archived_days_tmpl = """
 <table>
-{% for date, day in db.old_days.items() | sort(reverse=True) %}
+{% for date, day in db.days.items() | sort(reverse=True) %}
+{% if day.archived %}
 <tr><td>{{ date }} ({{ day.todos_sum |round(2) }}) {{ day.comment|e }} <input type="submit" name="edit_{{date}}" value="edit" /></td></tr>
 {% for task, todo in day.todos.items() | sort(attribute='1.title', reverse=True)  %}
 <tr><td>{{ todo.title }}</td><td>{% if todo.done %}✓{% endif %}</td><td>{{ todo.weight }}</td></tr>
 {% endfor %}
+{% endif %}
 {% endfor %}
 </table>
 """
@@ -141,6 +143,7 @@ class Day:
         self.db = db
         self.todos = todos 
         self.comment = comment
+        self.archived = True 
 
     @classmethod
     def from_dict(cls, db, d):
@@ -207,16 +210,19 @@ class TodoDB(PlomDB):
         self.t_filter_and = t_filter_and
         self.t_filter_not = t_filter_not
         self.hide_unchosen = hide_unchosen 
-        self.old_days = {}
+        self.days = {}
         self.tasks = {}
-        self.reset_day()
         self.t_tags = set() 
         super().__init__(db_path)
+        if not hasattr(self, 'selected_day_date'):
+            self.switch_to_day()
 
     def read_db_file(self, f):
         d = json.load(f)
-        self.selected_day = self.add_day(d['selected_day'])
         self.selected_day_date = d['selected_day_date'] 
+        for date, day_dict in d['days'].items():
+            self.days[date] = self.add_day(dict_source=day_dict)
+        self.selected_day.archived = False 
         for uuid, t_dict in d['tasks'].items():
             t = self.add_task(id_=uuid, dict_source=t_dict)
             t.visible = len([tag for tag in self.t_filter_and if not tag in t.tags]) == 0\
@@ -224,40 +230,34 @@ class TodoDB(PlomDB):
                     and ((not self.hide_unchosen) or uuid in self.selected_day.todos)
             for tag in t.tags:
                 self.t_tags.add(tag)
-        for date, day_dict in d['old_days'].items():
-            self.old_days[date] = self.add_day(dict_source=day_dict) # Day.from_dict(self, day_dict)
 
     def to_dict(self):
         d = {
-                'selected_day': self.selected_day.to_dict(),
                 'selected_day_date': self.selected_day_date,
                 't_filter_and': list(self.t_filter_and),
                 't_filter_not': list(self.t_filter_not),
                 'tasks': {},
-                'old_days': {}
+                'days': {}
         }
         for uuid, t in self.tasks.items():
              d['tasks'][uuid] = t.to_dict()
-        for date, day in self.old_days.items():
-            d['old_days'][date] = day.to_dict()
+        for date, day in self.days.items():
+            d['days'][date] = day.to_dict()
         return d
 
     def write(self):
         self.write_text_to_db(json.dumps(self.to_dict()))
 
-    def save_selected_day(self):
-        if self.selected_day_date in self.old_days.keys():
-            raise PlomException('cannot use same date twice')
-        self.old_days[self.selected_day_date] = self.selected_day
-
-    def reset_day(self, date=None):
+    def switch_to_day(self, date=None):
+        if self.selected_day_date in self.days.keys():
+            self.selected_day.archived = True 
         if date:
             self.selected_day_date = date 
-            self.selected_day = self.old_days[date]
-            del self.old_days[date]
         else:
             self.selected_day_date = str(datetime.now())[:10]
-            self.selected_day = self.add_day()
+            if not self.selected_day_date in self.days.keys():
+                self.days[self.selected_day_date] = self.add_day()
+        self.selected_day.archived = False 
 
     def add_task(self, id_=None, dict_source=None, return_id=False):
         t = Task.from_dict(self, dict_source) if dict_source else Task(self)
@@ -274,10 +274,14 @@ class TodoDB(PlomDB):
     def show_all(self):
         for i in range(10):
             self.add_task(id_=f'new{i}') 
-        for date, day in self.old_days.items():
+        for date, day in self.days.items():
             for task_uuid, todo in day.todos.items():
                 todo.title = self.tasks[task_uuid].title_at(date)
-        return Template(selected_day_tmpl + old_days_tmpl + form_footer).render(db=self, action=self.prefix+'/all')
+        return Template(selected_day_tmpl + archived_days_tmpl + form_footer).render(db=self, action=self.prefix+'/all')
+
+    @property
+    def selected_day(self):
+        return self.days[self.selected_day_date]
 
     def show_selected_day(self):
         return Template(selected_day_tmpl + form_footer).render(db=self, action=self.prefix+'/day')
@@ -339,19 +343,27 @@ class TodoHandler(PlomHandler):
                         done = 'done' in postvars and uuid in postvars['done']
                         day_weight = float(postvars['day_weight'][i]) if postvars['day_weight'][i] else None
                         db.selected_day.add_todo(uuid, {'done': done, 'day_weight': day_weight})
-        db.selected_day_date = postvars['selected_day_date'][0]
+
         db.selected_day.comment = postvars['comment'][0]
+        new_selected_day_date = postvars['selected_day_date'][0]
+        if new_selected_day_date != db.selected_day_date:
+            if new_selected_day_date in db.days.keys():
+                raise PlomException('cannot use same date twice')
+            else:
+                db.days[new_selected_day_date] = db.selected_day
+                del db.days[db.selected_day_date]
+                db.selected_day_date = new_selected_day_date
+
         switch_edited_day = None
-        for date in db.old_days.keys():
+        for date in db.days.keys():
             if f'edit_{date}' in postvars.keys():
                 switch_edited_day = date
                 break
         if 'archive_day' in postvars.keys() or switch_edited_day:
-            db.save_selected_day()
             if switch_edited_day:
-                db.reset_day(date) 
+                db.switch_to_day(date) 
             else:
-                db.reset_day()
+                db.switch_to_day()
         db.write()
         data = [('t_and', f) for f in db.t_filter_and] + [('t_not', f) for f in db.t_filter_not] + [('hide_unchosen', int(db.hide_unchosen))]
         encoded_params = urlencode(data)
-- 
2.30.2