app.infrastructure.serializers

  1from drf_spectacular.utils import extend_schema_serializer, OpenApiExample
  2from rest_framework import serializers
  3from accounts.models import Hospital,Role,User
  4from management.models import Blocks , Shift,Ward
  5import time
  6from .models import ApproverHierarchy, ApproverLevel
  7
  8@extend_schema_serializer(
  9    examples=[
 10        OpenApiExample(
 11            'Hospital Example',
 12            value={
 13                "id": 1,
 14                "name": "General Hospital",
 15                "geolocation_point": "POINT(77.5946 12.9716)",
 16                "radius": 500,
 17                "address": "123 Main St"
 18            }
 19        )
 20    ]
 21)
 22class HospitalSerializer(serializers.ModelSerializer):
 23    """
 24    Serializer for hospital details.
 25
 26    Fields:
 27        - id: Hospital ID.
 28        - name: Hospital name.
 29        - geolocation_point: Geolocation as POINT string.
 30        - radius: Coverage radius.
 31        - address: Hospital address.
 32    """
 33    class Meta:
 34        model = Hospital
 35        fields = ['id','name','geolocation_point','radius', 'address']
 36        read_only_fields = ['id']
 37
 38@extend_schema_serializer(
 39    examples=[
 40        OpenApiExample(
 41            'Role Example',
 42            value={
 43                "id": 1,
 44                "name": "Doctor",
 45                "description": "Medical Doctor",
 46                "hospital": "General Hospital",
 47                "is_approver": True,
 48                "is_responder": False,
 49                "is_creator": True,
 50                "is_protected": False
 51            }
 52        )
 53    ]
 54)
 55class RoleSerializer(serializers.ModelSerializer):
 56    """
 57    Serializer for user roles within a hospital.
 58
 59    Fields:
 60        - id: Role ID.
 61        - name: Role name.
 62        - description: Role description.
 63        - hospital: Hospital name.
 64        - is_approver: Is role an approver.
 65        - is_responder: Is role a responder.
 66        - is_creator: Is role a creator.
 67        - is_protected: Is role protected.
 68    """
 69    hospital = serializers.CharField(source='hospital.name', read_only=True)
 70    class Meta:
 71        model = Role
 72        fields = ['id', 'name', 'description','hospital', 'is_approver', 'is_responder', 'is_creator', 'is_protected']
 73        read_only_fields = ['id','hospital']
 74
 75@extend_schema_serializer(
 76    examples=[
 77        OpenApiExample(
 78            'Hospital User Example',
 79            value={
 80                "id": 1,
 81                "institution_id": "EMP123",
 82                "role": 2,
 83                "role_name": "Doctor",
 84                "phone_number": "9876543210",
 85                "current_block": 1,
 86                "current_block_name": "Block A",
 87                "current_ward": 3,
 88                "current_ward_name": "Ward 3",
 89                "date_joined": "2025-09-20T12:00:00Z"
 90            }
 91        )
 92    ]
 93)
 94class HospitalUserSerializer(serializers.ModelSerializer):
 95    """
 96    Serializer for hospital users including role, block, and ward info.
 97
 98    Fields:
 99        - id: User ID.
100        - institution_id: Institution ID.
101        - role: Role ID.
102        - role_name: Role name.
103        - phone_number: User's phone number.
104        - password: Password (write-only).
105        - fcm_token: FCM token (write-only).
106        - current_block: Block ID.
107        - current_block_name: Block name.
108        - current_ward: Ward ID.
109        - current_ward_name: Ward name.
110        - date_joined: Date joined.
111    """
112    role = serializers.PrimaryKeyRelatedField(queryset=Role.objects.all())
113    password = serializers.CharField(write_only=True, required=False, allow_blank=True)
114    current_block = serializers.PrimaryKeyRelatedField(queryset=Blocks.objects.all(), required=False, allow_null=True)
115    fcm_token = serializers.CharField(write_only=True, required=False, allow_blank=True)
116    current_block_name = serializers.CharField(source='current_block.name', read_only=True)
117    current_ward = serializers.PrimaryKeyRelatedField(queryset=Ward.objects.all(), required=False, allow_null=True)
118    current_ward_name = serializers.CharField(source='current_ward.ward_name', read_only=True)
119    role_name = serializers.CharField(source='role.name', read_only=True)
120
121    class Meta:
122        model = User
123        fields = ['id', 'institution_id', 'role','role_name', 'phone_number', 'password','fcm_token','current_block','current_block_name','current_ward','current_ward_name','date_joined']
124        read_only_fields = ['id']
125        write_only_fields = ['fcm_token']
126        required_fields = ['institution_id', 'role', 'phone_number']
127
128    def create(self, validated_data):
129        """Create a hospital user and set password."""
130        hospital_id = self.context.get('hospital_id')
131        user = User.objects.create(
132            institution_id=validated_data['institution_id'],
133            role=validated_data['role'],
134            phone_number=validated_data['phone_number'],
135            hospital=Hospital.objects.get(id=hospital_id)
136        )
137        password = validated_data.get('password')
138        if password:
139            user.set_password(password)
140            user.password_set = True
141        else:
142            user.set_unusable_password()
143            user.password_set = False
144        user.save()
145        return user
146
147    def update(self, instance, validated_data):
148        """Update hospital user details and password."""
149        try:
150            hospital_id = self.context.get('hospital_id')
151            instance.institution_id = validated_data.get('institution_id', instance.institution_id)
152            instance.role = validated_data.get('role', instance.role)
153            instance.phone_number = validated_data.get('phone_number', instance.phone_number)
154            instance.current_block = validated_data.get('current_block', instance.current_block)
155            instance.fcm_token = validated_data.get('fcm_token', instance.fcm_token)
156            instance.fcm_token_updated = time.time()
157            password = validated_data.get('password')
158            if password:
159                instance.set_password(password)
160                instance.password_set = True
161            instance.save()
162            return instance
163        except Hospital.DoesNotExist:
164            raise serializers.ValidationError("Hospital does not exist.")
165        except Blocks.DoesNotExist:
166            raise serializers.ValidationError("Block does not exist.")
167
168@extend_schema_serializer(
169    examples=[
170        OpenApiExample(
171            'Block Example',
172            value={
173                "id": 1,
174                "name": "Block A",
175                "no_of_floors": 5,
176                "created_by": "EMP123",
177                "hospital": "General Hospital",
178                "hospital_id": 1,
179                "created_at": "2025-09-20T12:00:00Z",
180                "updated_at": "2025-09-21T12:00:00Z"
181            }
182        )
183    ]
184)
185class BlockSerializer(serializers.ModelSerializer):
186    """
187    Serializer for hospital blocks.
188
189    Fields:
190        - id: Block ID.
191        - name: Block name.
192        - no_of_floors: Number of floors.
193        - created_by: Institution ID of creator.
194        - hospital: Hospital name.
195        - hospital_id: Hospital ID.
196        - created_at: Creation timestamp.
197        - updated_at: Last update timestamp.
198    """
199    created_by = serializers.CharField(source='created_by.institution_id', read_only=True)
200    hospital = serializers.CharField(source='hospital.name', read_only=True)
201    hospital_id = serializers.IntegerField(source='hospital.id', read_only=True)
202    class Meta:
203        model = Blocks
204        fields = ['id', 'name', 'no_of_floors', 'created_by', 'hospital', 'hospital_id', 'created_at', 'updated_at']
205        read_only_fields = ['id', 'hospital']
206
207    def create(self, validated_data):
208        """Create a block for a hospital."""
209        hospital_id = self.context.get('hospital_id')
210        validated_data['hospital'] = Hospital.objects.get(id=hospital_id)
211        return super().create(validated_data)
212
213    def update(self, instance, validated_data):
214        """Update block details for a hospital."""
215        hospital_id = self.context.get('hospital_id')
216        instance.hospital = Hospital.objects.get(id=hospital_id)
217        return super().update(instance, validated_data)
218
219@extend_schema_serializer(
220    examples=[
221        OpenApiExample(
222            'Shift Example',
223            value={
224                "id": 1,
225                "name": "Morning Shift",
226                "start_time": "08:00:00",
227                "end_time": "16:00:00",
228                "hospital": "General Hospital",
229                "hospital_id": 1
230            }
231        )
232    ]
233)
234class ShiftSerializer(serializers.ModelSerializer):
235    """
236    Serializer for hospital shifts.
237
238    Fields:
239        - id: Shift ID.
240        - name: Shift name.
241        - start_time: Shift start time.
242        - end_time: Shift end time.
243        - hospital: Hospital name.
244        - hospital_id: Hospital ID.
245    """
246    hospital = serializers.CharField(source='hospital.name', read_only=True)
247    hospital_id = serializers.IntegerField(source='hospital.id', read_only=True)
248    class Meta:
249        model = Shift
250        fields = ['id', 'name', 'start_time', 'end_time', 'hospital','hospital_id']
251        read_only_fields = ['id', 'hospital']
252
253    def create(self, validated_data):
254        """Create a shift for a hospital."""
255        hospital_id = self.context.get('hospital_id')
256        validated_data['hospital'] = Hospital.objects.get(id=hospital_id)
257        return super().create(validated_data)
258
259    def update(self, instance, validated_data):
260        """Update shift details for a hospital."""
261        hospital_id = self.context.get('hospital_id')
262        instance.hospital = Hospital.objects.get(id=hospital_id)
263        return super().update(instance, validated_data)
264    
265@extend_schema_serializer(
266    examples=[
267        OpenApiExample(
268            'Ward Example',
269            value={
270                "id": 1,
271                "ward_name": "Ward 3",
272                "block": 1,
273                "block_name": "Block A",
274                "floor": 2,
275                "created_at": "2025-09-20T12:00:00Z",
276                "created_by": 5,
277                "created_by_name": "EMP123"
278            }
279        )
280    ]
281)
282class WardSerializer(serializers.ModelSerializer):
283    """
284    Serializer for hospital wards.
285
286    Fields:
287        - id: Ward ID.
288        - ward_name: Ward name.
289        - block: Block ID.
290        - block_name: Block name.
291        - floor: Floor number.
292        - created_at: Creation timestamp.
293        - created_by: User ID of creator.
294        - created_by_name: Institution ID of creator.
295    """
296    block = serializers.PrimaryKeyRelatedField(queryset=Blocks.objects.all())
297    block_name = serializers.CharField(source='block.name', read_only=True)
298    created_by_name = serializers.CharField(source='created_by.institution_id',read_only=True)
299    class Meta:
300        model = Ward
301        fields = ['id','ward_name','block','floor','created_at','created_by','created_by_name','block_name']
302        read_only = ['id']
303    def create(self, validated_data):
304        """Create a ward for a hospital."""
305        hospital_id = self.context.get('hospital_id')
306        return super().create(validated_data)
307
308    def update(self, instance, validated_data):
309        """Update ward details for a hospital."""
310        hospital_id = self.context.get('hospital_id')
311        return super().update(instance, validated_data)
312    
313    def validate(self, data):
314        """Validate that the floor is within the block's floor range."""
315        block = data.get('block')
316        floor = data.get('floor')
317        if block and floor:
318            if floor < 1 or floor > block.no_of_floors:
319                raise serializers.ValidationError({
320                    'floor': f"Floor must be between 1 and {block.no_of_floors} for the selected block."
321                })
322        return data
323
324@extend_schema_serializer(
325    examples=[
326        OpenApiExample(
327            'Approver Level Example',
328            value={
329                "id": 1,
330                "role": 2,
331                "role_name": "Doctor",
332                "priority": 1
333            }
334        )
335    ]
336)
337class ApproverLevelSerializer(serializers.ModelSerializer):
338    """
339    Serializer for approver levels within a hierarchy.
340
341    Fields:
342        - id: Level ID.
343        - role: Role ID.
344        - role_name: Role name.
345        - priority: Priority (lower means higher).
346    """
347    role_name = serializers.CharField(source='role.name', read_only=True)
348    class Meta:
349        model = ApproverLevel
350        fields = ['id', 'role', 'role_name', 'priority']
351        read_only_fields = ['id', 'role_name']
352
353@extend_schema_serializer(
354    examples=[
355        OpenApiExample(
356            'Approver Hierarchy Example',
357            value={
358                "id": 1,
359                "is_active": True,
360                "levels": [
361                    {"id": 1, "role": 2, "role_name": "Doctor", "priority": 1}
362                ],
363                "created_at": "2025-09-20T12:00:00Z"
364            }
365        )
366    ]
367)
368class ApproverHierarchySerializer(serializers.ModelSerializer):
369    """
370    Serializer for approver hierarchy with levels.
371
372    Fields:
373        - id: Hierarchy ID.
374        - is_active: Is hierarchy active.
375        - levels: List of approver levels.
376        - created_at: Creation timestamp.
377    """
378    levels = ApproverLevelSerializer(many=True)
379    class Meta:
380        model = ApproverHierarchy
381        fields = ['id', 'is_active', 'levels', 'created_at']
382        read_only_fields = ['id', 'created_at']
383
384    def validate_levels(self, value):
385        """Ensure at least one level is provided."""
386        if not value:
387            raise serializers.ValidationError("At least one level is required")
388        return value
389
390    def create(self, validated_data):
391        """Create an approver hierarchy with levels."""
392        levels_data = validated_data.pop('levels')
393        hierarchy = ApproverHierarchy.objects.create(**validated_data)
394        for lvl in levels_data:
395            ApproverLevel.objects.create(hierarchy=hierarchy, **lvl)
396        return hierarchy
397
398    def update(self, instance, validated_data):
399        """Update approver hierarchy and its levels."""
400        levels_data = validated_data.pop('levels', None)
401        instance.is_active = validated_data.get('is_active', instance.is_active)
402        instance.save()
403        if levels_data is not None:
404            instance.levels.all().delete()
405            for lvl in levels_data:
406                ApproverLevel.objects.create(hierarchy=instance, **lvl)
407        return instance
@extend_schema_serializer(examples=[OpenApiExample('Hospital Example', value={'id': 1, 'name': 'General Hospital', 'geolocation_point': 'POINT(77.5946 12.9716)', 'radius': 500, 'address': '123 Main St'})])
class HospitalSerializer(rest_framework.serializers.ModelSerializer):
 9@extend_schema_serializer(
10    examples=[
11        OpenApiExample(
12            'Hospital Example',
13            value={
14                "id": 1,
15                "name": "General Hospital",
16                "geolocation_point": "POINT(77.5946 12.9716)",
17                "radius": 500,
18                "address": "123 Main St"
19            }
20        )
21    ]
22)
23class HospitalSerializer(serializers.ModelSerializer):
24    """
25    Serializer for hospital details.
26
27    Fields:
28        - id: Hospital ID.
29        - name: Hospital name.
30        - geolocation_point: Geolocation as POINT string.
31        - radius: Coverage radius.
32        - address: Hospital address.
33    """
34    class Meta:
35        model = Hospital
36        fields = ['id','name','geolocation_point','radius', 'address']
37        read_only_fields = ['id']

