home · contact · privacy
Minor reorganization of GET handlers code.
[plomtask] / plomtask / days.py
index 0815b9bde6e515381f644fd33a120b880b533abb..23201301bbe792042a361d3f970415c622d80627 100644 (file)
@@ -1,5 +1,7 @@
 """Collecting Day and date-related items."""
 from __future__ import annotations
 """Collecting Day and date-related items."""
 from __future__ import annotations
+from typing import Any
+from sqlite3 import Row
 from datetime import datetime, timedelta
 from plomtask.db import DatabaseConnection, BaseModel
 from plomtask.todos import Todo
 from datetime import datetime, timedelta
 from plomtask.db import DatabaseConnection, BaseModel
 from plomtask.todos import Todo
@@ -10,17 +12,44 @@ class Day(BaseModel[str]):
     """Individual days defined by their dates."""
     table_name = 'days'
     to_save = ['comment']
     """Individual days defined by their dates."""
     table_name = 'days'
     to_save = ['comment']
+    add_to_dict = ['todos']
+    can_create_by_id = True
 
     def __init__(self, date: str, comment: str = '') -> None:
         id_ = valid_date(date)
         super().__init__(id_)
         self.datetime = datetime.strptime(self.date, DATE_FORMAT)
         self.comment = comment
 
     def __init__(self, date: str, comment: str = '') -> None:
         id_ = valid_date(date)
         super().__init__(id_)
         self.datetime = datetime.strptime(self.date, DATE_FORMAT)
         self.comment = comment
-        self.calendarized_todos: list[Todo] = []
+        self.todos: list[Todo] = []
 
     def __lt__(self, other: Day) -> bool:
         return self.date < other.date
 
 
     def __lt__(self, other: Day) -> bool:
         return self.date < other.date
 
+    @classmethod
+    def from_table_row(cls, db_conn: DatabaseConnection, row: Row | list[Any]
+                       ) -> Day:
+        """Make from DB row, with linked Todos."""
+        day = super().from_table_row(db_conn, row)
+        assert isinstance(day.id_, str)
+        day.todos = Todo.by_date(db_conn, day.id_)
+        return day
+
+    @classmethod
+    def by_id(cls, db_conn: DatabaseConnection, id_: str) -> Day:
+        """Extend BaseModel.by_id
+
+        Checks Todo.days_to_update if we need to a retrieved Day's .todos,
+        and also ensures we're looking for proper dates and not strings like
+        "yesterday" by enforcing the valid_date translation.
+        """
+        assert isinstance(id_, str)
+        possibly_translated_date = valid_date(id_)
+        day = super().by_id(db_conn, possibly_translated_date)
+        if day.id_ in Todo.days_to_update:
+            Todo.days_to_update.remove(day.id_)
+            day.todos = Todo.by_date(db_conn, day.id_)
+        return day
+
     @classmethod
     def by_date_range_filled(cls, db_conn: DatabaseConnection,
                              start: str, end: str) -> list[Day]:
     @classmethod
     def by_date_range_filled(cls, db_conn: DatabaseConnection,
                              start: str, end: str) -> list[Day]:
@@ -85,7 +114,15 @@ class Day(BaseModel[str]):
         next_datetime = self.datetime + timedelta(days=1)
         return next_datetime.strftime(DATE_FORMAT)
 
         next_datetime = self.datetime + timedelta(days=1)
         return next_datetime.strftime(DATE_FORMAT)
 
-    def collect_calendarized_todos(self, db_conn: DatabaseConnection) -> None:
-        """Fill self.calendarized_todos."""
-        self.calendarized_todos = [t for t in Todo.by_date(db_conn, self.date)
-                                   if t.calendarize]
+    @property
+    def calendarized_todos(self) -> list[Todo]:
+        """Return only those of self.todos that have .calendarize set."""
+        return [t for t in self.todos if t.calendarize]
+
+    @property
+    def total_effort(self) -> float:
+        """"Sum all .performed_effort of self.todos."""
+        total_effort = 0.0
+        for todo in self.todos:
+            total_effort += todo.performed_effort
+        return total_effort