update
This commit is contained in:
204
gnx-react/backend/support/serializers.py
Normal file
204
gnx-react/backend/support/serializers.py
Normal file
@@ -0,0 +1,204 @@
|
||||
from rest_framework import serializers
|
||||
from .models import (
|
||||
SupportTicket, TicketStatus, TicketPriority, TicketCategory,
|
||||
TicketMessage, TicketActivity, KnowledgeBaseCategory,
|
||||
KnowledgeBaseArticle, SupportSettings
|
||||
)
|
||||
from .email_service import SupportEmailService
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TicketStatusSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = TicketStatus
|
||||
fields = ['id', 'name', 'color', 'description', 'is_closed', 'display_order']
|
||||
|
||||
|
||||
class TicketPrioritySerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = TicketPriority
|
||||
fields = ['id', 'name', 'level', 'color', 'description', 'sla_hours']
|
||||
|
||||
|
||||
class TicketCategorySerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = TicketCategory
|
||||
fields = ['id', 'name', 'description', 'color', 'icon', 'display_order']
|
||||
|
||||
|
||||
class TicketMessageSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = TicketMessage
|
||||
fields = [
|
||||
'id', 'ticket', 'message_type', 'content', 'author_name',
|
||||
'author_email', 'is_internal', 'created_at', 'updated_at',
|
||||
'attachments', 'is_read'
|
||||
]
|
||||
read_only_fields = ['created_at', 'updated_at']
|
||||
|
||||
|
||||
class TicketActivitySerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = TicketActivity
|
||||
fields = [
|
||||
'id', 'activity_type', 'description', 'user_name',
|
||||
'old_value', 'new_value', 'created_at'
|
||||
]
|
||||
read_only_fields = ['created_at']
|
||||
|
||||
|
||||
class SupportTicketSerializer(serializers.ModelSerializer):
|
||||
status_name = serializers.CharField(source='status.name', read_only=True)
|
||||
status_color = serializers.CharField(source='status.color', read_only=True)
|
||||
priority_name = serializers.CharField(source='priority.name', read_only=True)
|
||||
priority_color = serializers.CharField(source='priority.color', read_only=True)
|
||||
category_name = serializers.CharField(source='category.name', read_only=True)
|
||||
messages = TicketMessageSerializer(many=True, read_only=True)
|
||||
activities = TicketActivitySerializer(many=True, read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = SupportTicket
|
||||
fields = [
|
||||
'id', 'ticket_number', 'title', 'description', 'ticket_type',
|
||||
'user_name', 'user_email', 'user_phone', 'company',
|
||||
'category', 'category_name', 'priority', 'priority_name', 'priority_color',
|
||||
'status', 'status_name', 'status_color', 'assigned_to', 'assigned_at',
|
||||
'created_at', 'updated_at', 'closed_at', 'last_activity',
|
||||
'first_response_at', 'sla_deadline', 'tags', 'is_escalated',
|
||||
'escalation_reason', 'attachments', 'messages', 'activities'
|
||||
]
|
||||
read_only_fields = [
|
||||
'ticket_number', 'created_at', 'updated_at', 'last_activity',
|
||||
'assigned_at', 'closed_at', 'first_response_at', 'sla_deadline'
|
||||
]
|
||||
|
||||
|
||||
class SupportTicketCreateSerializer(serializers.ModelSerializer):
|
||||
"""Simplified serializer for creating tickets from public form"""
|
||||
ticket_number = serializers.CharField(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = SupportTicket
|
||||
fields = [
|
||||
'ticket_number', 'title', 'description', 'ticket_type', 'user_name',
|
||||
'user_email', 'user_phone', 'company', 'category'
|
||||
]
|
||||
read_only_fields = ['ticket_number']
|
||||
|
||||
def validate_user_email(self, value):
|
||||
"""
|
||||
Validate that the email is registered and active in the RegisteredEmail model
|
||||
"""
|
||||
from .models import RegisteredEmail
|
||||
|
||||
# Check if email exists and is active in RegisteredEmail model
|
||||
try:
|
||||
registered_email = RegisteredEmail.objects.get(email=value)
|
||||
if not registered_email.is_active:
|
||||
raise serializers.ValidationError(
|
||||
"This email has been deactivated. "
|
||||
"Please contact us at support@gnxsoft.com for assistance."
|
||||
)
|
||||
except RegisteredEmail.DoesNotExist:
|
||||
raise serializers.ValidationError(
|
||||
"This email is not registered in our system. "
|
||||
"Please contact us at support@gnxsoft.com to register your email first."
|
||||
)
|
||||
|
||||
return value
|
||||
|
||||
def create(self, validated_data):
|
||||
from .models import RegisteredEmail
|
||||
|
||||
# Set default status and priority if not set
|
||||
if not validated_data.get('status'):
|
||||
default_status = TicketStatus.objects.filter(name='Open').first()
|
||||
if default_status:
|
||||
validated_data['status'] = default_status
|
||||
|
||||
if not validated_data.get('priority'):
|
||||
default_priority = TicketPriority.objects.filter(name='Medium').first()
|
||||
if default_priority:
|
||||
validated_data['priority'] = default_priority
|
||||
|
||||
ticket = SupportTicket.objects.create(**validated_data)
|
||||
|
||||
# Create initial activity
|
||||
TicketActivity.objects.create(
|
||||
ticket=ticket,
|
||||
activity_type='created',
|
||||
description=f'Ticket created by {ticket.user_name}',
|
||||
user_name=ticket.user_name
|
||||
)
|
||||
|
||||
# Update registered email statistics
|
||||
try:
|
||||
registered_email = RegisteredEmail.objects.get(email=validated_data['user_email'])
|
||||
registered_email.increment_ticket_count()
|
||||
except RegisteredEmail.DoesNotExist:
|
||||
logger.warning(f'RegisteredEmail not found for {validated_data["user_email"]} after validation')
|
||||
|
||||
# Send email notifications
|
||||
try:
|
||||
email_results = SupportEmailService.send_ticket_created_emails(ticket)
|
||||
logger.info(f'Email notifications sent for ticket {ticket.ticket_number}: {email_results}')
|
||||
except Exception as e:
|
||||
logger.error(f'Failed to send email notifications for ticket {ticket.ticket_number}: {str(e)}')
|
||||
# Don't fail ticket creation if emails fail
|
||||
|
||||
return ticket
|
||||
|
||||
|
||||
class TicketStatusCheckSerializer(serializers.Serializer):
|
||||
"""Serializer for checking ticket status by ticket number"""
|
||||
ticket_number = serializers.CharField(max_length=20)
|
||||
|
||||
|
||||
class KnowledgeBaseCategorySerializer(serializers.ModelSerializer):
|
||||
article_count = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = KnowledgeBaseCategory
|
||||
fields = [
|
||||
'id', 'name', 'slug', 'description', 'icon', 'color',
|
||||
'display_order', 'article_count'
|
||||
]
|
||||
|
||||
def get_article_count(self, obj):
|
||||
return obj.articles.filter(is_published=True).count()
|
||||
|
||||
|
||||
class KnowledgeBaseArticleListSerializer(serializers.ModelSerializer):
|
||||
category_name = serializers.CharField(source='category.name', read_only=True)
|
||||
category_slug = serializers.CharField(source='category.slug', read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = KnowledgeBaseArticle
|
||||
fields = [
|
||||
'id', 'title', 'slug', 'category', 'category_name', 'category_slug',
|
||||
'summary', 'is_featured', 'view_count', 'helpful_count',
|
||||
'not_helpful_count', 'created_at', 'updated_at', 'published_at'
|
||||
]
|
||||
|
||||
|
||||
class KnowledgeBaseArticleDetailSerializer(serializers.ModelSerializer):
|
||||
category_name = serializers.CharField(source='category.name', read_only=True)
|
||||
category_slug = serializers.CharField(source='category.slug', read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = KnowledgeBaseArticle
|
||||
fields = [
|
||||
'id', 'title', 'slug', 'category', 'category_name', 'category_slug',
|
||||
'content', 'summary', 'meta_description', 'keywords',
|
||||
'is_featured', 'view_count', 'helpful_count', 'not_helpful_count',
|
||||
'created_at', 'updated_at', 'published_at'
|
||||
]
|
||||
|
||||
|
||||
class SupportSettingsSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = SupportSettings
|
||||
fields = ['id', 'setting_name', 'setting_value', 'description', 'is_active']
|
||||
|
||||
Reference in New Issue
Block a user