Serializer for hospital details.

Fields: - id: Hospital ID. - name: Hospital name. - geolocation_point: Geolocation as POINT string. - radius: Coverage radius. - address: Hospital address.

class HospitalSerializer.Meta:
34    class Meta:
35        model = Hospital
36        fields = ['id','name','geolocation_point','radius', 'address']
37        read_only_fields = ['id']
model = <class 'accounts.models.Hospital'>
fields = ['id', 'name', 'geolocation_point', 'radius', 'address']
read_only_fields = ['id']
@extend_schema_serializer(examples=[OpenApiExample('Role Example', value={'id': 1, 'name': 'Doctor', 'description': 'Medical Doctor', 'hospital': 'General Hospital', 'is_approver': True, 'is_responder': False, 'is_creator': True, 'is_protected': False})])
class RoleSerializer(rest_framework.serializers.ModelSerializer):
39@extend_schema_serializer(
40    examples=[
41        OpenApiExample(
42            'Role Example',
43            value={
44                "id": 1,
45                "name": "Doctor",
46                "description": "Medical Doctor",
47                "hospital": "General Hospital",
48                "is_approver": True,
49                "is_responder": False,
50                "is_creator": True,
51                "is_protected": False
52            }
53        )
54    ]
55)
56class RoleSerializer(serializers.ModelSerializer):
57    """
58    Serializer for user roles within a hospital.
59
60    Fields:
61        - id: Role ID.
62        - name: Role name.
63        - description: Role description.
64        - hospital: Hospital name.
65        - is_approver: Is role an approver.
66        - is_responder: Is role a responder.
67        - is_creator: Is role a creator.
68        - is_protected: Is role protected.
69    """
70    hospital = serializers.CharField(source='hospital.name', read_only=True)
71    class Meta:
72        model = Role
73        fields = ['id', 'name', 'description','hospital', 'is_approver', 'is_responder', 'is_creator', 'is_protected']
74        read_only_fields = ['id','hospital']

