289 lines
12 KiB
Python
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.")
|
|
|