diff --git a/backend/tasks/admin.py b/backend/tasks/admin.py index 5c5bbb3..cabf594 100644 --- a/backend/tasks/admin.py +++ b/backend/tasks/admin.py @@ -7,8 +7,9 @@ class TagAdmin(admin.ModelAdmin): @admin.register(Todo) class TodoAdmin(admin.ModelAdmin): - list_display = ['title', 'list_board', 'is_active', 'priority'] - list_filter = ['list_board', 'is_active', 'priority'] + list_display = ['title', 'list_board', 'is_active', 'priority', 'completed', 'completion_date'] + list_filter = ['list_board', 'is_active', 'priority', 'completed'] + exclude = ['completion_date'] @admin.register(RecurrenceTask) class RecurrenceTaskAdmin(admin.ModelAdmin): diff --git a/backend/tasks/migrations/0018_alter_habit_creation_date_and_more.py b/backend/tasks/migrations/0018_alter_habit_creation_date_and_more.py new file mode 100644 index 0000000..bbb1714 --- /dev/null +++ b/backend/tasks/migrations/0018_alter_habit_creation_date_and_more.py @@ -0,0 +1,29 @@ +# Generated by Django 4.2.6 on 2023-11-20 14:58 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('tasks', '0017_alter_recurrencetask_list_board_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='habit', + name='creation_date', + field=models.DateTimeField(default=django.utils.timezone.now, editable=False), + ), + migrations.AlterField( + model_name='recurrencetask', + name='creation_date', + field=models.DateTimeField(default=django.utils.timezone.now, editable=False), + ), + migrations.AlterField( + model_name='todo', + name='creation_date', + field=models.DateTimeField(default=django.utils.timezone.now, editable=False), + ), + ] diff --git a/backend/tasks/migrations/0019_alter_habit_creation_date_and_more.py b/backend/tasks/migrations/0019_alter_habit_creation_date_and_more.py new file mode 100644 index 0000000..0ba0307 --- /dev/null +++ b/backend/tasks/migrations/0019_alter_habit_creation_date_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 4.2.6 on 2023-11-20 15:02 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tasks', '0018_alter_habit_creation_date_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='habit', + name='creation_date', + field=models.DateTimeField(auto_now_add=True), + ), + migrations.AlterField( + model_name='recurrencetask', + name='creation_date', + field=models.DateTimeField(auto_now_add=True), + ), + migrations.AlterField( + model_name='todo', + name='creation_date', + field=models.DateTimeField(auto_now_add=True), + ), + ] diff --git a/backend/tasks/migrations/0020_recurrencetask_completion_date_todo_completion_date.py b/backend/tasks/migrations/0020_recurrencetask_completion_date_todo_completion_date.py new file mode 100644 index 0000000..f1ffe13 --- /dev/null +++ b/backend/tasks/migrations/0020_recurrencetask_completion_date_todo_completion_date.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.6 on 2023-11-20 15:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tasks', '0019_alter_habit_creation_date_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='recurrencetask', + name='completion_date', + field=models.DateTimeField(null=True), + ), + migrations.AddField( + model_name='todo', + name='completion_date', + field=models.DateTimeField(null=True), + ), + ] diff --git a/backend/tasks/models.py b/backend/tasks/models.py index fc29fe6..c848e00 100644 --- a/backend/tasks/models.py +++ b/backend/tasks/models.py @@ -1,5 +1,6 @@ from django.db import models from django.conf import settings +from django.utils import timezone from boards.models import ListBoard, Board @@ -25,6 +26,7 @@ class Task(models.Model): :param challenge: Associated challenge (optional). :param fromSystem: A boolean field indicating if the task is from System. :param creation_date: Creation date of the task. + :param last_update: Last update date of the task. """ class Difficulty(models.IntegerChoices): EASY = 1, 'Easy' @@ -59,6 +61,7 @@ class Todo(Task): :param end_event: End date and time of the task. :param google_calendar_id: The Google Calendar ID of the task. :param completed: A boolean field indicating whether the task is completed. + :param completion_date: The date and time when the task is completed. :param priority: The priority of the task (range: 1 to 4). """ class EisenhowerMatrix(models.IntegerChoices): @@ -74,8 +77,17 @@ class Todo(Task): end_event = models.DateTimeField(null=True) google_calendar_id = models.CharField(max_length=255, null=True, blank=True) completed = models.BooleanField(default=False) + completion_date = models.DateTimeField(null=True) priority = models.PositiveSmallIntegerField(choices=EisenhowerMatrix.choices, default=EisenhowerMatrix.NOT_IMPORTANT_NOT_URGENT) + def save(self, *args, **kwargs): + if self.completed and not self.completion_date: + self.completion_date = timezone.now() + elif not self.completed: + self.completion_date = None + + super().save(*args, **kwargs) + def __str__(self): return self.title @@ -90,6 +102,7 @@ class RecurrenceTask(Task): :param start_event: Start date and time of the task. :param end_event: End date and time of the task. :param completed: A boolean field indicating whether the task is completed. + :param completion_date: The date and time when the task is completed. :param parent_task: The parent task of the subtask. """ list_board = models.ForeignKey(ListBoard, on_delete=models.CASCADE, null=True, default=1) @@ -99,8 +112,17 @@ class RecurrenceTask(Task): start_event = models.DateTimeField(null=True) end_event = models.DateTimeField(null=True) completed = models.BooleanField(default=False) + completion_date = models.DateTimeField(null=True) parent_task = models.ForeignKey("self", on_delete=models.CASCADE, null=True) + def save(self, *args, **kwargs): + if self.completed and not self.completion_date: + self.completion_date = timezone.now() + elif not self.completed: + self.completion_date = None + + super().save(*args, **kwargs) + def __str__(self) -> str: return f"{self.title} ({self.recurrence_rule})"