Serializer for user roles within a hospital.

Fields: - id: Role ID. - name: Role name. - description: Role description. - hospital: Hospital name. - is_approver: Is role an approver. - is_responder: Is role a responder. - is_creator: Is role a creator. - is_protected: Is role protected.

hospital
class RoleSerializer.Meta:
71    class Meta:
72        model = Role
73        fields = ['id', 'name', 'description','hospital', 'is_approver', 'is_responder', 'is_creator', 'is_protected']
74        read_only_fields = ['id','hospital']
model = <class 'accounts.models.Role'>
fields = ['id', 'name', 'description', 'hospital', 'is_approver', 'is_responder', 'is_creator', 'is_protected']
read_only_fields = ['id', 'hospital']
@extend_schema_serializer(examples=[OpenApiExample('Hospital User Example', value={'id': 1, 'institution_id': 'EMP123', 'role': 2, 'role_name': 'Doctor', 'phone_number': '9876543210', 'current_block': 1, 'current_block_name': 'Block A', 'current_ward': 3, 'current_ward_name': 'Ward 3', 'date_joined': '2025-09-20T12:00:00Z'})])
class HospitalUserSerializer(rest_framework.serializers.ModelSerializer):
 76@extend_schema_serializer(
 77    examples=[
 78        OpenApiExample(
 79            'Hospital User Example',
 80            value={
 81                "id": 1,
 82                "institution_id": "EMP123",
 83                "role": 2,
 84                "role_name": "Doctor",
 85                "phone_number": "9876543210",
 86                "current_block": 1,
 87                "current_block_name": "Block A",
 88                "current_ward": 3,
 89                "current_ward_name": "Ward 3",
 90                "date_joined": "2025-09-20T12:00:00Z"
 91            }
 92        )
 93    ]
 94)
 95class HospitalUserSerializer(serializers.ModelSerializer):
 96    """
 97    Serializer for hospital users including role, block, and ward info.
 98
 99    Fields:
100        - id: User ID.
101        - institution_id: Institution ID.
102        - role: Role ID.
103        - role_name: Role name.
104        - phone_number: User's phone number.
105        - password: Password (write-only).
106        - fcm_token: FCM token (write-only).
107        - current_block: Block ID.
108        - current_block_name: Block name.
109        - current_ward: Ward ID.
110        - current_ward_name: Ward name.
111        - date_joined: Date joined.
112    """
113    role = serializers.PrimaryKeyRelatedField(queryset=Role.objects.all())
114    password = serializers.CharField(write_only=True, required=False, allow_blank=True)
115    current_block = serializers.PrimaryKeyRelatedField(queryset=Blocks.objects.all(), required=False, allow_null=True)
116    fcm_token = serializers.CharField(write_only=True, required=False, allow_blank=True)
117    current_block_name = serializers.CharField(source='current_block.name', read_only=True)
118    current_ward = serializers.PrimaryKeyRelatedField(queryset=Ward.objects.all(), required=False, allow_null=True)
119    current_ward_name = serializers.CharField(source='current_ward.ward_name', read_only=True)
120    role_name = serializers.CharField(source='role.name', read_only=True)
121
122    class Meta:
123        model = User
124        fields = ['id', 'institution_id', 'role','role_name', 'phone_number', 'password','fcm_token','current_block','current_block_name','current_ward','current_ward_name','date_joined']
125        read_only_fields = ['id']
126        write_only_fields = ['fcm_token']
127        required_fields = ['institution_id', 'role', 'phone_number']
128
129    def create(self, validated_data):
130        """Create a hospital user and set password."""
131        hospital_id = self.context.get('hospital_id')
132        user = User.objects.create(
133            institution_id=validated_data['institution_id'],
134            role=validated_data['role'],
135            phone_number=validated_data['phone_number'],
136            hospital=Hospital.objects.get(id=hospital_id)
137        )
138        password = validated_data.get('password')
139        if password:
140            user.set_password(password)
141            user.password_set = True
142        else:
143            user.set_unusable_password()
144            user.password_set = False
145        user.save()
146        return user
147
148    def update(self, instance, validated_data):
149        """Update hospital user details and password."""
150        try:
151            hospital_id = self.context.get('hospital_id')
152            instance.institution_id = validated_data.get('institution_id', instance.institution_id)
153            instance.role = validated_data.get('role', instance.role)
154            instance.phone_number = validated_data.get('phone_number', instance.phone_number)
155            instance.current_block = validated_data.get('current_block', instance.current_block)
156            instance.fcm_token = validated_data.get('fcm_token', instance.fcm_token)
157            instance.fcm_token_updated = time.time()
158            password = validated_data.get('password')
159            if password:
160                instance.set_password(password)
161                instance.password_set = True
162            instance.save()
163            return instance
164        except Hospital.DoesNotExist:
165            raise serializers.ValidationError("Hospital does not exist.")
166        except Blocks.DoesNotExist:
167            raise serializers.ValidationError("Block does not exist.")

