feat: added ticket history
This commit is contained in:
@@ -36,3 +36,16 @@ class Comment(models.Model):
|
||||
|
||||
def __str__(self):
|
||||
return f"Kommentar von {self.author} zu Ticket #{self.ticket.id}"
|
||||
|
||||
|
||||
class TicketHistory(models.Model):
|
||||
ticket = models.ForeignKey("Ticket", on_delete=models.CASCADE, related_name="history")
|
||||
changed_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
|
||||
changed_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
field = models.CharField(max_length=100) # z. B. "status" oder "description"
|
||||
old_value = models.TextField(null=True, blank=True)
|
||||
new_value = models.TextField(null=True, blank=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ["-changed_at"]
|
||||
|
||||
@@ -132,5 +132,22 @@
|
||||
<button type="submit">Absenden</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
<div style="margin-top: 3rem;">
|
||||
<h2>🕓 Bearbeitungshistorie</h2>
|
||||
{% if ticket.history.exists %}
|
||||
<ul style="list-style: none; padding: 0;">
|
||||
{% for entry in ticket.history.all %}
|
||||
<li style="margin-bottom: 1rem; background-color: #f9f9f9; border-left: 4px solid #ccc; padding: 0.5rem 1rem;">
|
||||
<strong>{{ entry.changed_by.username }}</strong>
|
||||
hat <code>{{ entry.field }}</code> geändert:<br>
|
||||
<em>{{ entry.old_value }}</em> → <strong>{{ entry.new_value }}</strong><br>
|
||||
<small>am {{ entry.changed_at|date:"d.m.Y H:i" }}</small>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p><em>Keine Änderungen bisher.</em></p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -10,7 +10,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.contrib import messages
|
||||
from django.shortcuts import redirect
|
||||
|
||||
from .models import Ticket
|
||||
from .models import Ticket, TicketHistory
|
||||
|
||||
|
||||
class HomeView(TemplateView):
|
||||
@@ -63,6 +63,7 @@ class TicketDetailView(FormMixin, DetailView):
|
||||
context["form"] = self.get_form()
|
||||
return context
|
||||
|
||||
|
||||
class TicketCreateView(CreateView):
|
||||
model = Ticket
|
||||
fields = ["title", "description", "priority", "assigned_to"] # user & status wird automatisch gesetzt
|
||||
@@ -74,6 +75,7 @@ class TicketCreateView(CreateView):
|
||||
form.instance.status = "open" # Neues Ticket beginnt immer als "offen"
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
class TicketUpdateView(LoginRequiredMixin, UpdateView):
|
||||
model = Ticket
|
||||
fields = ["title", "description", "status", "priority", "assigned_to"]
|
||||
@@ -90,3 +92,24 @@ class TicketUpdateView(LoginRequiredMixin, UpdateView):
|
||||
|
||||
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"]
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user