Files
korrekturmanagementsystem/ticketsystem/views.py

221 lines
8.2 KiB
Python

from django.views.generic import ListView, TemplateView
from django.views.generic.edit import CreateView, UpdateView
from django.urls import reverse_lazy
from django.views.generic.detail import DetailView
from django.views.generic.edit import FormMixin
from .forms import CommentForm
from django.urls import reverse
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages
from django.shortcuts import redirect
from django.db.models import Q
from .models import Ticket, TicketHistory
class HomeView(TemplateView):
template_name = "ticketsystem/home.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update(
{
"total_tickets": Ticket.objects.count(),
"open_tickets": Ticket.objects.filter(status="open").count(),
"closed_tickets": Ticket.objects.filter(status="closed").count(),
"recent_tickets": Ticket.objects.order_by("-updated_at")[:5],
}
)
return context
class TicketListView(ListView):
model = Ticket
template_name = "ticketsystem/index.html"
context_object_name = "tickets"
ordering = ["-created_at"]
paginate_by = 10
def get_queryset(self):
queryset = super().get_queryset()
status = self.request.GET.get("status")
assigned_to = self.request.GET.get("assigned_to")
query = self.request.GET.get("q")
if status:
queryset = queryset.filter(status=status)
if assigned_to:
queryset = queryset.filter(assigned_to_id=assigned_to)
if query:
queryset = queryset.filter(
Q(title__icontains=query) | Q(description__icontains=query)
)
return queryset
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["selected_status"] = self.request.GET.get("status", "")
context["search_query"] = self.request.GET.get("q", "")
context["status_choices"] = Ticket.STATUS_CHOICES
return context
class TicketDetailUpdateView(UpdateView):
model = Ticket
fields = ["title", "description", "status", "priority", "assigned_to", "course"]
template_name = "ticketsystem/detail.html"
comment_form_class = CommentForm
def get_success_url(self):
return reverse("detail", kwargs={"pk": self.object.pk})
def dispatch(self, request, *args, **kwargs):
self.ticket = self.get_object()
user = request.user
# Prüfen, ob User bearbeiten darf
self.can_edit = (user == self.ticket.assigned_to) or user.is_superuser
return super().dispatch(request, *args, **kwargs)
def get_form(self, form_class=None):
form = super().get_form(form_class)
if not self.can_edit:
for field in form.fields:
form.fields[field].disabled = True # Felder lesbar, aber nicht änderbar
return form
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# Kommentarformular hinzufügen
if "comment_form" not in context:
context["comment_form"] = self.comment_form_class()
return context
def form_valid(self, form):
ticket = form.instance
original = Ticket.objects.get(pk=ticket.pk)
response = super().form_valid(form) # Speichert das Ticket
# History tracking für geänderte Felder
tracked_fields = ["title", "description", "status", "priority", "assigned_to", "course"]
for field in tracked_fields:
if field in form.changed_data:
old_value = getattr(original, field)
new_value = form.cleaned_data.get(field)
# Für ForeignKey Felder den Display-Namen verwenden
if field == "assigned_to":
old_value = old_value.username if old_value else "Niemand"
new_value = new_value.username if new_value else "Niemand"
elif field == "status":
old_value = original.get_status_display()
new_value = ticket.get_status_display()
elif field == "priority":
old_value = original.get_priority_display()
new_value = ticket.get_priority_display()
TicketHistory.objects.create(
ticket=ticket,
changed_by=self.request.user,
field=field,
old_value=str(old_value),
new_value=str(new_value),
)
if form.changed_data:
messages.success(
self.request,
f"Ticket erfolgreich aktualisiert. Geänderte Felder: {', '.join(form.changed_data)}",
)
return response
def post(self, request, *args, **kwargs):
self.object = self.get_object() # Wichtig: object setzen für beide Fälle
if "comment_submit" in request.POST:
# Kommentar absenden
comment_form = self.comment_form_class(request.POST)
if comment_form.is_valid():
comment = comment_form.save(commit=False)
comment.ticket = self.object
comment.author = request.user
comment.save()
messages.success(request, "Kommentar hinzugefügt.")
return redirect(self.get_success_url())
else:
# Kommentarformular fehlerhaft: Seite neu laden mit Fehlern
context = self.get_context_data(comment_form=comment_form)
return self.render_to_response(context)
else:
# Ticket bearbeiten (UpdateView standard)
if not self.can_edit:
messages.error(request, "⛔ Du darfst dieses Ticket nicht bearbeiten.")
return redirect(self.get_success_url())
return super().post(request, *args, **kwargs)
class AssignedTicketListView(LoginRequiredMixin, ListView):
model = Ticket
template_name = "ticketsystem/assigned_tickets.html"
context_object_name = "tickets"
ordering = ["-created_at"]
def get_queryset(self):
return Ticket.objects.filter(assigned_to=self.request.user).exclude(
status="closed"
) # oder "geschlossen", je nach Wahl
class TicketCreateView(CreateView):
model = Ticket
fields = ["title", "description", "status", "priority", "assigned_to", "course"]
template_name = "ticketsystem/ticket_form.html"
def form_valid(self, form):
form.instance.created_by = self.request.user
form.instance.status = "new"
return super().form_valid(form)
def get_success_url(self):
return reverse("detail", kwargs={"pk": self.object.pk})
class TicketUpdateView(LoginRequiredMixin, UpdateView):
model = Ticket
fields = ["title", "description", "status", "priority", "assigned_to", "course"]
template_name = "ticketsystem/ticket_form.html"
def dispatch(self, request, *args, **kwargs):
ticket = self.get_object()
user = request.user
if user != ticket.assigned_to and not user.is_staff:
messages.error(request, "⛔ Du darfst dieses Ticket nicht bearbeiten.")
return redirect("detail", pk=ticket.pk)
return super().dispatch(request, *args, **kwargs)
def get_queryset(self):
return Ticket.objects.all() # Optional: Nur eigene Tickets bearbeiten lassen?
def form_valid(self, form):
ticket = form.instance
original = Ticket.objects.get(pk=ticket.pk)
response = super().form_valid(form) # Speichert das Ticket
tracked_fields = ["status", "description", "priority"]
for field in tracked_fields:
if field in form.changed_data:
old_value = getattr(original, field)
new_value = form.cleaned_data.get(field)
TicketHistory.objects.create(
ticket=ticket,
changed_by=self.request.user,
field=field,
old_value=str(old_value),
new_value=str(new_value),
)
return response
def get_success_url(self):
return reverse_lazy("detail", kwargs={"pk": self.object.pk})