Serializer for hospital users including role, block, and ward info.

Fields: - id: User ID. - institution_id: Institution ID. - role: Role ID. - role_name: Role name. - phone_number: User's phone number. - password: Password (write-only). - fcm_token: FCM token (write-only). - current_block: Block ID. - current_block_name: Block name. - current_ward: Ward ID. - current_ward_name: Ward name. - date_joined: Date joined.

role
password
current_block
fcm_token
current_block_name
current_ward
current_ward_name
role_name
def create(self, validated_data):
129    def create(self, validated_data):
130        """Create a hospital user and set password."""
131        hospital_id = self.context.get('hospital_id')
132        user = User.objects.create(
133            institution_id=validated_data['institution_id'],
134            role=validated_data['role'],
135            phone_number=validated_data['phone_number'],
136            hospital=Hospital.objects.get(id=hospital_id)
137        )
138        password = validated_data.get('password')
139        if password:
140            user.set_password(password)
141            user.password_set = True
142        else:
143            user.set_unusable_password()
144            user.password_set = False
145        user.save()
146        return user

Create a hospital user and set password.

def update(self, instance, validated_data):
148    def update(self, instance, validated_data):
149        """Update hospital user details and password."""
150        try:
151            hospital_id = self.context.get('hospital_id')
152            instance.institution_id = validated_data.get('institution_id', instance.institution_id)
153            instance.role = validated_data.get('role', instance.role)
154            instance.phone_number = validated_data.get('phone_number', instance.phone_number)
155            instance.current_block = validated_data.get('current_block', instance.current_block)
156            instance.fcm_token = validated_data.get('fcm_token', instance.fcm_token)
157            instance.fcm_token_updated = time.time()
158            password = validated_data.get('password')
159            if password:
160                instance.set_password(password)
161                instance.password_set = True
162            instance.save()
163            return instance
164        except Hospital.DoesNotExist:
165            raise serializers.ValidationError("Hospital does not exist.")
166        except Blocks.DoesNotExist:
167            raise serializers.ValidationError("Block does not exist.")

