From cd124c791b0ab5b50607288a87d2aa5ce7075dd9 Mon Sep 17 00:00:00 2001 From: Bhavik Agarwal <73033511+Bhavik-ag@users.noreply.github.com> Date: Thu, 24 Aug 2023 22:07:51 +0530 Subject: [PATCH] Made doctor role as static attribute (#1507) * made doctor role as static attribute * renamed create_by_local_user field and added tests * added comments * update migrations Signed-off-by: Aakash Singh --------- Signed-off-by: Aakash Singh Co-authored-by: Vignesh Hari Co-authored-by: Aakash Singh --- care/facility/api/serializers/patient.py | 18 ++++++++-- care/facility/api/viewsets/patient.py | 12 +------ .../migrations/0380_patientnotes_user_type.py | 20 +++++++++++ care/facility/models/patient.py | 1 + care/facility/tests/test_patient_api.py | 35 ++++++++++++------- care/utils/tests/test_base.py | 21 +++++++---- 6 files changed, 74 insertions(+), 33 deletions(-) create mode 100644 care/facility/migrations/0380_patientnotes_user_type.py diff --git a/care/facility/api/serializers/patient.py b/care/facility/api/serializers/patient.py index b0d60fc81b..d3b47f24c6 100644 --- a/care/facility/api/serializers/patient.py +++ b/care/facility/api/serializers/patient.py @@ -462,20 +462,34 @@ def save(self, **kwargs): class PatientNotesSerializer(serializers.ModelSerializer): facility = FacilityBasicInfoSerializer(read_only=True) created_by_object = UserBaseMinimumSerializer(source="created_by", read_only=True) - created_by_local_user = serializers.BooleanField(read_only=True) def validate_empty_values(self, data): if not data.get("note", "").strip(): raise serializers.ValidationError({"note": ["Note cannot be empty"]}) return super().validate_empty_values(data) + def create(self, validated_data): + user_type = User.REVERSE_TYPE_MAP[validated_data["created_by"].user_type] + # If the user is a doctor and the note is being created in the home facility + # then the user type is doctor else it is a remote specialist + if user_type == "Doctor": + if validated_data["created_by"].home_facility == validated_data["facility"]: + validated_data["user_type"] = "Doctor" + else: + validated_data["user_type"] = "RemoteSpecialist" + else: + # If the user is not a doctor then the user type is the same as the user type + validated_data["user_type"] = user_type + + return super().create(validated_data) + class Meta: model = PatientNotes fields = ( "note", "facility", "created_by_object", - "created_by_local_user", + "user_type", "created_date", ) read_only_fields = ("created_date",) diff --git a/care/facility/api/viewsets/patient.py b/care/facility/api/viewsets/patient.py index 098a3093bc..ec747eab38 100644 --- a/care/facility/api/viewsets/patient.py +++ b/care/facility/api/viewsets/patient.py @@ -5,7 +5,7 @@ from django.conf import settings from django.contrib.postgres.search import TrigramSimilarity from django.db import models -from django.db.models import BooleanField, Case, F, Value, When +from django.db.models import Case, When from django.db.models.query_utils import Q from django_filters import rest_framework as filters from djqscsv import render_to_csv_response @@ -607,16 +607,6 @@ class PatientNotesViewSet( queryset = ( PatientNotes.objects.all() .select_related("facility", "patient", "created_by") - .annotate( - created_by_local_user=Case( - When( - created_by__home_facility__external_id=F("facility__external_id"), - then=Value(True), - ), - default=Value(False), - output_field=BooleanField(), - ) - ) .order_by("-created_date") ) serializer_class = PatientNotesSerializer diff --git a/care/facility/migrations/0380_patientnotes_user_type.py b/care/facility/migrations/0380_patientnotes_user_type.py new file mode 100644 index 0000000000..ca0de6e789 --- /dev/null +++ b/care/facility/migrations/0380_patientnotes_user_type.py @@ -0,0 +1,20 @@ +# Generated by Django 4.2.2 on 2023-08-22 07:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ( + "facility", + "0379_rename_prescribed_medication_patientconsultation_treatment_plan", + ), + ] + + operations = [ + migrations.AddField( + model_name="patientnotes", + name="user_type", + field=models.CharField(default="", max_length=25), + ), + ] diff --git a/care/facility/models/patient.py b/care/facility/models/patient.py index 0d751ac8da..44fe0ee1a6 100644 --- a/care/facility/models/patient.py +++ b/care/facility/models/patient.py @@ -681,6 +681,7 @@ class PatientNotes(FacilityBaseModel, PatientRelatedPermissionMixin): facility = models.ForeignKey( Facility, on_delete=models.PROTECT, null=False, blank=False ) + user_type = models.CharField(max_length=25, default="") created_by = models.ForeignKey( User, on_delete=models.SET_NULL, diff --git a/care/facility/tests/test_patient_api.py b/care/facility/tests/test_patient_api.py index 0c13cd3307..5c5f10263d 100644 --- a/care/facility/tests/test_patient_api.py +++ b/care/facility/tests/test_patient_api.py @@ -6,6 +6,7 @@ from rest_framework.test import APIRequestFactory, APITestCase from rest_framework_simplejwt.tokens import RefreshToken +from care.facility.models import User from care.facility.tests.mixins import TestClassMixin from care.utils.tests.test_base import TestBase @@ -15,7 +16,7 @@ class ExpectedPatientNoteKeys(Enum): FACILITY = "facility" CREATED_BY_OBJECT = "created_by_object" CREATED_DATE = "created_date" - CREATED_BY_LOCAL_USER = "created_by_local_user" + USER_TYPE = "user_type" class ExpectedFacilityKeys(Enum): @@ -85,24 +86,32 @@ def setUp(self): district = self.create_district(state=state) # Create users and facility - self.user = self.create_user(district=district, username="test user") - facility = self.create_facility(district=district, user=self.user) + self.user = self.create_user( + district=district, + username="test user", + user_type=User.TYPE_VALUE_MAP["Doctor"], + ) + facility = self.create_facility(district=district) self.user.home_facility = facility self.user.save() # Create another user from different facility - self.user2 = self.create_user(district=district, username="test user 2") - facility2 = self.create_facility(district=district, user=self.user2) + self.user2 = self.create_user( + district=district, + username="test user 2", + user_type=User.TYPE_VALUE_MAP["Doctor"], + ) + facility2 = self.create_facility(district=district) self.user2.home_facility = facility2 self.user2.save() - self.patient = self.create_patient(district=district.id) + self.patient = self.create_patient(district=district.id, facility=facility) - self.patient_note = self.create_patient_note( + self.create_patient_note( patient=self.patient, facility=facility, created_by=self.user ) - self.patient_note2 = self.create_patient_note( + self.create_patient_note( patient=self.patient, facility=facility, created_by=self.user2 ) @@ -117,11 +126,11 @@ def test_patient_notes(self): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertIsInstance(response.json()["results"], list) - # Test created_by_local_user field if user is not from same facility as patient + # Test user_type field if user is not from same facility as patient data2 = response.json()["results"][0] - created_by_local_user_content2 = data2["created_by_local_user"] - self.assertEqual(created_by_local_user_content2, False) + user_type_content2 = data2["user_type"] + self.assertEqual(user_type_content2, "RemoteSpecialist") # Ensure only necessary data is being sent and no extra data data = response.json()["results"][1] @@ -130,9 +139,9 @@ def test_patient_notes(self): data.keys(), [item.value for item in ExpectedPatientNoteKeys] ) - created_by_local_user_content = data["created_by_local_user"] + user_type_content = data["user_type"] - self.assertEqual(created_by_local_user_content, True) + self.assertEqual(user_type_content, "Doctor") facility_content = data["facility"] diff --git a/care/utils/tests/test_base.py b/care/utils/tests/test_base.py index 6ef5bb2b32..25427225e3 100644 --- a/care/utils/tests/test_base.py +++ b/care/utils/tests/test_base.py @@ -8,6 +8,7 @@ from pytz import unicode from rest_framework import status from rest_framework.test import APITestCase +from rest_framework_simplejwt.tokens import RefreshToken from care.facility.models import ( CATEGORY_CHOICES, @@ -19,7 +20,6 @@ Facility, LocalBody, PatientConsultation, - PatientNotes, PatientRegistration, User, ) @@ -102,7 +102,7 @@ def create_facility( return f @classmethod - def create_patient(cls, **kwargs): + def create_patient(cls, facility=None, **kwargs): patient_data = cls.get_patient_data().copy() patient_data.update(kwargs) @@ -112,7 +112,7 @@ def create_patient(cls, **kwargs): patient_data.update( { - "facility": cls.facility, + "facility": facility or cls.facility, "district_id": district_id, "state_id": state_id, "disease_status": getattr( @@ -439,12 +439,19 @@ def create_consultation( return PatientConsultation.objects.create(**data) def create_patient_note( - self, patient=None, facility=None, note="Patient is doing find", **kwargs + self, patient=None, note="Patient is doing find", created_by=None, **kwargs ): data = { - "patient": patient or self.patient, - "facility": facility or self.facility, + "facility": patient.facility or self.facility, "note": note, } data.update(kwargs) - return PatientNotes.objects.create(**data) + + patientId = patient.external_id + + refresh_token = RefreshToken.for_user(created_by) + self.client.credentials( + HTTP_AUTHORIZATION=f"Bearer {refresh_token.access_token}" + ) + + self.client.post(f"/api/v1/patient/{patientId}/notes/", data=data)