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

261 lines
12 KiB
Python

from rest_framework import serializers
from django.contrib.auth import get_user_model
from ..models import (
QualityIndicator, QualityMeasurement, IncidentReport,
RiskAssessment, AuditPlan, AuditFinding, ImprovementProject
)
User = get_user_model()
class QualityIndicatorSerializer(serializers.ModelSerializer):
"""Serializer for quality indicators"""
responsible_department_name = serializers.CharField(source='responsible_department.name', read_only=True)
responsible_user_name = serializers.CharField(source='responsible_user.get_full_name', read_only=True)
current_status = serializers.CharField(read_only=True)
latest_measurement = serializers.SerializerMethodField()
class Meta:
model = QualityIndicator
fields = [
'id', 'name', 'description', 'category', 'type', 'measurement_unit',
'target_value', 'threshold_warning', 'threshold_critical',
'calculation_method', 'data_source', 'frequency',
'responsible_department', 'responsible_department_name',
'responsible_user', 'responsible_user_name',
'is_active', 'regulatory_requirement', 'current_status',
'latest_measurement', 'created_at', 'updated_at'
]
read_only_fields = ['created_at', 'updated_at', 'current_status']
def get_latest_measurement(self, obj):
"""Get the latest measurement for this indicator"""
latest = obj.latest_measurement
if latest:
return {
'id': latest.id,
'measurement_date': latest.measurement_date,
'value': latest.value,
'status': latest.status
}
return None
class QualityMeasurementSerializer(serializers.ModelSerializer):
"""Serializer for quality measurements"""
indicator_name = serializers.CharField(source='indicator.name', read_only=True)
verified_by_name = serializers.CharField(source='verified_by.get_full_name', read_only=True)
created_by_name = serializers.CharField(source='created_by.get_full_name', read_only=True)
class Meta:
model = QualityMeasurement
fields = [
'id', 'indicator', 'indicator_name', 'measurement_date', 'value',
'numerator', 'denominator', 'status', 'notes', 'data_source_reference',
'verified_by', 'verified_by_name', 'verified_at',
'created_by', 'created_by_name', 'created_at', 'updated_at'
]
read_only_fields = ['created_by', 'created_at', 'updated_at']
def create(self, validated_data):
"""Set the created_by field to the current user"""
validated_data['created_by'] = self.context['request'].user
validated_data['tenant'] = self.context['request'].user.tenant
return super().create(validated_data)
class IncidentReportSerializer(serializers.ModelSerializer):
"""Serializer for incident reports"""
patient_name = serializers.CharField(source='patient.full_name', read_only=True)
reported_by_name = serializers.CharField(source='reported_by.get_full_name', read_only=True)
assigned_to_name = serializers.CharField(source='assigned_to.get_full_name', read_only=True)
class Meta:
model = IncidentReport
fields = [
'id', 'incident_number', 'title', 'description', 'incident_type',
'severity', 'category', 'location', 'incident_date', 'discovered_date',
'patient', 'patient_name', 'reported_by', 'reported_by_name',
'status', 'priority', 'root_cause', 'contributing_factors',
'corrective_actions', 'preventive_actions',
'assigned_to', 'assigned_to_name', 'due_date', 'closed_date',
'is_confidential', 'regulatory_notification',
'created_at', 'updated_at'
]
read_only_fields = ['incident_number', 'reported_by', 'created_at', 'updated_at']
def create(self, validated_data):
"""Set the reported_by field to the current user"""
validated_data['reported_by'] = self.context['request'].user
validated_data['tenant'] = self.context['request'].user.tenant
return super().create(validated_data)
class RiskAssessmentSerializer(serializers.ModelSerializer):
"""Serializer for risk assessments"""
responsible_person_name = serializers.CharField(source='responsible_person.get_full_name', read_only=True)
created_by_name = serializers.CharField(source='created_by.get_full_name', read_only=True)
incident_report_number = serializers.CharField(source='incident_report.incident_number', read_only=True)
class Meta:
model = RiskAssessment
fields = [
'id', 'title', 'description', 'risk_category', 'risk_type',
'likelihood', 'impact', 'risk_score', 'risk_level',
'current_controls', 'control_effectiveness',
'residual_likelihood', 'residual_impact', 'residual_risk_score', 'residual_risk_level',
'mitigation_plan', 'responsible_person', 'responsible_person_name',
'review_date', 'status', 'incident_report', 'incident_report_number',
'created_by', 'created_by_name', 'created_at', 'updated_at'
]
read_only_fields = [
'risk_score', 'risk_level', 'residual_risk_score', 'residual_risk_level',
'created_by', 'created_at', 'updated_at'
]
def create(self, validated_data):
"""Set the created_by field to the current user"""
validated_data['created_by'] = self.context['request'].user
validated_data['tenant'] = self.context['request'].user.tenant
return super().create(validated_data)
class AuditFindingSerializer(serializers.ModelSerializer):
"""Serializer for audit findings"""
audit_plan_title = serializers.CharField(source='audit_plan.title', read_only=True)
responsible_person_name = serializers.CharField(source='responsible_person.get_full_name', read_only=True)
verified_by_name = serializers.CharField(source='verified_by.get_full_name', read_only=True)
created_by_name = serializers.CharField(source='created_by.get_full_name', read_only=True)
class Meta:
model = AuditFinding
fields = [
'id', 'audit_plan', 'audit_plan_title', 'finding_number', 'title', 'description',
'finding_type', 'severity', 'category', 'criteria_reference', 'evidence',
'root_cause', 'corrective_action_required', 'corrective_action_plan',
'responsible_person', 'responsible_person_name',
'target_completion_date', 'actual_completion_date', 'status',
'verification_method', 'verified_by', 'verified_by_name', 'verified_date',
'created_by', 'created_by_name', 'created_at', 'updated_at'
]
read_only_fields = ['finding_number', 'created_by', 'created_at', 'updated_at']
def create(self, validated_data):
"""Set the created_by field to the current user"""
validated_data['created_by'] = self.context['request'].user
validated_data['tenant'] = self.context['request'].user.tenant
return super().create(validated_data)
class AuditPlanSerializer(serializers.ModelSerializer):
"""Serializer for audit plans"""
department_name = serializers.CharField(source='department.name', read_only=True)
auditor_name = serializers.CharField(source='auditor.get_full_name', read_only=True)
audit_team_names = serializers.SerializerMethodField()
created_by_name = serializers.CharField(source='created_by.get_full_name', read_only=True)
findings_count = serializers.IntegerField(read_only=True)
open_findings_count = serializers.IntegerField(read_only=True)
findings = AuditFindingSerializer(many=True, read_only=True)
class Meta:
model = AuditPlan
fields = [
'id', 'title', 'description', 'audit_type', 'scope', 'criteria',
'department', 'department_name', 'auditor', 'auditor_name',
'audit_team', 'audit_team_names',
'planned_start_date', 'planned_end_date', 'actual_start_date', 'actual_end_date',
'status', 'priority', 'regulatory_requirement', 'accreditation_body',
'findings_count', 'open_findings_count', 'findings',
'created_by', 'created_by_name', 'created_at', 'updated_at'
]
read_only_fields = ['findings_count', 'open_findings_count', 'created_by', 'created_at', 'updated_at']
def get_audit_team_names(self, obj):
"""Get names of audit team members"""
return [member.get_full_name() or member.username for member in obj.audit_team.all()]
def create(self, validated_data):
"""Set the created_by field to the current user"""
audit_team = validated_data.pop('audit_team', [])
validated_data['created_by'] = self.context['request'].user
validated_data['tenant'] = self.context['request'].user.tenant
audit_plan = super().create(validated_data)
audit_plan.audit_team.set(audit_team)
return audit_plan
class ImprovementProjectSerializer(serializers.ModelSerializer):
"""Serializer for improvement projects"""
project_manager_name = serializers.CharField(source='project_manager.get_full_name', read_only=True)
sponsor_name = serializers.CharField(source='sponsor.get_full_name', read_only=True)
department_name = serializers.CharField(source='department.name', read_only=True)
project_team_names = serializers.SerializerMethodField()
created_by_name = serializers.CharField(source='created_by.get_full_name', read_only=True)
duration_planned = serializers.IntegerField(read_only=True)
duration_actual = serializers.IntegerField(read_only=True)
class Meta:
model = ImprovementProject
fields = [
'id', 'project_number', 'title', 'description', 'project_type', 'methodology',
'problem_statement', 'goal_statement', 'success_metrics',
'baseline_data', 'target_metrics', 'scope',
'project_manager', 'project_manager_name',
'project_team', 'project_team_names',
'sponsor', 'sponsor_name', 'department', 'department_name',
'planned_start_date', 'planned_end_date', 'actual_start_date', 'actual_end_date',
'status', 'phase', 'budget', 'actual_cost', 'roi_expected', 'roi_actual',
'lessons_learned', 'sustainability_plan', 'duration_planned', 'duration_actual',
'created_by', 'created_by_name', 'created_at', 'updated_at'
]
read_only_fields = [
'project_number', 'duration_planned', 'duration_actual',
'created_by', 'created_at', 'updated_at'
]
def get_project_team_names(self, obj):
"""Get names of project team members"""
return [member.get_full_name() or member.username for member in obj.project_team.all()]
def create(self, validated_data):
"""Set the created_by field to the current user"""
project_team = validated_data.pop('project_team', [])
validated_data['created_by'] = self.context['request'].user
validated_data['tenant'] = self.context['request'].user.tenant
project = super().create(validated_data)
project.project_team.set(project_team)
return project
# Summary serializers for dashboard and reporting
class QualityMetricsSummarySerializer(serializers.Serializer):
"""Serializer for quality metrics summary"""
indicators_count = serializers.IntegerField()
critical_count = serializers.IntegerField()
warning_count = serializers.IntegerField()
open_incidents_count = serializers.IntegerField()
recent_incidents_count = serializers.IntegerField()
high_risks_count = serializers.IntegerField()
active_audits_count = serializers.IntegerField()
upcoming_audits_count = serializers.IntegerField()
active_projects_count = serializers.IntegerField()
class IncidentTrendSerializer(serializers.Serializer):
"""Serializer for incident trend data"""
date = serializers.DateField()
count = serializers.IntegerField()
severity_breakdown = serializers.DictField()
class RiskMatrixSerializer(serializers.Serializer):
"""Serializer for risk matrix data"""
likelihood = serializers.CharField()
impact = serializers.CharField()
risk_count = serializers.IntegerField()
risks = RiskAssessmentSerializer(many=True)