Update hospital user details and password.

class HospitalUserSerializer.Meta:
122    class Meta:
123        model = User
124        fields = ['id', 'institution_id', 'role','role_name', 'phone_number', 'password','fcm_token','current_block','current_block_name','current_ward','current_ward_name','date_joined']
125        read_only_fields = ['id']
126        write_only_fields = ['fcm_token']
127        required_fields = ['institution_id', 'role', 'phone_number']
model = <class 'accounts.models.User'>
fields = ['id', 'institution_id', 'role', 'role_name', 'phone_number', 'password', 'fcm_token', 'current_block', 'current_block_name', 'current_ward', 'current_ward_name', 'date_joined']
read_only_fields = ['id']
write_only_fields = ['fcm_token']
required_fields = ['institution_id', 'role', 'phone_number']
@extend_schema_serializer(examples=[OpenApiExample('Block Example', value={'id': 1, 'name': 'Block A', 'no_of_floors': 5, 'created_by': 'EMP123', 'hospital': 'General Hospital', 'hospital_id': 1, 'created_at': '2025-09-20T12:00:00Z', 'updated_at': '2025-09-21T12:00:00Z'})])
class BlockSerializer(rest_framework.serializers.ModelSerializer):
169@extend_schema_serializer(
170    examples=[
171        OpenApiExample(
172            'Block Example',
173            value={
174                "id": 1,
175                "name": "Block A",
176                "no_of_floors": 5,
177                "created_by": "EMP123",
178                "hospital": "General Hospital",
179                "hospital_id": 1,
180                "created_at": "2025-09-20T12:00:00Z",
181                "updated_at": "2025-09-21T12:00:00Z"
182            }
183        )
184    ]
185)
186class BlockSerializer(serializers.ModelSerializer):
187    """
188    Serializer for hospital blocks.
189
190    Fields:
191        - id: Block ID.
192        - name: Block name.
193        - no_of_floors: Number of floors.
194        - created_by: Institution ID of creator.
195        - hospital: Hospital name.
196        - hospital_id: Hospital ID.
197        - created_at: Creation timestamp.
198        - updated_at: Last update timestamp.
199    """
200    created_by = serializers.CharField(source='created_by.institution_id', read_only=True)
201    hospital = serializers.CharField(source='hospital.name', read_only=True)
202    hospital_id = serializers.IntegerField(source='hospital.id', read_only=True)
203    class Meta:
204        model = Blocks
205        fields = ['id', 'name', 'no_of_floors', 'created_by', 'hospital', 'hospital_id', 'created_at', 'updated_at']
206        read_only_fields = ['id', 'hospital']
207
208    def create(self, validated_data):
209        """Create a block for a hospital."""
210        hospital_id = self.context.get('hospital_id')
211        validated_data['hospital'] = Hospital.objects.get(id=hospital_id)
212        return super().create(validated_data)
213
214    def update(self, instance, validated_data):
215        """Update block details for a hospital."""
216        hospital_id = self.context.get('hospital_id')
217        instance.hospital = Hospital.objects.get(id=hospital_id)
218        return super().update(instance, validated_data)

