mirror of
https://gitea.mueller.network/extern/django-helpdesk.git
synced 2025-08-02 03:39:39 +02:00
This is extremely useful when writing custom frontends on top of django helpdesk. This is similar to the custom_fields except it is normalized and attached to followups and not tickets. The fact that it is just JSON means that there is no need for updating the database with new CustomField entries making for more easily maintained custom frontends.
220 lines
7.6 KiB
Python
220 lines
7.6 KiB
Python
from django.contrib.auth import get_user_model
|
|
from django.contrib.humanize.templatetags import humanize
|
|
from rest_framework import serializers
|
|
from rest_framework.exceptions import ValidationError
|
|
|
|
from .forms import TicketForm
|
|
from .lib import format_time_spent
|
|
from .models import CustomField, FollowUp, FollowUpAttachment, Ticket
|
|
from .user import HelpdeskUser
|
|
from .update_ticket import update_ticket
|
|
|
|
|
|
class DatatablesTicketSerializer(serializers.ModelSerializer):
|
|
"""
|
|
A serializer for the Ticket model, returns data in the format as required by
|
|
datatables for ticket_list.html. Called from staff.datatables_ticket_list.
|
|
"""
|
|
ticket = serializers.SerializerMethodField()
|
|
assigned_to = serializers.SerializerMethodField()
|
|
submitter = serializers.SerializerMethodField()
|
|
created = serializers.SerializerMethodField()
|
|
due_date = serializers.SerializerMethodField()
|
|
status = serializers.SerializerMethodField()
|
|
row_class = serializers.SerializerMethodField()
|
|
time_spent = serializers.SerializerMethodField()
|
|
queue = serializers.SerializerMethodField()
|
|
kbitem = serializers.SerializerMethodField()
|
|
|
|
class Meta:
|
|
model = Ticket
|
|
# fields = '__all__'
|
|
fields = ('ticket', 'id', 'priority', 'title', 'queue', 'status',
|
|
'created', 'due_date', 'assigned_to', 'submitter', 'row_class',
|
|
'time_spent', 'kbitem')
|
|
|
|
def get_queue(self, obj):
|
|
return {"title": obj.queue.title, "id": obj.queue.id}
|
|
|
|
def get_ticket(self, obj):
|
|
return str(obj.id) + " " + obj.ticket
|
|
|
|
def get_status(self, obj):
|
|
return obj.get_status
|
|
|
|
def get_created(self, obj):
|
|
return humanize.naturaltime(obj.created)
|
|
|
|
def get_due_date(self, obj):
|
|
return humanize.naturaltime(obj.due_date)
|
|
|
|
def get_assigned_to(self, obj):
|
|
if obj.assigned_to:
|
|
if obj.assigned_to.get_full_name():
|
|
return obj.assigned_to.get_full_name()
|
|
elif obj.assigned_to.email:
|
|
return obj.assigned_to.email
|
|
else:
|
|
return obj.assigned_to.username
|
|
else:
|
|
return "None"
|
|
|
|
def get_submitter(self, obj):
|
|
return obj.submitter_email
|
|
|
|
def get_time_spent(self, obj):
|
|
return format_time_spent(obj.time_spent)
|
|
|
|
def get_row_class(self, obj):
|
|
return obj.get_priority_css_class
|
|
|
|
def get_kbitem(self, obj):
|
|
return obj.kbitem.title if obj.kbitem else ""
|
|
|
|
|
|
class FollowUpAttachmentSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = FollowUpAttachment
|
|
fields = ('id', 'followup', 'file', 'filename', 'mime_type', 'size')
|
|
|
|
|
|
class FollowUpSerializer(serializers.ModelSerializer):
|
|
followupattachment_set = FollowUpAttachmentSerializer(
|
|
many=True, read_only=True)
|
|
attachments = serializers.ListField(
|
|
child=serializers.FileField(),
|
|
write_only=True,
|
|
required=False
|
|
)
|
|
date = serializers.DateTimeField(read_only=True)
|
|
|
|
class Meta:
|
|
model = FollowUp
|
|
fields = (
|
|
'id', 'ticket', 'user', 'title', 'comment', 'public', 'new_status', 'extra_fields',
|
|
'time_spent', 'attachments', 'followupattachment_set', 'date', 'message_id',
|
|
)
|
|
|
|
def create(self, validated_data):
|
|
if validated_data["user"]:
|
|
user = validated_data["user"]
|
|
else:
|
|
user = self.context['request'].user
|
|
return update_ticket(
|
|
user=user,
|
|
ticket=validated_data["ticket"],
|
|
title=validated_data.get("title", None),
|
|
comment=validated_data.get("comment", ""),
|
|
files=validated_data.get("attachments", None),
|
|
public=validated_data.get("public", False),
|
|
new_status=validated_data.get("new_status", None),
|
|
time_spent=validated_data.get("time_spent", None),
|
|
extra_fields=validated_data.get("extra_fields", None),
|
|
)
|
|
|
|
|
|
class UserSerializer(serializers.ModelSerializer):
|
|
password = serializers.CharField(write_only=True)
|
|
|
|
class Meta:
|
|
model = get_user_model()
|
|
fields = ('first_name', 'last_name', 'username', 'email', 'password')
|
|
|
|
def create(self, validated_data):
|
|
user = super(UserSerializer, self).create(validated_data)
|
|
user.is_active = True
|
|
user.set_password(validated_data['password'])
|
|
user.save()
|
|
return user
|
|
|
|
|
|
class BaseTicketSerializer(serializers.ModelSerializer):
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
|
|
# Add custom fields
|
|
for field in CustomField.objects.all():
|
|
self.fields['custom_%s' % field.name] = field.build_api_field()
|
|
|
|
|
|
class PublicTicketListingSerializer(BaseTicketSerializer):
|
|
"""
|
|
A serializer to be used by the public API for listing tickets. Don't expose private fields here!
|
|
"""
|
|
ticket = serializers.SerializerMethodField()
|
|
submitter = serializers.SerializerMethodField()
|
|
created = serializers.SerializerMethodField()
|
|
due_date = serializers.SerializerMethodField()
|
|
status = serializers.SerializerMethodField()
|
|
queue = serializers.SerializerMethodField()
|
|
kbitem = serializers.SerializerMethodField()
|
|
secret_key = serializers.CharField(read_only=True)
|
|
|
|
class Meta:
|
|
model = Ticket
|
|
# fields = '__all__'
|
|
fields = ('ticket', 'id', 'title', 'queue', 'status',
|
|
'created', 'due_date', 'submitter', 'kbitem', 'secret_key')
|
|
|
|
def get_queue(self, obj):
|
|
return {"title": obj.queue.title, "id": obj.queue.id}
|
|
|
|
def get_ticket(self, obj):
|
|
return str(obj.id) + " " + obj.ticket
|
|
|
|
def get_status(self, obj):
|
|
return obj.get_status
|
|
|
|
def get_created(self, obj):
|
|
return humanize.naturaltime(obj.created)
|
|
|
|
def get_due_date(self, obj):
|
|
return humanize.naturaltime(obj.due_date)
|
|
|
|
def get_submitter(self, obj):
|
|
return obj.submitter_email
|
|
|
|
def get_kbitem(self, obj):
|
|
return obj.kbitem.title if obj.kbitem else ""
|
|
|
|
|
|
class TicketSerializer(BaseTicketSerializer):
|
|
followup_set = FollowUpSerializer(many=True, read_only=True)
|
|
attachment = serializers.FileField(write_only=True, required=False)
|
|
|
|
class Meta:
|
|
model = Ticket
|
|
fields = (
|
|
'id', 'queue', 'title', 'description', 'resolution', 'submitter_email', 'assigned_to', 'status', 'on_hold',
|
|
'priority', 'due_date', 'merged_to', 'attachment', 'followup_set'
|
|
)
|
|
|
|
def create(self, validated_data):
|
|
""" Use TicketForm to validate and create ticket """
|
|
queues = HelpdeskUser(self.context['request'].user).get_queues()
|
|
queue_choices = [(q.id, q.title) for q in queues]
|
|
data = validated_data.copy()
|
|
data['body'] = data['description']
|
|
# TicketForm needs id for ForeignKey (not the instance themselves)
|
|
data['queue'] = data['queue'].id
|
|
if data.get('assigned_to'):
|
|
data['assigned_to'] = data['assigned_to'].id
|
|
if data.get('merged_to'):
|
|
data['merged_to'] = data['merged_to'].id
|
|
|
|
files = {'attachment': data.pop('attachment', None)}
|
|
|
|
ticket_form = TicketForm(
|
|
data=data, files=files, queue_choices=queue_choices)
|
|
if ticket_form.is_valid():
|
|
ticket = ticket_form.save(user=self.context['request'].user)
|
|
ticket.set_custom_field_values()
|
|
return ticket
|
|
|
|
raise ValidationError(ticket_form.errors)
|
|
|
|
def update(self, instance, validated_data):
|
|
instance = super().update(instance, validated_data)
|
|
instance.save_custom_field_values(validated_data)
|
|
return instance
|