from datetime import timedelta from django.core.files.uploadedfile import UploadedFile from django.db.models import Sum, Q, QuerySet from django.http import JsonResponse from django.shortcuts import render, get_object_or_404, redirect from django.views import generic from django.views.decorators.http import require_POST from dispatcher.core import import_tasks from dispatcher.forms import ProjectForm, ImportForm from dispatcher.models import Project, Parent, Task def dashboard_view(request): context = { "projects": Project.objects.all(), "parents": Parent.objects.all() } return render(request, "dashboard.html", context) def projects_view(request): context = { "projects": Project.objects.all(), "parents": Parent.objects.all() } return render(request, "projects.html", context) def project_view(request, id): project = get_object_or_404(Project, id=id) context = {} form = ProjectForm(request.POST or None, request.FILES or None, instance=project) if form.is_valid(): form.save() context["form"] = ProjectForm(instance=project) return render(request, "project.html", context) @require_POST def set_parent(request, id): project = get_object_or_404(Project, id=id) parent_id = request.POST.get("parent_id") try: parent = Parent.objects.get(id=parent_id) except Parent.DoesNotExist: parent = None project.parent = parent project.save() return JsonResponse({"status": "success"}) def import_view(request): if request.method == "POST": form = ImportForm(request.POST, request.FILES) if form.is_valid(): print(request.FILES) import_tasks(request.FILES["file"].read().decode("utf-8")) return redirect("dashboard") return render(request, "import.html") def get_stats_by_month(request, year: int, month: int): if month < 1 or month > 12: return JsonResponse({"status": "error", "error": f"Invalid month {month}"}) parents = Parent.objects.annotate( total_duration=Sum( "project__task__duration", filter=Q( project__task__date__year=year, project__task__date__month=month ) ) ) projects = Project.objects.annotate( total_duration=Sum( "task__duration", filter=Q( task__date__year=year, task__date__month=month ) ) ) return JsonResponse({"status": "success", "data": format_stats(parents, projects)}) def get_stats_between(request, start_date, end_date): parents = Parent.objects.annotate( total_duration=Sum( "project__task__duration", filter=Q( project__task__date__gte=start_date, project__task__date__lt=end_date + timedelta(days=1) ) ) ) projects = Project.objects.annotate( total_duration=Sum( "task__duration", filter=Q( task__date__gte=start_date, task__date__lt=end_date + timedelta(days=1) ) ) ) return JsonResponse({"status": "success", "data": format_stats(parents, projects)}) def format_stats(parents: QuerySet[Parent], projects: QuerySet[Project]): data = { "parents": [ { "id": parent.id, "name": parent.name, "project_num": parent.project_num, "duration": parent.total_duration } for parent in parents ], "projects": [ { "id": project.id, "name": project.name, "duration": project.total_duration } for project in projects ] } return data class ParentsView(generic.ListView): model = Parent template_name = "parents.html" context_object_name = "elements"