2025-08-12 13:33:25 +03:00

289 lines
12 KiB
Python

from rest_framework import serializers
from ..models import (
Message, MessageRecipient, NotificationTemplate, AlertRule,
AlertInstance, CommunicationChannel, DeliveryLog
)
class BaseSerializer(serializers.ModelSerializer):
"""Base serializer with common functionality"""
class Meta:
fields = ['id']
read_only_fields = ['created_at', 'updated_at']
class CommunicationChannelSerializer(serializers.ModelSerializer):
"""Serializer for CommunicationChannel model"""
channel_type_display = serializers.CharField(source='get_channel_type_display', read_only=True)
class Meta:
model = CommunicationChannel
fields = [
'channel_id', 'name', 'description', 'channel_type', 'channel_type_display',
'configuration', 'is_active', 'is_default', 'priority',
'created_at', 'updated_at'
]
read_only_fields = ['channel_id', 'created_at', 'updated_at']
class NotificationTemplateSerializer(serializers.ModelSerializer):
"""Serializer for NotificationTemplate model"""
template_type_display = serializers.CharField(source='get_template_type_display', read_only=True)
class Meta:
model = NotificationTemplate
fields = [
'template_id', 'name', 'description', 'template_type', 'template_type_display',
'subject_template', 'body_template', 'variables', 'is_active',
'created_at', 'updated_at'
]
read_only_fields = ['template_id', 'created_at', 'updated_at']
class MessageRecipientSerializer(serializers.ModelSerializer):
"""Serializer for MessageRecipient model"""
recipient_name = serializers.CharField(source='recipient.get_full_name', read_only=True)
status_display = serializers.CharField(source='get_status_display', read_only=True)
class Meta:
model = MessageRecipient
fields = [
'recipient_id', 'message', 'recipient', 'recipient_name',
'status', 'status_display', 'delivered_at', 'read_at',
'created_at', 'updated_at'
]
read_only_fields = ['recipient_id', 'created_at', 'updated_at']
class MessageSerializer(serializers.ModelSerializer):
"""Serializer for Message model"""
sender_name = serializers.CharField(source='sender.get_full_name', read_only=True)
message_type_display = serializers.CharField(source='get_message_type_display', read_only=True)
priority_display = serializers.CharField(source='get_priority_display', read_only=True)
recipients = MessageRecipientSerializer(many=True, read_only=True)
recipient_count = serializers.IntegerField(read_only=True)
delivered_count = serializers.IntegerField(read_only=True)
read_count = serializers.IntegerField(read_only=True)
class Meta:
model = Message
fields = [
'message_id', 'sender', 'sender_name', 'subject', 'body',
'message_type', 'message_type_display', 'priority', 'priority_display',
'scheduled_at', 'sent_at', 'expires_at', 'is_draft',
'recipients', 'recipient_count', 'delivered_count', 'read_count',
'created_at', 'updated_at'
]
read_only_fields = [
'message_id', 'recipient_count', 'delivered_count', 'read_count',
'created_at', 'updated_at'
]
class AlertRuleSerializer(serializers.ModelSerializer):
"""Serializer for AlertRule model"""
rule_type_display = serializers.CharField(source='get_rule_type_display', read_only=True)
severity_display = serializers.CharField(source='get_severity_display', read_only=True)
class Meta:
model = AlertRule
fields = [
'rule_id', 'name', 'description', 'rule_type', 'rule_type_display',
'conditions', 'severity', 'severity_display', 'notification_template',
'recipients', 'is_active', 'cooldown_minutes', 'created_at', 'updated_at'
]
read_only_fields = ['rule_id', 'created_at', 'updated_at']
class AlertInstanceSerializer(serializers.ModelSerializer):
"""Serializer for AlertInstance model"""
rule_name = serializers.CharField(source='rule.name', read_only=True)
severity_display = serializers.CharField(source='get_severity_display', read_only=True)
status_display = serializers.CharField(source='get_status_display', read_only=True)
class Meta:
model = AlertInstance
fields = [
'alert_id', 'rule', 'rule_name', 'title', 'description',
'severity', 'severity_display', 'status', 'status_display',
'triggered_at', 'acknowledged_at', 'resolved_at',
'acknowledged_by', 'resolved_by', 'data', 'created_at', 'updated_at'
]
read_only_fields = ['alert_id', 'created_at', 'updated_at']
class DeliveryLogSerializer(serializers.ModelSerializer):
"""Serializer for DeliveryLog model"""
channel_name = serializers.CharField(source='channel.name', read_only=True)
status_display = serializers.CharField(source='get_status_display', read_only=True)
class Meta:
model = DeliveryLog
fields = [
'log_id', 'message', 'recipient', 'channel', 'channel_name',
'status', 'status_display', 'attempt_count', 'last_attempt_at',
'delivered_at', 'error_message', 'created_at', 'updated_at'
]
read_only_fields = ['log_id', 'created_at', 'updated_at']
class CommunicationsStatsSerializer(serializers.Serializer):
"""Serializer for communications statistics"""
total_messages = serializers.IntegerField()
messages_today = serializers.IntegerField()
pending_messages = serializers.IntegerField()
delivered_messages = serializers.IntegerField()
failed_messages = serializers.IntegerField()
active_alerts = serializers.IntegerField()
delivery_rate = serializers.FloatField()
message_types = serializers.DictField()
channel_usage = serializers.DictField()
class MessageCreateSerializer(serializers.Serializer):
"""Serializer for creating messages"""
subject = serializers.CharField()
body = serializers.CharField()
message_type = serializers.CharField()
priority = serializers.CharField(default='NORMAL')
recipients = serializers.ListField(
child=serializers.IntegerField(),
min_length=1
)
scheduled_at = serializers.DateTimeField(required=False)
expires_at = serializers.DateTimeField(required=False)
is_draft = serializers.BooleanField(default=False)
def validate_recipients(self, value):
"""Validate recipient user IDs"""
from django.contrib.auth import get_user_model
User = get_user_model()
valid_users = User.objects.filter(id__in=value).count()
if valid_users != len(value):
raise serializers.ValidationError("Some recipient IDs are invalid.")
return value
def validate(self, data):
"""Validate message data"""
if data.get('scheduled_at') and data.get('expires_at'):
if data['expires_at'] <= data['scheduled_at']:
raise serializers.ValidationError("Expiry time must be after scheduled time.")
return data
class BulkMessageSerializer(serializers.Serializer):
"""Serializer for bulk messaging"""
subject = serializers.CharField()
body = serializers.CharField()
message_type = serializers.CharField()
priority = serializers.CharField(default='NORMAL')
recipient_groups = serializers.ListField(
child=serializers.CharField(),
min_length=1
)
template_id = serializers.IntegerField(required=False)
template_variables = serializers.JSONField(required=False)
def validate_recipient_groups(self, value):
"""Validate recipient groups"""
valid_groups = ['ALL_STAFF', 'DOCTORS', 'NURSES', 'ADMINISTRATORS', 'DEPARTMENT_HEADS']
for group in value:
if group not in valid_groups:
raise serializers.ValidationError(f"Invalid recipient group: {group}")
return value
class AlertCreateSerializer(serializers.Serializer):
"""Serializer for creating alerts"""
rule_id = serializers.IntegerField()
title = serializers.CharField()
description = serializers.CharField()
severity = serializers.CharField()
data = serializers.JSONField(required=False)
def validate_rule_id(self, value):
"""Validate that the alert rule exists and is active"""
try:
rule = AlertRule.objects.get(id=value)
if not rule.is_active:
raise serializers.ValidationError("Alert rule is not active.")
return value
except AlertRule.DoesNotExist:
raise serializers.ValidationError("Invalid alert rule ID.")
class AlertAcknowledgeSerializer(serializers.Serializer):
"""Serializer for acknowledging alerts"""
alert_id = serializers.IntegerField()
notes = serializers.CharField(required=False, allow_blank=True)
def validate_alert_id(self, value):
"""Validate that the alert exists and can be acknowledged"""
try:
alert = AlertInstance.objects.get(id=value)
if alert.status != 'ACTIVE':
raise serializers.ValidationError("Alert is not in active status.")
return value
except AlertInstance.DoesNotExist:
raise serializers.ValidationError("Invalid alert ID.")
class AlertResolveSerializer(serializers.Serializer):
"""Serializer for resolving alerts"""
alert_id = serializers.IntegerField()
resolution_notes = serializers.CharField()
def validate_alert_id(self, value):
"""Validate that the alert exists and can be resolved"""
try:
alert = AlertInstance.objects.get(id=value)
if alert.status == 'RESOLVED':
raise serializers.ValidationError("Alert is already resolved.")
return value
except AlertInstance.DoesNotExist:
raise serializers.ValidationError("Invalid alert ID.")
class NotificationSendSerializer(serializers.Serializer):
"""Serializer for sending notifications"""
template_id = serializers.IntegerField()
recipients = serializers.ListField(
child=serializers.IntegerField(),
min_length=1
)
variables = serializers.JSONField(required=False)
channel_ids = serializers.ListField(
child=serializers.IntegerField(),
required=False
)
def validate_template_id(self, value):
"""Validate that the template exists and is active"""
try:
template = NotificationTemplate.objects.get(id=value)
if not template.is_active:
raise serializers.ValidationError("Notification template is not active.")
return value
except NotificationTemplate.DoesNotExist:
raise serializers.ValidationError("Invalid template ID.")
class ChannelTestSerializer(serializers.Serializer):
"""Serializer for testing communication channels"""
channel_id = serializers.IntegerField()
test_message = serializers.CharField(default="Test message from hospital management system")
test_recipient = serializers.CharField()
def validate_channel_id(self, value):
"""Validate that the channel exists and is active"""
try:
channel = CommunicationChannel.objects.get(id=value)
if not channel.is_active:
raise serializers.ValidationError("Communication channel is not active.")
return value
except CommunicationChannel.DoesNotExist:
raise serializers.ValidationError("Invalid channel ID.")