mirror of
https://github.com/TurTaskProject/TurTaskWeb.git
synced 2025-12-19 22:14:07 +01:00
Merge branch 'main' of https://github.com/TurTaskProject/TurTaskWeb
This commit is contained in:
commit
1f9a96a867
@ -1,3 +1,103 @@
|
|||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
from django.urls import reverse
|
||||||
|
from tasks.models import Todo
|
||||||
|
from django.utils import timezone
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
# Create your tests here.
|
from tasks.tests.utils import create_test_user, login_user
|
||||||
|
|
||||||
|
class DashboardStatsAndWeeklyViewSetTests(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.user = create_test_user()
|
||||||
|
self.client = login_user(self.user)
|
||||||
|
|
||||||
|
def create_task(self, title, completed=False, completion_date=None, end_event=None):
|
||||||
|
return Todo.objects.create(
|
||||||
|
user=self.user,
|
||||||
|
title=title,
|
||||||
|
completed=completed,
|
||||||
|
completion_date=completion_date,
|
||||||
|
end_event=end_event
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_dashboard_stats_view(self):
|
||||||
|
# Create tasks for testing
|
||||||
|
self.create_task('Task 1', completed=True)
|
||||||
|
self.create_task('Task 2', end_event=timezone.now() - timedelta(days=8))
|
||||||
|
self.create_task('Task 3', end_event=timezone.now())
|
||||||
|
|
||||||
|
response = self.client.get(reverse('stats-list'))
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
self.assertEqual(response.data['completed_this_week'], 1)
|
||||||
|
self.assertEqual(response.data['tasks_assigned_this_week'], 1)
|
||||||
|
self.assertEqual(response.data['tasks_assigned_last_week'], 0)
|
||||||
|
|
||||||
|
def test_dashboard_weekly_view(self):
|
||||||
|
# Create tasks for testing
|
||||||
|
self.create_task('Task 1', completion_date=timezone.now() - timedelta(days=1))
|
||||||
|
self.create_task('Task 2', end_event=timezone.now() - timedelta(days=8))
|
||||||
|
self.create_task('Task 3', end_event=timezone.now())
|
||||||
|
|
||||||
|
response = self.client.get(reverse('weekly-list'))
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
|
||||||
|
# class DashboardStatsAPITestCase(TestCase):
|
||||||
|
# def setUp(self):
|
||||||
|
# # Create a test user
|
||||||
|
# self.user = create_test_user()
|
||||||
|
|
||||||
|
# # Create test tasks
|
||||||
|
# self.todo = Todo.objects.create(user=self.user, title='Test Todo')
|
||||||
|
# self.recurrence_task = RecurrenceTask.objects.create(user=self.user, title='Test Recurrence Task')
|
||||||
|
|
||||||
|
# # Create an API client
|
||||||
|
# self.client = APIClient()
|
||||||
|
|
||||||
|
# def test_dashboard_stats_api(self):
|
||||||
|
# # Authenticate the user
|
||||||
|
# self.client.force_authenticate(user=self.user)
|
||||||
|
|
||||||
|
# # Make a GET request to the DashboardStatsAPIView
|
||||||
|
# response = self.client.get(reverse("dashboard-stats"))
|
||||||
|
|
||||||
|
# # Assert the response status code is 200
|
||||||
|
# self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
# def test_task_completion_status_update(self):
|
||||||
|
# # Authenticate the user
|
||||||
|
# self.client.force_authenticate(user=self.user)
|
||||||
|
|
||||||
|
# # Make a POST request to update the completion status of a task
|
||||||
|
# data = {'task_id': self.todo.id, 'is_completed': True}
|
||||||
|
# response = self.client.post(reverse("dashboard-stats"), data, format='json')
|
||||||
|
|
||||||
|
# # Assert the response status code is 200
|
||||||
|
# self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
# # Assert the message in the response
|
||||||
|
# self.assertEqual(response.data['message'], 'Task completion status updated successfully')
|
||||||
|
|
||||||
|
# # Refresh the todo instance from the database and assert the completion status
|
||||||
|
# self.todo.refresh_from_db()
|
||||||
|
# self.assertTrue(self.todo.completed)
|
||||||
|
|
||||||
|
|
||||||
|
# class WeeklyStatsAPITestCase(TestCase):
|
||||||
|
# def setUp(self):
|
||||||
|
# # Create a test user
|
||||||
|
# self.user = create_test_user()
|
||||||
|
|
||||||
|
# # Create an API client
|
||||||
|
# self.client = APIClient()
|
||||||
|
|
||||||
|
# def test_weekly_stats_api(self):
|
||||||
|
# # Authenticate the user
|
||||||
|
# self.client.force_authenticate(user=self.user)
|
||||||
|
|
||||||
|
# # Make a GET request to the WeeklyStatsAPIView
|
||||||
|
# response = self.client.get(reverse('dashboard-weekly-stats'))
|
||||||
|
|
||||||
|
# # Assert the response status code is 200
|
||||||
|
# self.assertEqual(response.status_code, 200)
|
||||||
|
|||||||
@ -1,6 +1,11 @@
|
|||||||
from django.urls import path
|
from django.urls import path, include
|
||||||
from .views import DashboardStatsAPIView
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
|
from .views import DashboardStatsViewSet, DashboardWeeklyViewSet
|
||||||
|
|
||||||
|
router = DefaultRouter()
|
||||||
|
router.register(r'dashboard/stats', DashboardStatsViewSet, basename='stats')
|
||||||
|
router.register(r'dashboard/weekly', DashboardWeeklyViewSet, basename='weekly')
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('dashboard/stats/', DashboardStatsAPIView.as_view(), name='dashboard-stats'),
|
path('', include(router.urls)),
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,58 +1,311 @@
|
|||||||
from rest_framework.views import APIView
|
from datetime import timedelta
|
||||||
from rest_framework.response import Response
|
|
||||||
from rest_framework import status
|
|
||||||
from rest_framework.permissions import IsAuthenticated
|
|
||||||
from django.db.models import Count
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from rest_framework import status
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.permissions import IsAuthenticated
|
||||||
|
from rest_framework import viewsets, mixins
|
||||||
|
|
||||||
from tasks.models import Todo, RecurrenceTask
|
from tasks.models import Todo
|
||||||
|
|
||||||
class DashboardStatsAPIView(APIView):
|
|
||||||
permission_classes = [IsAuthenticated]
|
|
||||||
|
|
||||||
def get(self, request):
|
class DashboardStatsViewSet(viewsets.GenericViewSet, mixins.ListModelMixin):
|
||||||
user = request.user
|
permission_classes = (IsAuthenticated,)
|
||||||
|
|
||||||
# Calculate task usage statistics
|
def get_queryset(self):
|
||||||
todo_count = Todo.objects.filter(user=user).count()
|
return Todo.objects.all()
|
||||||
recurrence_task_count = RecurrenceTask.objects.filter(user=user).count()
|
|
||||||
|
|
||||||
# Calculate how many tasks were completed in the last 7 days
|
def list(self, request, *args, **kwargs):
|
||||||
completed_todo_count_last_week = Todo.objects.filter(user=user, completed=True, last_update__gte=timezone.now() - timezone.timedelta(days=7)).count()
|
user = self.request.user
|
||||||
completed_recurrence_task_count_last_week = RecurrenceTask.objects.filter(user=user, completed=True, last_update__gte=timezone.now() - timezone.timedelta(days=7)).count()
|
|
||||||
|
|
||||||
# Calculate subtask completion rate
|
# Calculate the start and end date for the last 7 days
|
||||||
total_subtasks = Todo.objects.filter(user=user).aggregate(total=Count('subtask__id'))['total']
|
end_date = timezone.now()
|
||||||
completed_subtasks = Todo.objects.filter(user=user, subtask__completed=True).aggregate(total=Count('subtask__id'))['total']
|
start_date = end_date - timedelta(days=7)
|
||||||
|
|
||||||
# Calculate overall completion rate
|
# How many tasks were completed in the last 7 days
|
||||||
total_tasks = todo_count + recurrence_task_count
|
completed_last_7_days = Todo.objects.filter(
|
||||||
completed_tasks = completed_todo_count_last_week + completed_recurrence_task_count_last_week
|
user=user,
|
||||||
overall_completion_rate = (completed_tasks / total_tasks) * 100 if total_tasks > 0 else 0
|
completed=True,
|
||||||
|
completion_date__gte=start_date,
|
||||||
|
completion_date__lte=end_date
|
||||||
|
).count()
|
||||||
|
|
||||||
|
# Task assign last week compared with this week
|
||||||
|
tasks_assigned_last_week = Todo.objects.filter(
|
||||||
|
user=user,
|
||||||
|
completion_date__gte=start_date - timedelta(days=7),
|
||||||
|
completion_date__lte=start_date
|
||||||
|
).count()
|
||||||
|
|
||||||
|
tasks_assigned_this_week = Todo.objects.filter(
|
||||||
|
user=user,
|
||||||
|
completion_date__gte=start_date,
|
||||||
|
completion_date__lte=end_date
|
||||||
|
).count()
|
||||||
|
|
||||||
|
# Completed tasks from last week compared with this week
|
||||||
|
completed_last_week = Todo.objects.filter(
|
||||||
|
user=user,
|
||||||
|
completed=True,
|
||||||
|
completion_date__gte=start_date - timedelta(days=7),
|
||||||
|
completion_date__lte=start_date
|
||||||
|
).count()
|
||||||
|
|
||||||
|
completed_this_week = Todo.objects.filter(
|
||||||
|
user=user,
|
||||||
|
completed=True,
|
||||||
|
completion_date__gte=start_date,
|
||||||
|
completion_date__lte=end_date
|
||||||
|
).count()
|
||||||
|
|
||||||
|
overdue_tasks = Todo.objects.filter(
|
||||||
|
user=user,
|
||||||
|
completed=False,
|
||||||
|
end_event__lt=timezone.now()
|
||||||
|
).count()
|
||||||
|
|
||||||
|
# Overall completion rate
|
||||||
|
total_tasks = Todo.objects.filter(user=user).count()
|
||||||
|
overall_completion_rate = (completed_last_7_days / total_tasks) * 100 if total_tasks > 0 else 0
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'todo_count': todo_count,
|
"completed_last_7_days": completed_last_7_days,
|
||||||
'recurrence_task_count': recurrence_task_count,
|
"tasks_assigned_last_week": tasks_assigned_last_week,
|
||||||
'completed_todo_count_last_week': completed_todo_count_last_week,
|
"tasks_assigned_this_week": tasks_assigned_this_week,
|
||||||
'completed_recurrence_task_count_last_week': completed_recurrence_task_count_last_week,
|
"completed_last_week": completed_last_week,
|
||||||
'total_subtasks': total_subtasks,
|
"completed_this_week": completed_this_week,
|
||||||
'completed_subtasks': completed_subtasks,
|
"overdue_tasks": overdue_tasks,
|
||||||
'overall_completion_rate': overall_completion_rate,
|
"overall_completion_rate": overall_completion_rate,
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response(data, status=status.HTTP_200_OK)
|
return Response(data, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
class DashboardWeeklyViewSet(viewsets.GenericViewSet, mixins.ListModelMixin):
|
||||||
|
permission_classes = (IsAuthenticated,)
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
return Todo.objects.all()
|
||||||
|
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
user = self.request.user
|
||||||
|
|
||||||
|
# Calculate the start and end date for the last 7 days (Monday to Sunday)
|
||||||
|
today = timezone.now().date()
|
||||||
|
current_week_start = today - timedelta(days=today.weekday())
|
||||||
|
current_week_end = current_week_start + timedelta(days=6)
|
||||||
|
|
||||||
|
last_week_start = current_week_start - timedelta(days=7)
|
||||||
|
last_week_end = last_week_start + timedelta(days=6)
|
||||||
|
|
||||||
|
# Create a list to store daily statistics
|
||||||
|
weekly_stats = []
|
||||||
|
|
||||||
|
# Iterate over each day of the week
|
||||||
|
for day in range(7):
|
||||||
|
current_day = current_week_start + timedelta(days=day)
|
||||||
|
last_day = last_week_start + timedelta(days=day)
|
||||||
|
|
||||||
|
# Calculate stats for this week
|
||||||
|
tasks_this_week = Todo.objects.filter(
|
||||||
|
user=user,
|
||||||
|
completion_date__gte=current_day,
|
||||||
|
completion_date__lte=current_day + timedelta(days=1)
|
||||||
|
).count()
|
||||||
|
|
||||||
|
completed_this_week = Todo.objects.filter(
|
||||||
|
user=user,
|
||||||
|
completed=True,
|
||||||
|
completion_date__gte=current_day,
|
||||||
|
completion_date__lte=current_day + timedelta(days=1)
|
||||||
|
).count()
|
||||||
|
|
||||||
|
# Calculate stats for last week
|
||||||
|
tasks_last_week = Todo.objects.filter(
|
||||||
|
user=user,
|
||||||
|
completion_date__gte=last_day,
|
||||||
|
completion_date__lte=last_day + timedelta(days=1)
|
||||||
|
).count()
|
||||||
|
|
||||||
|
completed_last_week = Todo.objects.filter(
|
||||||
|
user=user,
|
||||||
|
completed=True,
|
||||||
|
completion_date__gte=last_day,
|
||||||
|
completion_date__lte=last_day + timedelta(days=1)
|
||||||
|
).count()
|
||||||
|
|
||||||
|
daily_stat = {
|
||||||
|
"date": current_day.strftime("%A"),
|
||||||
|
"This Week": tasks_this_week,
|
||||||
|
"Last Week": tasks_last_week,
|
||||||
|
"Completed This Week": completed_this_week,
|
||||||
|
"Completed Last Week": completed_last_week,
|
||||||
|
}
|
||||||
|
|
||||||
|
weekly_stats.append(daily_stat)
|
||||||
|
|
||||||
|
return Response(weekly_stats, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
# class DashboardStatsAPIView(APIView):
|
||||||
|
# permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
# def get(self, request):
|
||||||
|
# user = request.user
|
||||||
|
|
||||||
|
# # Calculate task usage statistics
|
||||||
|
# todo_count = Todo.objects.filter(user=user).count()
|
||||||
|
# recurrence_task_count = RecurrenceTask.objects.filter(user=user).count()
|
||||||
|
|
||||||
|
# # Calculate how many tasks were completed in the last 7 days
|
||||||
|
# completed_todo_count_last_week = Todo.objects.filter(user=user, completed=True, last_update__gte=timezone.now() - timezone.timedelta(days=7)).count()
|
||||||
|
# completed_recurrence_task_count_last_week = RecurrenceTask.objects.filter(user=user, completed=True, last_update__gte=timezone.now() - timezone.timedelta(days=7)).count()
|
||||||
|
|
||||||
|
# # Calculate subtask completion rate
|
||||||
|
# total_subtasks = Todo.objects.filter(user=user).aggregate(total=Count('subtask__id'))['total']
|
||||||
|
# completed_subtasks = Todo.objects.filter(user=user, subtask__completed=True).aggregate(total=Count('subtask__id'))['total']
|
||||||
|
|
||||||
|
# # Calculate overall completion rate
|
||||||
|
# total_tasks = todo_count + recurrence_task_count
|
||||||
|
# completed_tasks = completed_todo_count_last_week + completed_recurrence_task_count_last_week
|
||||||
|
# overall_completion_rate = (completed_tasks / total_tasks) * 100 if total_tasks > 0 else 0
|
||||||
|
|
||||||
|
# # pie chart show
|
||||||
|
# complete_todo_percent_last_week = (completed_todo_count_last_week / todo_count) * 100 if todo_count > 0 else 0
|
||||||
|
|
||||||
|
# complete_recurrence_percent_last_week = (completed_recurrence_task_count_last_week / recurrence_task_count) * 100 if recurrence_task_count > 0 else 0
|
||||||
|
|
||||||
|
# incomplete_task_percent_last_week = 100 - complete_recurrence_percent_last_week - complete_todo_percent_last_week
|
||||||
|
|
||||||
|
# data = {
|
||||||
|
# 'todo_count': todo_count,
|
||||||
|
# 'recurrence_task_count': recurrence_task_count,
|
||||||
|
# 'completed_todo_count_last_week': completed_todo_count_last_week,
|
||||||
|
# 'completed_recurrence_task_count_last_week': completed_recurrence_task_count_last_week,
|
||||||
|
# 'total_subtasks': total_subtasks,
|
||||||
|
# 'completed_subtasks': completed_subtasks,
|
||||||
|
# 'overall_completion_rate': overall_completion_rate,
|
||||||
|
# 'complete_todo_percent_last_week': complete_todo_percent_last_week,
|
||||||
|
# 'complete_recurrence_percent_last_week' : complete_recurrence_percent_last_week,
|
||||||
|
# 'incomplete_task_percent_last_week': incomplete_task_percent_last_week,
|
||||||
|
|
||||||
|
# }
|
||||||
|
|
||||||
|
# return Response(data, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
def post(self, request):
|
# def post(self, request):
|
||||||
# Handle incoming data from the POST request
|
# # Handle incoming data from the POST request
|
||||||
# Update the necessary information based on the data
|
# # Update the necessary information based on the data
|
||||||
|
|
||||||
task_id = request.data.get('task_id')
|
# task_id = request.data.get('task_id')
|
||||||
is_completed = request.data.get('is_completed')
|
# is_completed = request.data.get('is_completed')
|
||||||
|
|
||||||
try:
|
# try:
|
||||||
task = Todo.objects.get(id=task_id, user=request.user)
|
# task = Todo.objects.get(id=task_id, user=request.user)
|
||||||
task.completed = is_completed
|
# task.completed = is_completed
|
||||||
task.save()
|
# task.save()
|
||||||
return Response({'message': 'Task completion status updated successfully'}, status=status.HTTP_200_OK)
|
# return Response({'message': 'Task completion status updated successfully'}, status=status.HTTP_200_OK)
|
||||||
except Todo.DoesNotExist:
|
# except Todo.DoesNotExist:
|
||||||
return Response({'error': 'Task not found'}, status=status.HTTP_404_NOT_FOUND)
|
# return Response({'error': 'Task not found'}, status=status.HTTP_404_NOT_FOUND)
|
||||||
|
|
||||||
|
# class WeeklyStatsAPIView(APIView):
|
||||||
|
# permission_classes = [IsAuthenticated]
|
||||||
|
|
||||||
|
# def get(self, request):
|
||||||
|
# user = request.user
|
||||||
|
# today = timezone.now()
|
||||||
|
|
||||||
|
# # Calculate the start and end dates for the current week
|
||||||
|
# current_week_start = today - timezone.timedelta(days=today.weekday())
|
||||||
|
# current_week_end = current_week_start + timezone.timedelta(days=6)
|
||||||
|
|
||||||
|
# # Initialize a list to store daily statistics
|
||||||
|
# weekly_stats = []
|
||||||
|
|
||||||
|
# # Loop through each day of the week
|
||||||
|
# for i in range(7):
|
||||||
|
# # Calculate the start and end dates for the current day
|
||||||
|
# current_day_start = current_week_start + timezone.timedelta(days=i)
|
||||||
|
# current_day_end = current_day_start + timezone.timedelta(days=1)
|
||||||
|
|
||||||
|
# # Calculate the start and end dates for the same day over the last 7 days
|
||||||
|
# last_7_days_start = current_day_start - timezone.timedelta(days=7)
|
||||||
|
# last_7_days_end = current_day_end - timezone.timedelta(days=7)
|
||||||
|
|
||||||
|
# # Calculate statistics for the current day
|
||||||
|
# current_day_stats = self.calculate_stats(user, current_day_start, current_day_end)
|
||||||
|
|
||||||
|
# # Calculate statistics for the same day over the last 7 days
|
||||||
|
# last_7_days_stats = self.calculate_stats(user, last_7_days_start, last_7_days_end)
|
||||||
|
|
||||||
|
# # Calculate the percentage change
|
||||||
|
# percent_change_over_all = self.calculate_percent_change(
|
||||||
|
# current_day_stats['overall_completion_rate'],
|
||||||
|
# last_7_days_stats['overall_completion_rate']
|
||||||
|
# )
|
||||||
|
|
||||||
|
# # Calculate percentage change for completed_todo_count
|
||||||
|
# percent_change_todo = self.calculate_percent_change(
|
||||||
|
# current_day_stats['completed_todo_count'],
|
||||||
|
# last_7_days_stats['completed_todo_count']
|
||||||
|
# )
|
||||||
|
|
||||||
|
# # Calculate percentage change for completed_recurrence_task_count
|
||||||
|
# percent_change_recurrence = self.calculate_percent_change(
|
||||||
|
# current_day_stats['completed_recurrence_task_count'],
|
||||||
|
# last_7_days_stats['completed_recurrence_task_count']
|
||||||
|
# )
|
||||||
|
|
||||||
|
# # Append the daily statistics to the list
|
||||||
|
# weekly_stats.append({
|
||||||
|
# 'day_of_week': current_day_start.strftime('%A'),
|
||||||
|
# 'current_day_stats': current_day_stats,
|
||||||
|
# 'last_7_days_stats': last_7_days_stats,
|
||||||
|
# 'percent_change_over_all': percent_change_over_all,
|
||||||
|
# 'percent_change_todo': percent_change_todo,
|
||||||
|
# 'percent_change_recurrence': percent_change_recurrence,
|
||||||
|
# })
|
||||||
|
|
||||||
|
# response_data = {
|
||||||
|
# 'weekly_stats': weekly_stats,
|
||||||
|
# }
|
||||||
|
|
||||||
|
# return Response(response_data, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
# def calculate_stats(self, user, start_date, end_date):
|
||||||
|
# # Calculate task usage statistics for the specified day
|
||||||
|
# todo_count = Todo.objects.filter(user=user, created_at__gte=start_date, created_at__lte=end_date).count()
|
||||||
|
# recurrence_task_count = RecurrenceTask.objects.filter(user=user, created_at__gte=start_date, created_at__lte=end_date).count()
|
||||||
|
|
||||||
|
# # Calculate how many tasks were completed on the specified day
|
||||||
|
# completed_todo_count = Todo.objects.filter(user=user, completed=True, last_update__gte=start_date, last_update__lte=end_date).count()
|
||||||
|
# completed_recurrence_task_count = RecurrenceTask.objects.filter(user=user, completed=True, last_update__gte=start_date, last_update__lte=end_date).count()
|
||||||
|
|
||||||
|
# # Calculate subtask completion rate for the specified day
|
||||||
|
# total_subtasks = Todo.objects.filter(user=user, created_at__gte=start_date, created_at__lte=end_date).aggregate(total=Count('subtask__id'))['total']
|
||||||
|
# completed_subtasks = Todo.objects.filter(user=user, subtask__completed=True, created_at__gte=start_date, created_at__lte=end_date).aggregate(total=Count('subtask__id'))['total']
|
||||||
|
|
||||||
|
# # Calculate overall completion rate for the specified day
|
||||||
|
# total_tasks = todo_count + recurrence_task_count
|
||||||
|
# completed_tasks = completed_todo_count + completed_recurrence_task_count
|
||||||
|
# overall_completion_rate = (completed_tasks / total_tasks) * 100 if total_tasks > 0 else 0
|
||||||
|
|
||||||
|
# return {
|
||||||
|
# 'start_date': start_date.strftime('%Y-%m-%d'),
|
||||||
|
# 'end_date': end_date.strftime('%Y-%m-%d'),
|
||||||
|
# 'todo_count': todo_count,
|
||||||
|
# 'recurrence_task_count': recurrence_task_count,
|
||||||
|
# 'completed_todo_count': completed_todo_count,
|
||||||
|
# 'completed_recurrence_task_count': completed_recurrence_task_count,
|
||||||
|
# 'total_subtasks': total_subtasks,
|
||||||
|
# 'completed_subtasks': completed_subtasks,
|
||||||
|
# 'overall_completion_rate': overall_completion_rate,
|
||||||
|
# }
|
||||||
|
|
||||||
|
# def calculate_percent_change(self, current_value, last_value):
|
||||||
|
# # Calculate the percentage change between current and last values
|
||||||
|
# if last_value != 0:
|
||||||
|
# percent_change = ((current_value - last_value) / last_value) * 100
|
||||||
|
# else:
|
||||||
|
# percent_change = current_value * 100 # Consider infinite change when the last value is zero
|
||||||
|
|
||||||
|
# return round(percent_change, 2)
|
||||||
|
|||||||
@ -7,8 +7,9 @@ class TagAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
@admin.register(Todo)
|
@admin.register(Todo)
|
||||||
class TodoAdmin(admin.ModelAdmin):
|
class TodoAdmin(admin.ModelAdmin):
|
||||||
list_display = ['title', 'list_board', 'is_active', 'priority']
|
list_display = ['title', 'list_board', 'is_active', 'priority', 'completed', 'completion_date']
|
||||||
list_filter = ['list_board', 'is_active', 'priority']
|
list_filter = ['list_board', 'is_active', 'priority', 'completed']
|
||||||
|
exclude = ['completion_date']
|
||||||
|
|
||||||
@admin.register(RecurrenceTask)
|
@admin.register(RecurrenceTask)
|
||||||
class RecurrenceTaskAdmin(admin.ModelAdmin):
|
class RecurrenceTaskAdmin(admin.ModelAdmin):
|
||||||
|
|||||||
@ -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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -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),
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -1,5 +1,6 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
from boards.models import ListBoard, Board
|
from boards.models import ListBoard, Board
|
||||||
|
|
||||||
@ -25,6 +26,7 @@ class Task(models.Model):
|
|||||||
:param challenge: Associated challenge (optional).
|
:param challenge: Associated challenge (optional).
|
||||||
:param fromSystem: A boolean field indicating if the task is from System.
|
:param fromSystem: A boolean field indicating if the task is from System.
|
||||||
:param creation_date: Creation date of the task.
|
:param creation_date: Creation date of the task.
|
||||||
|
:param last_update: Last update date of the task.
|
||||||
"""
|
"""
|
||||||
class Difficulty(models.IntegerChoices):
|
class Difficulty(models.IntegerChoices):
|
||||||
EASY = 1, 'Easy'
|
EASY = 1, 'Easy'
|
||||||
@ -59,6 +61,7 @@ class Todo(Task):
|
|||||||
:param end_event: End date and time of the task.
|
:param end_event: End date and time of the task.
|
||||||
:param google_calendar_id: The Google Calendar ID 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 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).
|
:param priority: The priority of the task (range: 1 to 4).
|
||||||
"""
|
"""
|
||||||
class EisenhowerMatrix(models.IntegerChoices):
|
class EisenhowerMatrix(models.IntegerChoices):
|
||||||
@ -74,8 +77,17 @@ class Todo(Task):
|
|||||||
end_event = models.DateTimeField(null=True)
|
end_event = models.DateTimeField(null=True)
|
||||||
google_calendar_id = models.CharField(max_length=255, null=True, blank=True)
|
google_calendar_id = models.CharField(max_length=255, null=True, blank=True)
|
||||||
completed = models.BooleanField(default=False)
|
completed = models.BooleanField(default=False)
|
||||||
|
completion_date = models.DateTimeField(null=True)
|
||||||
priority = models.PositiveSmallIntegerField(choices=EisenhowerMatrix.choices, default=EisenhowerMatrix.NOT_IMPORTANT_NOT_URGENT)
|
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):
|
def __str__(self):
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
@ -90,6 +102,7 @@ class RecurrenceTask(Task):
|
|||||||
:param start_event: Start date and time of the task.
|
:param start_event: Start date and time of the task.
|
||||||
:param end_event: End 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 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.
|
:param parent_task: The parent task of the subtask.
|
||||||
"""
|
"""
|
||||||
list_board = models.ForeignKey(ListBoard, on_delete=models.CASCADE, null=True, default=1)
|
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)
|
start_event = models.DateTimeField(null=True)
|
||||||
end_event = models.DateTimeField(null=True)
|
end_event = models.DateTimeField(null=True)
|
||||||
completed = models.BooleanField(default=False)
|
completed = models.BooleanField(default=False)
|
||||||
|
completion_date = models.DateTimeField(null=True)
|
||||||
parent_task = models.ForeignKey("self", on_delete=models.CASCADE, 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:
|
def __str__(self) -> str:
|
||||||
return f"{self.title} ({self.recurrence_rule})"
|
return f"{self.title} ({self.recurrence_rule})"
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user