Serializer for hospital blocks.

Fields: - id: Block ID. - name: Block name. - no_of_floors: Number of floors. - created_by: Institution ID of creator. - hospital: Hospital name. - hospital_id: Hospital ID. - created_at: Creation timestamp. - updated_at: Last update timestamp.

created_by
hospital
hospital_id
def create(self, validated_data):
208    def create(self, validated_data):
209        """Create a block for a hospital."""
210        hospital_id = self.context.get('hospital_id')
211        validated_data['hospital'] = Hospital.objects.get(id=hospital_id)
212        return super().create(validated_data)

Create a block for a hospital.

def update(self, instance, validated_data):
214    def update(self, instance, validated_data):
215        """Update block details for a hospital."""
216        hospital_id = self.context.get('hospital_id')
217        instance.hospital = Hospital.objects.get(id=hospital_id)
218        return super().update(instance, validated_data)

Update block details for a hospital.

class BlockSerializer.Meta:
203    class Meta:
204        model = Blocks
205        fields = ['id', 'name', 'no_of_floors', 'created_by', 'hospital', 'hospital_id', 'created_at', 'updated_at']
206        read_only_fields = ['id', 'hospital']
model = <class 'management.models.Blocks'>
fields = ['id', 'name', 'no_of_floors', 'created_by', 'hospital', 'hospital_id', 'created_at', 'updated_at']
read_only_fields = ['id', 'hospital']
@extend_schema_serializer(examples=[OpenApiExample('Shift Example', value={'id': 1, 'name': 'Morning Shift', 'start_time': '08:00:00', 'end_time': '16:00:00', 'hospital': 'General Hospital', 'hospital_id': 1})])
class ShiftSerializer(rest_framework.serializers.ModelSerializer):
220@extend_schema_serializer(
221    examples=[
222        OpenApiExample(
223            'Shift Example',
224            value={
225                "id": 1,
226                "name": "Morning Shift",
227                "start_time": "08:00:00",
228                "end_time": "16:00:00",
229                "hospital": "General Hospital",
230                "hospital_id": 1
231            }
232        )
233    ]
234)
235class ShiftSerializer(serializers.ModelSerializer):
236    """
237    Serializer for hospital shifts.
238
239    Fields:
240        - id: Shift ID.
241        - name: Shift name.
242        - start_time: Shift start time.
243        - end_time: Shift end time.
244        - hospital: Hospital name.
245        - hospital_id: Hospital ID.
246    """
247    hospital = serializers.CharField(source='hospital.name', read_only=True)
248    hospital_id = serializers.IntegerField(source='hospital.id', read_only=True)
249    class Meta:
250        model = Shift
251        fields = ['id', 'name', 'start_time', 'end_time', 'hospital','hospital_id']
252        read_only_fields = ['id', 'hospital']
253
254    def create(self, validated_data):
255        """Create a shift for a hospital."""
256        hospital_id = self.context.get('hospital_id')
257        validated_data['hospital'] = Hospital.objects.get(id=hospital_id)
258        return super().create(validated_data)
259
260    def update(self, instance, validated_data):
261        """Update shift details for a hospital."""
262        hospital_id = self.context.get('hospital_id')
263        instance.hospital = Hospital.objects.get(id=hospital_id)
264        return super().update(instance, validated_data)

Serializer for hospital shifts.

Fields: - id: Shift ID. - name: Shift name. - start_time: Shift start time. - end_time: Shift end time. - hospital: Hospital name. - hospital_id: Hospital ID.

