make tickets assignable to users

This commit is contained in:
j3d1 2024-01-22 17:21:22 +01:00
parent 4be8109753
commit e605292bf0
11 changed files with 317 additions and 110 deletions

View file

@ -2,7 +2,7 @@ import logging
from django.urls import re_path
from django.contrib.auth.decorators import permission_required
from rest_framework import routers, viewsets, serializers, status
from rest_framework import routers, viewsets, status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
@ -10,78 +10,11 @@ from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
from core.settings import MAIL_DOMAIN
from mail.api_v2 import AttachmentSerializer
from mail.models import Email
from mail.protocol import send_smtp, make_reply, collect_references
from notify_sessions.models import SystemEvent
from tickets.models import IssueThread, Comment, STATE_CHOICES
class IssueSerializer(serializers.ModelSerializer):
timeline = serializers.SerializerMethodField()
last_activity = serializers.SerializerMethodField()
class Meta:
model = IssueThread
fields = ('id', 'timeline', 'name', 'state', 'assigned_to', 'last_activity', 'uuid')
read_only_fields = ('id', 'timeline', 'last_activity', 'uuid')
def to_internal_value(self, data):
ret = super().to_internal_value(data)
if 'state' in data:
ret['state'] = data['state']
return ret
def validate(self, attrs):
if 'state' in attrs:
if attrs['state'] not in [x[0] for x in STATE_CHOICES]:
raise serializers.ValidationError('invalid state')
return attrs
@staticmethod
def get_last_activity(self):
try:
last_state_change = self.state_changes.order_by('-timestamp').first().timestamp \
if self.state_changes.count() > 0 else None
last_comment = self.comments.order_by('-timestamp').first().timestamp if self.comments.count() > 0 else None
last_mail = self.emails.order_by('-timestamp').first().timestamp if self.emails.count() > 0 else None
args = [x for x in [last_state_change, last_comment, last_mail] if x is not None]
return max(args)
except AttributeError:
return None
@staticmethod
def get_timeline(obj):
timeline = []
for comment in obj.comments.all():
timeline.append({
'type': 'comment',
'id': comment.id,
'timestamp': comment.timestamp,
'comment': comment.comment,
})
for state_change in obj.state_changes.all():
timeline.append({
'type': 'state',
'id': state_change.id,
'timestamp': state_change.timestamp,
'state': state_change.state,
})
for email in obj.emails.all():
timeline.append({
'type': 'mail',
'id': email.id,
'timestamp': email.timestamp,
'sender': email.sender,
'recipient': email.recipient,
'subject': email.subject,
'body': email.body,
'attachments': AttachmentSerializer(email.attachments.all(), many=True).data,
})
return sorted(timeline, key=lambda x: x['timestamp'])
def get_queryset(self):
return IssueThread.objects.all().order_by('-last_activity')
from tickets.serializers import IssueSerializer, CommentSerializer
class IssueViewSet(viewsets.ModelViewSet):
@ -89,18 +22,6 @@ class IssueViewSet(viewsets.ModelViewSet):
queryset = IssueThread.objects.all()
class CommentSerializer(serializers.ModelSerializer):
def validate(self, attrs):
if 'comment' not in attrs or attrs['comment'] == '':
raise serializers.ValidationError('comment cannot be empty')
return attrs
class Meta:
model = Comment
fields = ('id', 'comment', 'timestamp', 'issue_thread')
class CommentViewSet(viewsets.ModelViewSet):
serializer_class = CommentSerializer
queryset = Comment.objects.all()
@ -116,7 +37,8 @@ def reply(request, pk):
first_mail = Email.objects.filter(issue_thread=issue, recipient__endswith='@' + MAIL_DOMAIN).order_by(
'timestamp').first()
if not first_mail:
return Response({'status': 'error', 'message': 'no previous mail found, reply would not make sense.'}, status=status.HTTP_400_BAD_REQUEST)
return Response({'status': 'error', 'message': 'no previous mail found, reply would not make sense.'},
status=status.HTTP_400_BAD_REQUEST)
mail = Email.objects.create(
issue_thread=issue,
sender=first_mail.recipient,
@ -165,17 +87,6 @@ def manual_ticket(request):
return Response(IssueSerializer(issue).data, status=status.HTTP_201_CREATED)
class StateSerializer(serializers.Serializer):
text = serializers.SerializerMethodField()
value = serializers.SerializerMethodField()
def get_text(self, obj):
return obj['text']
def get_value(self, obj):
return obj['value']
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def get_available_states(request):