from django.contrib.auth.mixins import LoginRequiredMixin from django.db.models import Count from django.urls import reverse_lazy from django.views.generic import CreateView, DeleteView, DetailView, ListView, TemplateView, UpdateView from apps.core.permissions import AdminRequiredMixin from apps.issues.models import Issue from apps.projects.models import Project from apps.tickets.models import Ticket class DashboardView(LoginRequiredMixin, TemplateView): template_name = "pages/dashboard.html" def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) user = self.request.user user_projects = Project.objects.filter(members=user) if user.is_admin(): user_projects = Project.objects.all() context["total_projects"] = user_projects.count() context["active_projects"] = user_projects.filter(status=Project.Status.ACTIVE).count() context["projects"] = user_projects.order_by("-updated_at")[:5] issues = Issue.objects.filter(project__in=user_projects) context["total_issues"] = issues.count() context["open_issues"] = issues.filter(status=Issue.Status.OPEN).count() context["recent_issues"] = issues.select_related("project").order_by("-created_at")[:5] tickets = Ticket.objects.filter(project__in=user_projects) context["total_tickets"] = tickets.count() context["new_tickets"] = tickets.filter(status=Ticket.Status.NEW).count() context["recent_tickets"] = tickets.select_related("project").order_by("-created_at")[:5] return context class ProjectListView(LoginRequiredMixin, ListView): model = Project template_name = "pages/projects/project_list.html" context_object_name = "projects" paginate_by = 20 def get_queryset(self): user = self.request.user if user.is_admin(): return Project.objects.all() return Project.objects.filter(members=user) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["status_counts"] = ( self.get_queryset().values("status").annotate(count=Count("id")) ) return context class ProjectDetailView(LoginRequiredMixin, DetailView): model = Project template_name = "pages/projects/project_detail.html" context_object_name = "project" def get_queryset(self): user = self.request.user if user.is_admin(): return Project.objects.all() return Project.objects.filter(members=user) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) project = self.object context["issues"] = project.issues.select_related("assignee").all() context["open_issues"] = project.issues.filter(status=Issue.Status.OPEN).count() context["tickets"] = project.tickets.all()[:5] return context class ProjectCreateView(LoginRequiredMixin, CreateView): model = Project template_name = "pages/projects/project_form.html" fields = ["name", "client", "status", "members"] success_url = reverse_lazy("project_list") class ProjectUpdateView(AdminRequiredMixin, UpdateView): model = Project template_name = "pages/projects/project_form.html" fields = ["name", "client", "status", "members"] success_url = reverse_lazy("project_list") class ProjectDeleteView(AdminRequiredMixin, DeleteView): model = Project template_name = "pages/projects/project_confirm_delete.html" success_url = reverse_lazy("project_list")