hospital
hospital_id
def create(self, validated_data):
254    def create(self, validated_data):
255        """Create a shift for a hospital."""
256        hospital_id = self.context.get('hospital_id')
257        validated_data['hospital'] = Hospital.objects.get(id=hospital_id)
258        return super().create(validated_data)

Create a shift for a hospital.

def update(self, instance, validated_data):
260    def update(self, instance, validated_data):
261        """Update shift details for a hospital."""
262        hospital_id = self.context.get('hospital_id')
263        instance.hospital = Hospital.objects.get(id=hospital_id)
264        return super().update(instance, validated_data)

Update shift details for a hospital.

class ShiftSerializer.Meta:
249    class Meta:
250        model = Shift
251        fields = ['id', 'name', 'start_time', 'end_time', 'hospital','hospital_id']
252        read_only_fields = ['id', 'hospital']
model = <class 'management.models.Shift'>
fields = ['id', 'name', 'start_time', 'end_time', 'hospital', 'hospital_id']
read_only_fields = ['id', 'hospital']
@extend_schema_serializer(examples=[OpenApiExample('Ward Example', value={'id': 1, 'ward_name': 'Ward 3', 'block': 1, 'block_name': 'Block A', 'floor': 2, 'created_at': '2025-09-20T12:00:00Z', 'created_by': 5, 'created_by_name': 'EMP123'})])
class WardSerializer(rest_framework.serializers.ModelSerializer):
266@extend_schema_serializer(
267    examples=[
268        OpenApiExample(
269            'Ward Example',
270            value={
271                "id": 1,
272                "ward_name": "Ward 3",
273                "block": 1,
274                "block_name": "Block A",
275                "floor": 2,
276                "created_at": "2025-09-20T12:00:00Z",
277                "created_by": 5,
278                "created_by_name": "EMP123"
279            }
280        )
281    ]
282)
283class WardSerializer(serializers.ModelSerializer):
284    """
285    Serializer for hospital wards.
286
287    Fields:
288        - id: Ward ID.
289        - ward_name: Ward name.
290        - block: Block ID.
291        - block_name: Block name.
292        - floor: Floor number.
293        - created_at: Creation timestamp.
294        - created_by: User ID of creator.
295        - created_by_name: Institution ID of creator.
296    """
297    block = serializers.PrimaryKeyRelatedField(queryset=Blocks.objects.all())
298    block_name = serializers.CharField(source='block.name', read_only=True)
299    created_by_name = serializers.CharField(source='created_by.institution_id',read_only=True)
300    class Meta:
301        model = Ward
302        fields = ['id','ward_name','block','floor','created_at','created_by','created_by_name','block_name']
303        read_only = ['id']
304    def create(self, validated_data):
305        """Create a ward for a hospital."""
306        hospital_id = self.context.get('hospital_id')
307        return super().create(validated_data)
308
309    def update(self, instance, validated_data):
310        """Update ward details for a hospital."""
311        hospital_id = self.context.get('hospital_id')
312        return super().update(instance, validated_data)
313    
314    def validate(self, data):
315        """Validate that the floor is within the block's floor range."""
316        block = data.get('block')
317        floor = data.get('floor')
318        if block and floor:
319            if floor < 1 or floor > block.no_of_floors:
320                raise serializers.ValidationError({
321                    'floor': f"Floor must be between 1 and {block.no_of_floors} for the selected block."
322                })
323        return data

Serializer for hospital wards.

Fields: - id: Ward ID. - ward_name: Ward name. - block: Block ID. - block_name: Block name. - floor: Floor number. - created_at: Creation timestamp. - created_by: User ID of creator. - created_by_name: Institution ID of creator.

block
block_name
created_by_name
def create(self, validated_data):
304    def create(self, validated_data):
305        """Create a ward for a hospital."""
306        hospital_id = self.context.get('hospital_id')
307        return super().create(validated_data)

Create a ward for a hospital.

def update(self, instance, validated_data):
309    def update(self, instance, validated_data):
310        """Update ward details for a hospital."""
311        hospital_id = self.context.get('hospital_id')
312        return super().update(instance, validated_data)

Update ward details for a hospital.

def validate(self, data):
314    def validate(self, data):
315        """Validate that the floor is within the block's floor range."""
316        block = data.get('block')
317        floor = data.get('floor')
318        if block and floor:
319            if floor < 1 or floor > block.no_of_floors:
320                raise serializers.ValidationError({
321                    'floor': f"Floor must be between 1 and {block.no_of_floors} for the selected block."
322                })
323        return data

Validate that the floor is within the block's floor range.

