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)