app.infrastructure.views
Infrastructure API views for hospital management.
Endpoints documented:
- /api/hospitals/ : Hospital CRUD
- /api/hospitals/{hospital_pk}/roles/ : Role CRUD for a hospital
- /api/hospitals/{hospital_pk}/users/ : Hospital user CRUD
- /api/hospitals/{hospital_pk}/shifts/ : Shift CRUD for a hospital
- /api/hospitals/{hospital_pk}/blocks/ : Block CRUD for a hospital
- /api/hospitals/{hospital_pk}/hierarchies/ : Approver hierarchy CRUD
- /api/hospitals/{hospital_pk}/wards/ : Ward CRUD for a hospital
- /api/set-password/ : Change user password
- /api/switch-block/ : Switch user's current block
- /api/switch-ward/ : Switch user's current ward
Each endpoint is documented with drf-spectacular's @extend_schema for OpenAPI generation.
1""" 2Infrastructure API views for hospital management. 3 4Endpoints documented: 5- /api/hospitals/ : Hospital CRUD 6- /api/hospitals/{hospital_pk}/roles/ : Role CRUD for a hospital 7- /api/hospitals/{hospital_pk}/users/ : Hospital user CRUD 8- /api/hospitals/{hospital_pk}/shifts/ : Shift CRUD for a hospital 9- /api/hospitals/{hospital_pk}/blocks/ : Block CRUD for a hospital 10- /api/hospitals/{hospital_pk}/hierarchies/ : Approver hierarchy CRUD 11- /api/hospitals/{hospital_pk}/wards/ : Ward CRUD for a hospital 12- /api/set-password/ : Change user password 13- /api/switch-block/ : Switch user's current block 14- /api/switch-ward/ : Switch user's current ward 15 16Each endpoint is documented with drf-spectacular's @extend_schema for OpenAPI generation. 17""" 18 19from rest_framework import viewsets, status 20from rest_framework.views import APIView 21from .serializers import HospitalSerializer, RoleSerializer, HospitalUserSerializer, ShiftSerializer, BlockSerializer, WardSerializer, ApproverHierarchySerializer 22from accounts.models import Hospital, User, Role 23from management.models import Shift, Blocks, Ward 24from .models import ApproverHierarchy, ApproverLevel, BlockChange, WardChange 25from .permissions import IsHospitalUserOrSuperUser, RoleEditPermission, UserPermission, WardPermission 26from rest_framework.response import Response 27from rest_framework.permissions import IsAuthenticated 28from drf_spectacular.utils import extend_schema, OpenApiTypes, OpenApiParameter, OpenApiResponse 29from rest_framework.decorators import action 30from django_filters.rest_framework import DjangoFilterBackend 31 32@extend_schema( 33 summary="Hospital CRUD", 34 description="Create, retrieve, update, and list hospitals.", 35 responses={200: HospitalSerializer(many=True)} 36) 37class HospitalViewSet(viewsets.ModelViewSet): 38 """ 39 ViewSet for hospital CRUD operations. 40 """ 41 serializer_class = HospitalSerializer 42 permission_classes = [IsHospitalUserOrSuperUser] 43 44 def get_queryset(self): 45 print(self.kwargs) 46 user = self.request.user 47 return Hospital.objects.filter() 48 49 def get_serializer_context(self): 50 context = super().get_serializer_context() 51 context['hospital_id'] = self.kwargs.get('pk') 52 return context 53 54 def destroy(self, request, *args, **kwargs): 55 return Response({"detail": "Deletion not allowed."}, status=405) 56 57@extend_schema( 58 summary="Change user's password", 59 description="Change password by providing phone and new password.", 60 parameters=[ 61 OpenApiParameter(name="phone", type=str, location="query", required=True, description="User's phone number"), 62 OpenApiParameter(name="password", type=str, location="query", required=True, description="New password"), 63 ], 64 responses={ 65 200: OpenApiResponse(description="Password changed successfully."), 66 404: OpenApiResponse(description="User not found."), 67 400: OpenApiResponse(description="Bad request."), 68 }, 69) 70class PasswordChangeViewSet(APIView): 71 """ 72 APIView to change a user's password. 73 """ 74 permission_classes = [] 75 76 @extend_schema( 77 summary="Change user's password", 78 description="This endpoint allows a user to change their password by providing their phone number and new password.", 79 parameters=[ 80 OpenApiParameter(name="phone", type=str, location="query", required=True, description="User's phone number"), 81 OpenApiParameter(name="password", type=str, location="query", required=True, description="New password"), 82 ], 83 responses={ 84 200: OpenApiResponse(description="Password changed successfully."), 85 404: OpenApiResponse(description="User not found."), 86 400: OpenApiResponse(description="Bad request."), 87 }, 88 ) 89 def post(self, request, *args, **kwargs): 90 try: 91 phone = request.data.get('phone') 92 password = request.data.get('password') 93 94 user = User.objects.get(phone_number=phone) 95 user.set_password(password) 96 user.save() 97 return Response({"detail": "Password changed successfully."}, status=200) 98 except User.DoesNotExist: 99 return Response({"detail": "User not found."}, status=404) 100 except Exception as e: 101 return Response({"detail": str(e)}, status=400) 102 103@extend_schema( 104 summary="Role CRUD", 105 description="Create, retrieve, update, and list roles for a hospital.", 106 responses={200: RoleSerializer(many=True)} 107) 108class RoleViewSet(viewsets.ModelViewSet): 109 """ 110 ViewSet for role CRUD operations within a hospital. 111 """ 112 serializer_class = RoleSerializer 113 permission_classes = [IsAuthenticated, RoleEditPermission] 114 lookup_field = 'id' 115 116 def get_queryset(self): 117 hospital_id = self.kwargs.get('hospital_pk') 118 print("KWARGS:", self.kwargs) 119 if self.request.query_params.get('is_responder') is not None: 120 return Role.objects.filter( 121 hospital__id=hospital_id, 122 is_responder=True 123 ) 124 return Role.objects.filter(hospital__id=hospital_id) 125 126 def get_serializer_context(self): 127 context = super().get_serializer_context() 128 context['hospital_id'] = self.kwargs.get('hospital_pk') 129 return context 130 131 def perform_create(self, serializer): 132 hospital_id = self.kwargs.get('hospital_pk') 133 serializer.save(hospital_id=hospital_id) 134 135 def destroy(self, request, *args, **kwargs): 136 instance = self.get_object() 137 self.perform_destroy(instance) 138 return Response({"detail": "Role deleted successfully."}, status=status.HTTP_204_NO_CONTENT) 139 140@extend_schema( 141 summary="Hospital User CRUD", 142 description="Create, retrieve, update, and list hospital users.", 143 responses={200: HospitalUserSerializer(many=True)} 144) 145class HospitalUserViewSet(viewsets.ModelViewSet): 146 """ 147 ViewSet for hospital user CRUD operations. 148 """ 149 serializer_class = HospitalUserSerializer 150 permission_classes = [IsAuthenticated, UserPermission] 151 lookup_field = 'id' 152 153 def get_queryset(self): 154 return User.objects.filter(hospital__id=self.kwargs.get('hospital_pk')).exclude(is_superuser=True) 155 156 def get_serializer_context(self): 157 context = super().get_serializer_context() 158 context['hospital_id'] = self.kwargs.get('hospital_pk') 159 return context 160 161@extend_schema( 162 summary="Block CRUD", 163 description="Create, retrieve, update, and list blocks for a hospital.", 164 responses={200: BlockSerializer(many=True)} 165) 166class BlockViewSet(viewsets.ModelViewSet): 167 """ 168 ViewSet for block CRUD operations within a hospital. 169 """ 170 serializer_class = BlockSerializer 171 permission_classes = [IsAuthenticated, RoleEditPermission] 172 lookup_field = 'id' 173 174 def get_queryset(self): 175 return Blocks.objects.filter(hospital_id=self.kwargs.get('hospital_pk')) 176 177 def get_serializer_context(self): 178 context = super().get_serializer_context() 179 context['hospital_id'] = self.kwargs.get('hospital_pk') 180 return context 181 182 def perform_create(self, serializer): 183 serializer.save( 184 hospital_id=self.kwargs.get('hospital_pk'), 185 created_by=self.request.user 186 ) 187 188@extend_schema( 189 summary="Shift CRUD", 190 description="Create, retrieve, update, and list shifts for a hospital.", 191 responses={200: ShiftSerializer(many=True)} 192) 193class ShiftViewSet(viewsets.ModelViewSet): 194 """ 195 ViewSet for shift CRUD operations within a hospital. 196 """ 197 serializer_class = ShiftSerializer 198 permission_classes = [IsAuthenticated, RoleEditPermission] 199 lookup_field = 'id' 200 201 def get_queryset(self): 202 return Shift.objects.filter(hospital_id=self.kwargs.get('hospital_pk')) 203 204 def get_serializer_context(self): 205 context = super().get_serializer_context() 206 context['hospital_id'] = self.kwargs.get('hospital_pk') 207 return context 208 209 def perform_create(self, serializer): 210 serializer.save( 211 hospital_id=self.kwargs.get('hospital_pk'), 212 created_by=self.request.user 213 ) 214 215 def destroy(self, request, *args, **kwargs): 216 return Response({"detail": "Deletion not allowed."}, status=405) 217 218@extend_schema( 219 summary="Approver Hierarchy CRUD", 220 description="Create, retrieve, update, and list approver hierarchies for a hospital.", 221 responses={200: ApproverHierarchySerializer(many=True)} 222) 223class ApproverHierarchyViewSet(viewsets.ModelViewSet): 224 """ 225 ViewSet for approver hierarchy CRUD operations within a hospital. 226 """ 227 serializer_class = ApproverHierarchySerializer 228 permission_classes = [IsAuthenticated, RoleEditPermission] 229 lookup_field = 'id' 230 231 def get_queryset(self): 232 hospital_id = self.kwargs.get('hospital_pk') 233 return ApproverHierarchy.objects.filter(levels__role__hospital_id=hospital_id).distinct() 234 235 def perform_create(self, serializer): 236 serializer.save() 237 238 def get_serializer_context(self): 239 return super().get_serializer_context() 240 241@extend_schema( 242 summary="Ward CRUD", 243 description="Create, retrieve, update, and list wards for a hospital.", 244 responses={200: WardSerializer(many=True)} 245) 246class WardViewSet(viewsets.ModelViewSet): 247 """ 248 ViewSet for ward CRUD operations within a hospital. 249 """ 250 serializer_class = WardSerializer 251 permission_classes = [IsAuthenticated, WardPermission] 252 lookup_field = 'id' 253 254 def get_queryset(self): 255 hospital_id = self.kwargs.get('hospital_pk') 256 queryset = Ward.objects.filter( 257 deleted=False, 258 block__hospital_id=hospital_id 259 ) 260 261 block_id = self.request.query_params.get('block') 262 if block_id: 263 queryset = queryset.filter(block_id=block_id) 264 265 floor = self.request.query_params.get('floor') 266 if floor is not None: 267 queryset = queryset.filter(floor=floor) 268 269 return queryset 270 271 def get_serializer_context(self): 272 context = super().get_serializer_context() 273 context['hospital_id'] = self.kwargs.get('hospital_pk') 274 return context 275 276 def perform_create(self, serializer): 277 serializer.save(created_by=self.request.user) 278 279 def destroy(self, request, *args, **kwargs): 280 instance = self.get_object() 281 if request.user.is_superuser: 282 instance.delete() 283 return Response({"detail": "Ward deleted successfully."}, status=status.HTTP_202_ACCEPTED) 284 instance.deleted = True 285 instance.save() 286 return Response({"detail": "Ward soft-deleted successfully."}, status=status.HTTP_202_ACCEPTED) 287 288 @action(detail=True, methods=['post'], url_path='restore') 289 def restore(self, request, *args, **kwargs): 290 instance = self.get_object() 291 instance.deleted = False 292 instance.save() 293 return Response({"detail": "Ward restored successfully."}) 294 295@extend_schema( 296 summary="Switch Current Block", 297 description="Switch user's current block by providing block ID.", 298 parameters=[ 299 OpenApiParameter(name="block_id", type=int, location="query", required=True, description="Block ID"), 300 ], 301 responses={ 302 200: OpenApiResponse(description="Block switched successfully."), 303 400: OpenApiResponse(description="Bad request, block ID is required."), 304 404: OpenApiResponse(description="Block not found.") 305 } 306) 307class SwitchBlock(APIView): 308 """ 309 APIView to switch user's current block. 310 """ 311 permission_classes = [IsAuthenticated] 312 313 @extend_schema( 314 summary="Switch Current Block", 315 description="This endpoint allows a user to switch their current block by providing the block ID.", 316 parameters=[ 317 OpenApiParameter(name="block_id", type=int, location="query", required=True, description="Block ID"), 318 ], 319 responses={ 320 200: OpenApiResponse(description="Block switched successfully."), 321 400: OpenApiResponse(description="Bad request, block ID is required."), 322 404: OpenApiResponse(description="Block not found.") 323 } 324 ) 325 def post(self, request, *args, **kwargs): 326 user = request.user 327 block_id = request.data.get('block_id') 328 329 if not block_id: 330 return Response({"detail": "Block ID is required."}, status=status.HTTP_400_BAD_REQUEST) 331 332 try: 333 block = Blocks.objects.get(id=block_id, hospital=user.hospital) 334 BlockChange.objects.create( 335 user=user, 336 from_block=user.current_block if user.current_block else None, 337 to_block=block 338 ) 339 user.current_block = block 340 user.save() 341 return Response({"detail": "Block switched successfully."}, status=status.HTTP_200_OK) 342 except Blocks.DoesNotExist: 343 return Response({"detail": "Block not found."}, status=status.HTTP_404_NOT_FOUND) 344 345@extend_schema( 346 summary="Switch Current Ward", 347 description="Switch user's current ward by providing ward ID.", 348 parameters=[ 349 OpenApiParameter(name="ward_id", type=int, location="query", required=True, description="Ward ID"), 350 ], 351 responses={ 352 200: OpenApiResponse(description="Ward switched successfully."), 353 400: OpenApiResponse(description="Bad request, ward ID is required."), 354 404: OpenApiResponse(description="Ward not found.") 355 } 356) 357class SwitchWard(APIView): 358 """ 359 APIView to switch user's current ward. 360 """ 361 permission_classes = [IsAuthenticated] 362 363 @extend_schema( 364 summary="Switch Current Ward", 365 description="This endpoint allows a user to switch their current ward by providing the ward ID.", 366 parameters=[ 367 OpenApiParameter(name="ward_id", type=int, location="query", required=True, description="Ward ID"), 368 ], 369 responses={ 370 200: OpenApiResponse(description="Ward switched successfully."), 371 400: OpenApiResponse(description="Bad request, ward ID is required."), 372 404: OpenApiResponse(description="Ward not found.") 373 } 374 ) 375 def post(self, request, *args, **kwargs): 376 user = request.user 377 ward_id = request.data.get('ward_id') 378 379 if not ward_id: 380 return Response({"detail": "Ward ID is required."}, status=status.HTTP_400_BAD_REQUEST) 381 382 try: 383 ward = Ward.objects.get(id=ward_id, block__hospital=user.hospital) 384 WardChange.objects.create( 385 user=user, 386 from_ward=user.current_ward if user.current_ward else None, 387 to_ward=ward 388 ) 389 user.current_ward = ward 390 user.current_block = ward.block 391 user.save() 392 return Response({"detail": "Ward switched successfully."}, status=status.HTTP_200_OK) 393 except Ward.DoesNotExist: 394 return Response({"detail": "Ward not found."}, status=status.HTTP_404_NOT_FOUND)
33@extend_schema( 34 summary="Hospital CRUD", 35 description="Create, retrieve, update, and list hospitals.", 36 responses={200: HospitalSerializer(many=True)} 37) 38class HospitalViewSet(viewsets.ModelViewSet): 39 """ 40 ViewSet for hospital CRUD operations. 41 """ 42 serializer_class = HospitalSerializer 43 permission_classes = [IsHospitalUserOrSuperUser] 44 45 def get_queryset(self): 46 print(self.kwargs) 47 user = self.request.user 48 return Hospital.objects.filter() 49 50 def get_serializer_context(self): 51 context = super().get_serializer_context() 52 context['hospital_id'] = self.kwargs.get('pk') 53 return context 54 55 def destroy(self, request, *args, **kwargs): 56 return Response({"detail": "Deletion not allowed."}, status=405)
ViewSet for hospital CRUD operations.
45 def get_queryset(self): 46 print(self.kwargs) 47 user = self.request.user 48 return Hospital.objects.filter()
Get the list of items for this view.
This must be an iterable, and may be a queryset.
Defaults to using self.queryset
.
This method should always be used rather than accessing self.queryset
directly, as self.queryset
gets evaluated only once, and those results
are cached for all subsequent requests.
You may want to override this if you need to provide different querysets depending on the incoming request.
(Eg. return a list of items that is specific to the user)
50 def get_serializer_context(self): 51 context = super().get_serializer_context() 52 context['hospital_id'] = self.kwargs.get('pk') 53 return context
Extra context provided to the serializer class.
58@extend_schema( 59 summary="Change user's password", 60 description="Change password by providing phone and new password.", 61 parameters=[ 62 OpenApiParameter(name="phone", type=str, location="query", required=True, description="User's phone number"), 63 OpenApiParameter(name="password", type=str, location="query", required=True, description="New password"), 64 ], 65 responses={ 66 200: OpenApiResponse(description="Password changed successfully."), 67 404: OpenApiResponse(description="User not found."), 68 400: OpenApiResponse(description="Bad request."), 69 }, 70) 71class PasswordChangeViewSet(APIView): 72 """ 73 APIView to change a user's password. 74 """ 75 permission_classes = [] 76 77 @extend_schema( 78 summary="Change user's password", 79 description="This endpoint allows a user to change their password by providing their phone number and new password.", 80 parameters=[ 81 OpenApiParameter(name="phone", type=str, location="query", required=True, description="User's phone number"), 82 OpenApiParameter(name="password", type=str, location="query", required=True, description="New password"), 83 ], 84 responses={ 85 200: OpenApiResponse(description="Password changed successfully."), 86 404: OpenApiResponse(description="User not found."), 87 400: OpenApiResponse(description="Bad request."), 88 }, 89 ) 90 def post(self, request, *args, **kwargs): 91 try: 92 phone = request.data.get('phone') 93 password = request.data.get('password') 94 95 user = User.objects.get(phone_number=phone) 96 user.set_password(password) 97 user.save() 98 return Response({"detail": "Password changed successfully."}, status=200) 99 except User.DoesNotExist: 100 return Response({"detail": "User not found."}, status=404) 101 except Exception as e: 102 return Response({"detail": str(e)}, status=400)
APIView to change a user's password.
77 @extend_schema( 78 summary="Change user's password", 79 description="This endpoint allows a user to change their password by providing their phone number and new password.", 80 parameters=[ 81 OpenApiParameter(name="phone", type=str, location="query", required=True, description="User's phone number"), 82 OpenApiParameter(name="password", type=str, location="query", required=True, description="New password"), 83 ], 84 responses={ 85 200: OpenApiResponse(description="Password changed successfully."), 86 404: OpenApiResponse(description="User not found."), 87 400: OpenApiResponse(description="Bad request."), 88 }, 89 ) 90 def post(self, request, *args, **kwargs): 91 try: 92 phone = request.data.get('phone') 93 password = request.data.get('password') 94 95 user = User.objects.get(phone_number=phone) 96 user.set_password(password) 97 user.save() 98 return Response({"detail": "Password changed successfully."}, status=200) 99 except User.DoesNotExist: 100 return Response({"detail": "User not found."}, status=404) 101 except Exception as e: 102 return Response({"detail": str(e)}, status=400)
104@extend_schema( 105 summary="Role CRUD", 106 description="Create, retrieve, update, and list roles for a hospital.", 107 responses={200: RoleSerializer(many=True)} 108) 109class RoleViewSet(viewsets.ModelViewSet): 110 """ 111 ViewSet for role CRUD operations within a hospital. 112 """ 113 serializer_class = RoleSerializer 114 permission_classes = [IsAuthenticated, RoleEditPermission] 115 lookup_field = 'id' 116 117 def get_queryset(self): 118 hospital_id = self.kwargs.get('hospital_pk') 119 print("KWARGS:", self.kwargs) 120 if self.request.query_params.get('is_responder') is not None: 121 return Role.objects.filter( 122 hospital__id=hospital_id, 123 is_responder=True 124 ) 125 return Role.objects.filter(hospital__id=hospital_id) 126 127 def get_serializer_context(self): 128 context = super().get_serializer_context() 129 context['hospital_id'] = self.kwargs.get('hospital_pk') 130 return context 131 132 def perform_create(self, serializer): 133 hospital_id = self.kwargs.get('hospital_pk') 134 serializer.save(hospital_id=hospital_id) 135 136 def destroy(self, request, *args, **kwargs): 137 instance = self.get_object() 138 self.perform_destroy(instance) 139 return Response({"detail": "Role deleted successfully."}, status=status.HTTP_204_NO_CONTENT)
ViewSet for role CRUD operations within a hospital.
117 def get_queryset(self): 118 hospital_id = self.kwargs.get('hospital_pk') 119 print("KWARGS:", self.kwargs) 120 if self.request.query_params.get('is_responder') is not None: 121 return Role.objects.filter( 122 hospital__id=hospital_id, 123 is_responder=True 124 ) 125 return Role.objects.filter(hospital__id=hospital_id)
Get the list of items for this view.
This must be an iterable, and may be a queryset.
Defaults to using self.queryset
.
This method should always be used rather than accessing self.queryset
directly, as self.queryset
gets evaluated only once, and those results
are cached for all subsequent requests.
You may want to override this if you need to provide different querysets depending on the incoming request.
(Eg. return a list of items that is specific to the user)
127 def get_serializer_context(self): 128 context = super().get_serializer_context() 129 context['hospital_id'] = self.kwargs.get('hospital_pk') 130 return context
Extra context provided to the serializer class.
141@extend_schema( 142 summary="Hospital User CRUD", 143 description="Create, retrieve, update, and list hospital users.", 144 responses={200: HospitalUserSerializer(many=True)} 145) 146class HospitalUserViewSet(viewsets.ModelViewSet): 147 """ 148 ViewSet for hospital user CRUD operations. 149 """ 150 serializer_class = HospitalUserSerializer 151 permission_classes = [IsAuthenticated, UserPermission] 152 lookup_field = 'id' 153 154 def get_queryset(self): 155 return User.objects.filter(hospital__id=self.kwargs.get('hospital_pk')).exclude(is_superuser=True) 156 157 def get_serializer_context(self): 158 context = super().get_serializer_context() 159 context['hospital_id'] = self.kwargs.get('hospital_pk') 160 return context
ViewSet for hospital user CRUD operations.
154 def get_queryset(self): 155 return User.objects.filter(hospital__id=self.kwargs.get('hospital_pk')).exclude(is_superuser=True)
Get the list of items for this view.
This must be an iterable, and may be a queryset.
Defaults to using self.queryset
.
This method should always be used rather than accessing self.queryset
directly, as self.queryset
gets evaluated only once, and those results
are cached for all subsequent requests.
You may want to override this if you need to provide different querysets depending on the incoming request.
(Eg. return a list of items that is specific to the user)
162@extend_schema( 163 summary="Block CRUD", 164 description="Create, retrieve, update, and list blocks for a hospital.", 165 responses={200: BlockSerializer(many=True)} 166) 167class BlockViewSet(viewsets.ModelViewSet): 168 """ 169 ViewSet for block CRUD operations within a hospital. 170 """ 171 serializer_class = BlockSerializer 172 permission_classes = [IsAuthenticated, RoleEditPermission] 173 lookup_field = 'id' 174 175 def get_queryset(self): 176 return Blocks.objects.filter(hospital_id=self.kwargs.get('hospital_pk')) 177 178 def get_serializer_context(self): 179 context = super().get_serializer_context() 180 context['hospital_id'] = self.kwargs.get('hospital_pk') 181 return context 182 183 def perform_create(self, serializer): 184 serializer.save( 185 hospital_id=self.kwargs.get('hospital_pk'), 186 created_by=self.request.user 187 )
ViewSet for block CRUD operations within a hospital.
175 def get_queryset(self): 176 return Blocks.objects.filter(hospital_id=self.kwargs.get('hospital_pk'))
Get the list of items for this view.
This must be an iterable, and may be a queryset.
Defaults to using self.queryset
.
This method should always be used rather than accessing self.queryset
directly, as self.queryset
gets evaluated only once, and those results
are cached for all subsequent requests.
You may want to override this if you need to provide different querysets depending on the incoming request.
(Eg. return a list of items that is specific to the user)
178 def get_serializer_context(self): 179 context = super().get_serializer_context() 180 context['hospital_id'] = self.kwargs.get('hospital_pk') 181 return context
Extra context provided to the serializer class.
189@extend_schema( 190 summary="Shift CRUD", 191 description="Create, retrieve, update, and list shifts for a hospital.", 192 responses={200: ShiftSerializer(many=True)} 193) 194class ShiftViewSet(viewsets.ModelViewSet): 195 """ 196 ViewSet for shift CRUD operations within a hospital. 197 """ 198 serializer_class = ShiftSerializer 199 permission_classes = [IsAuthenticated, RoleEditPermission] 200 lookup_field = 'id' 201 202 def get_queryset(self): 203 return Shift.objects.filter(hospital_id=self.kwargs.get('hospital_pk')) 204 205 def get_serializer_context(self): 206 context = super().get_serializer_context() 207 context['hospital_id'] = self.kwargs.get('hospital_pk') 208 return context 209 210 def perform_create(self, serializer): 211 serializer.save( 212 hospital_id=self.kwargs.get('hospital_pk'), 213 created_by=self.request.user 214 ) 215 216 def destroy(self, request, *args, **kwargs): 217 return Response({"detail": "Deletion not allowed."}, status=405)
ViewSet for shift CRUD operations within a hospital.
202 def get_queryset(self): 203 return Shift.objects.filter(hospital_id=self.kwargs.get('hospital_pk'))
Get the list of items for this view.
This must be an iterable, and may be a queryset.
Defaults to using self.queryset
.
This method should always be used rather than accessing self.queryset
directly, as self.queryset
gets evaluated only once, and those results
are cached for all subsequent requests.
You may want to override this if you need to provide different querysets depending on the incoming request.
(Eg. return a list of items that is specific to the user)
205 def get_serializer_context(self): 206 context = super().get_serializer_context() 207 context['hospital_id'] = self.kwargs.get('hospital_pk') 208 return context
Extra context provided to the serializer class.
219@extend_schema( 220 summary="Approver Hierarchy CRUD", 221 description="Create, retrieve, update, and list approver hierarchies for a hospital.", 222 responses={200: ApproverHierarchySerializer(many=True)} 223) 224class ApproverHierarchyViewSet(viewsets.ModelViewSet): 225 """ 226 ViewSet for approver hierarchy CRUD operations within a hospital. 227 """ 228 serializer_class = ApproverHierarchySerializer 229 permission_classes = [IsAuthenticated, RoleEditPermission] 230 lookup_field = 'id' 231 232 def get_queryset(self): 233 hospital_id = self.kwargs.get('hospital_pk') 234 return ApproverHierarchy.objects.filter(levels__role__hospital_id=hospital_id).distinct() 235 236 def perform_create(self, serializer): 237 serializer.save() 238 239 def get_serializer_context(self): 240 return super().get_serializer_context()
ViewSet for approver hierarchy CRUD operations within a hospital.
232 def get_queryset(self): 233 hospital_id = self.kwargs.get('hospital_pk') 234 return ApproverHierarchy.objects.filter(levels__role__hospital_id=hospital_id).distinct()
Get the list of items for this view.
This must be an iterable, and may be a queryset.
Defaults to using self.queryset
.
This method should always be used rather than accessing self.queryset
directly, as self.queryset
gets evaluated only once, and those results
are cached for all subsequent requests.
You may want to override this if you need to provide different querysets depending on the incoming request.
(Eg. return a list of items that is specific to the user)
242@extend_schema( 243 summary="Ward CRUD", 244 description="Create, retrieve, update, and list wards for a hospital.", 245 responses={200: WardSerializer(many=True)} 246) 247class WardViewSet(viewsets.ModelViewSet): 248 """ 249 ViewSet for ward CRUD operations within a hospital. 250 """ 251 serializer_class = WardSerializer 252 permission_classes = [IsAuthenticated, WardPermission] 253 lookup_field = 'id' 254 255 def get_queryset(self): 256 hospital_id = self.kwargs.get('hospital_pk') 257 queryset = Ward.objects.filter( 258 deleted=False, 259 block__hospital_id=hospital_id 260 ) 261 262 block_id = self.request.query_params.get('block') 263 if block_id: 264 queryset = queryset.filter(block_id=block_id) 265 266 floor = self.request.query_params.get('floor') 267 if floor is not None: 268 queryset = queryset.filter(floor=floor) 269 270 return queryset 271 272 def get_serializer_context(self): 273 context = super().get_serializer_context() 274 context['hospital_id'] = self.kwargs.get('hospital_pk') 275 return context 276 277 def perform_create(self, serializer): 278 serializer.save(created_by=self.request.user) 279 280 def destroy(self, request, *args, **kwargs): 281 instance = self.get_object() 282 if request.user.is_superuser: 283 instance.delete() 284 return Response({"detail": "Ward deleted successfully."}, status=status.HTTP_202_ACCEPTED) 285 instance.deleted = True 286 instance.save() 287 return Response({"detail": "Ward soft-deleted successfully."}, status=status.HTTP_202_ACCEPTED) 288 289 @action(detail=True, methods=['post'], url_path='restore') 290 def restore(self, request, *args, **kwargs): 291 instance = self.get_object() 292 instance.deleted = False 293 instance.save() 294 return Response({"detail": "Ward restored successfully."})
ViewSet for ward CRUD operations within a hospital.
255 def get_queryset(self): 256 hospital_id = self.kwargs.get('hospital_pk') 257 queryset = Ward.objects.filter( 258 deleted=False, 259 block__hospital_id=hospital_id 260 ) 261 262 block_id = self.request.query_params.get('block') 263 if block_id: 264 queryset = queryset.filter(block_id=block_id) 265 266 floor = self.request.query_params.get('floor') 267 if floor is not None: 268 queryset = queryset.filter(floor=floor) 269 270 return queryset
Get the list of items for this view.
This must be an iterable, and may be a queryset.
Defaults to using self.queryset
.
This method should always be used rather than accessing self.queryset
directly, as self.queryset
gets evaluated only once, and those results
are cached for all subsequent requests.
You may want to override this if you need to provide different querysets depending on the incoming request.
(Eg. return a list of items that is specific to the user)
272 def get_serializer_context(self): 273 context = super().get_serializer_context() 274 context['hospital_id'] = self.kwargs.get('hospital_pk') 275 return context
Extra context provided to the serializer class.
280 def destroy(self, request, *args, **kwargs): 281 instance = self.get_object() 282 if request.user.is_superuser: 283 instance.delete() 284 return Response({"detail": "Ward deleted successfully."}, status=status.HTTP_202_ACCEPTED) 285 instance.deleted = True 286 instance.save() 287 return Response({"detail": "Ward soft-deleted successfully."}, status=status.HTTP_202_ACCEPTED)
296@extend_schema( 297 summary="Switch Current Block", 298 description="Switch user's current block by providing block ID.", 299 parameters=[ 300 OpenApiParameter(name="block_id", type=int, location="query", required=True, description="Block ID"), 301 ], 302 responses={ 303 200: OpenApiResponse(description="Block switched successfully."), 304 400: OpenApiResponse(description="Bad request, block ID is required."), 305 404: OpenApiResponse(description="Block not found.") 306 } 307) 308class SwitchBlock(APIView): 309 """ 310 APIView to switch user's current block. 311 """ 312 permission_classes = [IsAuthenticated] 313 314 @extend_schema( 315 summary="Switch Current Block", 316 description="This endpoint allows a user to switch their current block by providing the block ID.", 317 parameters=[ 318 OpenApiParameter(name="block_id", type=int, location="query", required=True, description="Block ID"), 319 ], 320 responses={ 321 200: OpenApiResponse(description="Block switched successfully."), 322 400: OpenApiResponse(description="Bad request, block ID is required."), 323 404: OpenApiResponse(description="Block not found.") 324 } 325 ) 326 def post(self, request, *args, **kwargs): 327 user = request.user 328 block_id = request.data.get('block_id') 329 330 if not block_id: 331 return Response({"detail": "Block ID is required."}, status=status.HTTP_400_BAD_REQUEST) 332 333 try: 334 block = Blocks.objects.get(id=block_id, hospital=user.hospital) 335 BlockChange.objects.create( 336 user=user, 337 from_block=user.current_block if user.current_block else None, 338 to_block=block 339 ) 340 user.current_block = block 341 user.save() 342 return Response({"detail": "Block switched successfully."}, status=status.HTTP_200_OK) 343 except Blocks.DoesNotExist: 344 return Response({"detail": "Block not found."}, status=status.HTTP_404_NOT_FOUND)
APIView to switch user's current block.
314 @extend_schema( 315 summary="Switch Current Block", 316 description="This endpoint allows a user to switch their current block by providing the block ID.", 317 parameters=[ 318 OpenApiParameter(name="block_id", type=int, location="query", required=True, description="Block ID"), 319 ], 320 responses={ 321 200: OpenApiResponse(description="Block switched successfully."), 322 400: OpenApiResponse(description="Bad request, block ID is required."), 323 404: OpenApiResponse(description="Block not found.") 324 } 325 ) 326 def post(self, request, *args, **kwargs): 327 user = request.user 328 block_id = request.data.get('block_id') 329 330 if not block_id: 331 return Response({"detail": "Block ID is required."}, status=status.HTTP_400_BAD_REQUEST) 332 333 try: 334 block = Blocks.objects.get(id=block_id, hospital=user.hospital) 335 BlockChange.objects.create( 336 user=user, 337 from_block=user.current_block if user.current_block else None, 338 to_block=block 339 ) 340 user.current_block = block 341 user.save() 342 return Response({"detail": "Block switched successfully."}, status=status.HTTP_200_OK) 343 except Blocks.DoesNotExist: 344 return Response({"detail": "Block not found."}, status=status.HTTP_404_NOT_FOUND)
346@extend_schema( 347 summary="Switch Current Ward", 348 description="Switch user's current ward by providing ward ID.", 349 parameters=[ 350 OpenApiParameter(name="ward_id", type=int, location="query", required=True, description="Ward ID"), 351 ], 352 responses={ 353 200: OpenApiResponse(description="Ward switched successfully."), 354 400: OpenApiResponse(description="Bad request, ward ID is required."), 355 404: OpenApiResponse(description="Ward not found.") 356 } 357) 358class SwitchWard(APIView): 359 """ 360 APIView to switch user's current ward. 361 """ 362 permission_classes = [IsAuthenticated] 363 364 @extend_schema( 365 summary="Switch Current Ward", 366 description="This endpoint allows a user to switch their current ward by providing the ward ID.", 367 parameters=[ 368 OpenApiParameter(name="ward_id", type=int, location="query", required=True, description="Ward ID"), 369 ], 370 responses={ 371 200: OpenApiResponse(description="Ward switched successfully."), 372 400: OpenApiResponse(description="Bad request, ward ID is required."), 373 404: OpenApiResponse(description="Ward not found.") 374 } 375 ) 376 def post(self, request, *args, **kwargs): 377 user = request.user 378 ward_id = request.data.get('ward_id') 379 380 if not ward_id: 381 return Response({"detail": "Ward ID is required."}, status=status.HTTP_400_BAD_REQUEST) 382 383 try: 384 ward = Ward.objects.get(id=ward_id, block__hospital=user.hospital) 385 WardChange.objects.create( 386 user=user, 387 from_ward=user.current_ward if user.current_ward else None, 388 to_ward=ward 389 ) 390 user.current_ward = ward 391 user.current_block = ward.block 392 user.save() 393 return Response({"detail": "Ward switched successfully."}, status=status.HTTP_200_OK) 394 except Ward.DoesNotExist: 395 return Response({"detail": "Ward not found."}, status=status.HTTP_404_NOT_FOUND)
APIView to switch user's current ward.
364 @extend_schema( 365 summary="Switch Current Ward", 366 description="This endpoint allows a user to switch their current ward by providing the ward ID.", 367 parameters=[ 368 OpenApiParameter(name="ward_id", type=int, location="query", required=True, description="Ward ID"), 369 ], 370 responses={ 371 200: OpenApiResponse(description="Ward switched successfully."), 372 400: OpenApiResponse(description="Bad request, ward ID is required."), 373 404: OpenApiResponse(description="Ward not found.") 374 } 375 ) 376 def post(self, request, *args, **kwargs): 377 user = request.user 378 ward_id = request.data.get('ward_id') 379 380 if not ward_id: 381 return Response({"detail": "Ward ID is required."}, status=status.HTTP_400_BAD_REQUEST) 382 383 try: 384 ward = Ward.objects.get(id=ward_id, block__hospital=user.hospital) 385 WardChange.objects.create( 386 user=user, 387 from_ward=user.current_ward if user.current_ward else None, 388 to_ward=ward 389 ) 390 user.current_ward = ward 391 user.current_block = ward.block 392 user.save() 393 return Response({"detail": "Ward switched successfully."}, status=status.HTTP_200_OK) 394 except Ward.DoesNotExist: 395 return Response({"detail": "Ward not found."}, status=status.HTTP_404_NOT_FOUND)