hospital-management/hr/api/serializers.py
2025-08-12 13:33:25 +03:00

221 lines
9.5 KiB
Python

from rest_framework import serializers
from ..models import (
Employee, Department, Schedule, ScheduleAssignment,
TimeEntry, PerformanceReview, TrainingRecord
)
class BaseSerializer(serializers.ModelSerializer):
"""Base serializer with common functionality"""
class Meta:
fields = ['id']
read_only_fields = ['created_at', 'updated_at']
class DepartmentSerializer(serializers.ModelSerializer):
"""Serializer for Department model"""
manager_name = serializers.CharField(source='manager.get_full_name', read_only=True)
employee_count = serializers.IntegerField(read_only=True)
class Meta:
model = Department
fields = [
'department_id', 'name', 'description', 'code', 'manager',
'manager_name', 'budget', 'location', 'phone', 'email',
'is_active', 'employee_count', 'created_at', 'updated_at'
]
read_only_fields = ['department_id', 'employee_count', 'created_at', 'updated_at']
class EmployeeSerializer(serializers.ModelSerializer):
"""Serializer for Employee model"""
department_name = serializers.CharField(source='department.name', read_only=True)
supervisor_name = serializers.CharField(source='supervisor.get_full_name', read_only=True)
employment_status_display = serializers.CharField(source='get_employment_status_display', read_only=True)
class Meta:
model = Employee
fields = [
'employee_id', 'employee_number', 'user', 'department', 'department_name',
'job_title', 'employment_status', 'employment_status_display',
'hire_date', 'termination_date', 'supervisor', 'supervisor_name',
'salary', 'hourly_rate', 'fte', 'is_active', 'emergency_contact_name',
'emergency_contact_phone', 'emergency_contact_relationship',
'created_at', 'updated_at'
]
read_only_fields = ['employee_id', 'employee_number', 'created_at', 'updated_at']
class ScheduleSerializer(serializers.ModelSerializer):
"""Serializer for Schedule model"""
created_by_name = serializers.CharField(source='created_by.get_full_name', read_only=True)
class Meta:
model = Schedule
fields = [
'schedule_id', 'name', 'description', 'start_date', 'end_date',
'is_published', 'created_by', 'created_by_name', 'notes',
'created_at', 'updated_at'
]
read_only_fields = ['schedule_id', 'created_at', 'updated_at']
class ScheduleAssignmentSerializer(serializers.ModelSerializer):
"""Serializer for ScheduleAssignment model"""
employee_name = serializers.CharField(source='employee.user.get_full_name', read_only=True)
schedule_name = serializers.CharField(source='schedule.name', read_only=True)
shift_type_display = serializers.CharField(source='get_shift_type_display', read_only=True)
duration_hours = serializers.FloatField(read_only=True)
class Meta:
model = ScheduleAssignment
fields = [
'assignment_id', 'schedule', 'schedule_name', 'employee', 'employee_name',
'date', 'start_time', 'end_time', 'duration_hours', 'shift_type',
'shift_type_display', 'location', 'notes', 'created_at', 'updated_at'
]
read_only_fields = ['assignment_id', 'duration_hours', 'created_at', 'updated_at']
class TimeEntrySerializer(serializers.ModelSerializer):
"""Serializer for TimeEntry model"""
employee_name = serializers.CharField(source='employee.user.get_full_name', read_only=True)
entry_type_display = serializers.CharField(source='get_entry_type_display', read_only=True)
hours_worked = serializers.FloatField(read_only=True)
class Meta:
model = TimeEntry
fields = [
'entry_id', 'employee', 'employee_name', 'date', 'clock_in_time',
'clock_out_time', 'break_start_time', 'break_end_time',
'hours_worked', 'entry_type', 'entry_type_display', 'notes',
'approved_by', 'approved_date', 'created_at', 'updated_at'
]
read_only_fields = ['entry_id', 'hours_worked', 'created_at', 'updated_at']
class PerformanceReviewSerializer(serializers.ModelSerializer):
"""Serializer for PerformanceReview model"""
employee_name = serializers.CharField(source='employee.user.get_full_name', read_only=True)
reviewer_name = serializers.CharField(source='reviewer.get_full_name', read_only=True)
review_type_display = serializers.CharField(source='get_review_type_display', read_only=True)
class Meta:
model = PerformanceReview
fields = [
'review_id', 'employee', 'employee_name', 'reviewer', 'reviewer_name',
'review_period_start', 'review_period_end', 'review_date',
'review_type', 'review_type_display', 'overall_rating',
'goals_achievements', 'strengths', 'areas_for_improvement',
'development_plan', 'comments', 'is_final', 'created_at', 'updated_at'
]
read_only_fields = ['review_id', 'created_at', 'updated_at']
class TrainingRecordSerializer(serializers.ModelSerializer):
"""Serializer for TrainingRecord model"""
employee_name = serializers.CharField(source='employee.user.get_full_name', read_only=True)
training_type_display = serializers.CharField(source='get_training_type_display', read_only=True)
status_display = serializers.CharField(source='get_status_display', read_only=True)
class Meta:
model = TrainingRecord
fields = [
'record_id', 'employee', 'employee_name', 'training_name',
'training_type', 'training_type_display', 'provider',
'start_date', 'completion_date', 'expiration_date',
'hours', 'cost', 'status', 'status_display', 'certificate_number',
'notes', 'created_at', 'updated_at'
]
read_only_fields = ['record_id', 'created_at', 'updated_at']
class HRStatsSerializer(serializers.Serializer):
"""Serializer for HR statistics"""
total_employees = serializers.IntegerField()
active_employees = serializers.IntegerField()
new_hires_this_month = serializers.IntegerField()
terminations_this_month = serializers.IntegerField()
attendance_rate = serializers.FloatField()
overtime_hours = serializers.FloatField()
training_completion_rate = serializers.FloatField()
department_breakdown = serializers.DictField()
employment_status_breakdown = serializers.DictField()
class ClockInOutSerializer(serializers.Serializer):
"""Serializer for clock in/out operations"""
employee_id = serializers.IntegerField()
action = serializers.ChoiceField(choices=['CLOCK_IN', 'CLOCK_OUT', 'BREAK_START', 'BREAK_END'])
notes = serializers.CharField(required=False, allow_blank=True)
def validate_employee_id(self, value):
"""Validate that the employee exists"""
try:
Employee.objects.get(id=value)
return value
except Employee.DoesNotExist:
raise serializers.ValidationError("Invalid employee ID.")
class ScheduleCreateSerializer(serializers.Serializer):
"""Serializer for creating schedules"""
name = serializers.CharField()
description = serializers.CharField(required=False, allow_blank=True)
start_date = serializers.DateField()
end_date = serializers.DateField()
assignments = serializers.ListField(
child=serializers.DictField(),
min_length=1
)
notes = serializers.CharField(required=False, allow_blank=True)
def validate(self, data):
"""Validate schedule data"""
if data['end_date'] <= data['start_date']:
raise serializers.ValidationError("End date must be after start date.")
return data
def validate_assignments(self, value):
"""Validate schedule assignments"""
for assignment in value:
required_fields = ['employee_id', 'date', 'start_time', 'end_time', 'shift_type']
for field in required_fields:
if field not in assignment:
raise serializers.ValidationError(f"Assignment missing required field: {field}")
return value
class PerformanceReviewCreateSerializer(serializers.Serializer):
"""Serializer for creating performance reviews"""
employee_id = serializers.IntegerField()
review_period_start = serializers.DateField()
review_period_end = serializers.DateField()
review_type = serializers.CharField()
overall_rating = serializers.IntegerField(min_value=1, max_value=5)
goals_achievements = serializers.CharField()
strengths = serializers.CharField()
areas_for_improvement = serializers.CharField()
development_plan = serializers.CharField()
comments = serializers.CharField(required=False, allow_blank=True)
def validate(self, data):
"""Validate review data"""
if data['review_period_end'] <= data['review_period_start']:
raise serializers.ValidationError("Review period end must be after start.")
return data
class TrainingRecordCreateSerializer(serializers.Serializer):
"""Serializer for creating training records"""
employee_id = serializers.IntegerField()
training_name = serializers.CharField()
training_type = serializers.CharField()
provider = serializers.CharField()
start_date = serializers.DateField()
hours = serializers.IntegerField(min_value=1)
cost = serializers.DecimalField(max_digits=10, decimal_places=2, required=False)
notes = serializers.CharField(required=False, allow_blank=True)