class WardSerializer.Meta:
300    class Meta:
301        model = Ward
302        fields = ['id','ward_name','block','floor','created_at','created_by','created_by_name','block_name']
303        read_only = ['id']
model = <class 'management.models.Ward'>
fields = ['id', 'ward_name', 'block', 'floor', 'created_at', 'created_by', 'created_by_name', 'block_name']
read_only = ['id']
@extend_schema_serializer(examples=[OpenApiExample('Approver Level Example', value={'id': 1, 'role': 2, 'role_name': 'Doctor', 'priority': 1})])
class ApproverLevelSerializer(rest_framework.serializers.ModelSerializer):
325@extend_schema_serializer(
326    examples=[
327        OpenApiExample(
328            'Approver Level Example',
329            value={
330                "id": 1,
331                "role": 2,
332                "role_name": "Doctor",
333                "priority": 1
334            }
335        )
336    ]
337)
338class ApproverLevelSerializer(serializers.ModelSerializer):
339    """
340    Serializer for approver levels within a hierarchy.
341
342    Fields:
343        - id: Level ID.
344        - role: Role ID.
345        - role_name: Role name.
346        - priority: Priority (lower means higher).
347    """
348    role_name = serializers.CharField(source='role.name', read_only=True)
349    class Meta:
350        model = ApproverLevel
351        fields = ['id', 'role', 'role_name', 'priority']
352        read_only_fields = ['id', 'role_name']

Serializer for approver levels within a hierarchy.

Fields: - id: Level ID. - role: Role ID. - role_name: Role name. - priority: Priority (lower means higher).

role_name
class ApproverLevelSerializer.Meta:
349    class Meta:
350        model = ApproverLevel
351        fields = ['id', 'role', 'role_name', 'priority']
352        read_only_fields = ['id', 'role_name']
fields = ['id', 'role', 'role_name', 'priority']
read_only_fields = ['id', 'role_name']
@extend_schema_serializer(examples=[OpenApiExample('Approver Hierarchy Example', value={'id': 1, 'is_active': True, 'levels': [{'id': 1, 'role': 2, 'role_name': 'Doctor', 'priority': 1}], 'created_at': '2025-09-20T12:00:00Z'})])
class ApproverHierarchySerializer(rest_framework.serializers.ModelSerializer):
354@extend_schema_serializer(
355    examples=[
356        OpenApiExample(
357            'Approver Hierarchy Example',
358            value={
359                "id": 1,
360                "is_active": True,
361                "levels": [
362                    {"id": 1, "role": 2, "role_name": "Doctor", "priority": 1}
363                ],
364                "created_at": "2025-09-20T12:00:00Z"
365            }
366        )
367    ]
368)
369class ApproverHierarchySerializer(serializers.ModelSerializer):
370    """
371    Serializer for approver hierarchy with levels.
372
373    Fields:
374        - id: Hierarchy ID.
375        - is_active: Is hierarchy active.
376        - levels: List of approver levels.
377        - created_at: Creation timestamp.
378    """
379    levels = ApproverLevelSerializer(many=True)
380    class Meta:
381        model = ApproverHierarchy
382        fields = ['id', 'is_active', 'levels', 'created_at']
383        read_only_fields = ['id', 'created_at']
384
385    def validate_levels(self, value):
386        """Ensure at least one level is provided."""
387        if not value:
388            raise serializers.ValidationError("At least one level is required")
389        return value
390
391    def create(self, validated_data):
392        """Create an approver hierarchy with levels."""
393        levels_data = validated_data.pop('levels')
394        hierarchy = ApproverHierarchy.objects.create(**validated_data)
395        for lvl in levels_data:
396            ApproverLevel.objects.create(hierarchy=hierarchy, **lvl)
397        return hierarchy
398
399    def update(self, instance, validated_data):
400        """Update approver hierarchy and its levels."""
401        levels_data = validated_data.pop('levels', None)
402        instance.is_active = validated_data.get('is_active', instance.is_active)
403        instance.save()
404        if levels_data is not None:
405            instance.levels.all().delete()
406            for lvl in levels_data:
407                ApproverLevel.objects.create(hierarchy=instance, **lvl)
408        return instance

Serializer for approver hierarchy with levels.

Fields: - id: Hierarchy ID. - is_active: Is hierarchy active. - levels: List of approver levels. - created_at: Creation timestamp.

levels
def validate_levels(self, value):
385    def validate_levels(self, value):
386        """Ensure at least one level is provided."""
387        if not value:
388            raise serializers.ValidationError("At least one level is required")
389        return value

Ensure at least one level is provided.

def create(self, validated_data):
391    def create(self, validated_data):
392        """Create an approver hierarchy with levels."""
393        levels_data = validated_data.pop('levels')
394        hierarchy = ApproverHierarchy.objects.create(**validated_data)
395        for lvl in levels_data:
396            ApproverLevel.objects.create(hierarchy=hierarchy, **lvl)
397        return hierarchy

Create an approver hierarchy with levels.

def update(self, instance, validated_data):
399    def update(self, instance, validated_data):
400        """Update approver hierarchy and its levels."""
401        levels_data = validated_data.pop('levels', None)
402        instance.is_active = validated_data.get('is_active', instance.is_active)
403        instance.save()
404        if levels_data is not None:
405            instance.levels.all().delete()
406            for lvl in levels_data:
407                ApproverLevel.objects.create(hierarchy=instance, **lvl)
408        return instance

Update approver hierarchy and its levels.

class ApproverHierarchySerializer.Meta:
380    class Meta:
381        model = ApproverHierarchy
382        fields = ['id', 'is_active', 'levels', 'created_at']
383        read_only_fields = ['id', 'created_at']
fields = ['id', 'is_active', 'levels', 'created_at']
read_only_fields = ['id', 'created_at']