diff --git a/care/facility/api/serializers/patient_consultation.py b/care/facility/api/serializers/patient_consultation.py index 731492969c..97b9fa43ad 100644 --- a/care/facility/api/serializers/patient_consultation.py +++ b/care/facility/api/serializers/patient_consultation.py @@ -39,6 +39,7 @@ class PatientConsultationSerializer(serializers.ModelSerializer): + # TODO: Remove when #5492 is completed id = serializers.CharField(source="external_id", read_only=True) facility_name = serializers.CharField(source="facility.name", read_only=True) suggestion_text = ChoiceField( @@ -589,3 +590,393 @@ def validate(self, attrs): class Meta: model = PatientConsultation fields = ("email",) + + +class PatientConsultationListSerializer(serializers.ModelSerializer): + id = serializers.CharField(source="external_id", read_only=True) + facility_name = serializers.CharField(source="facility.name", read_only=True) + facility = serializers.CharField(source="facility.external_id", read_only=True) + patient = serializers.CharField(source="patient.external_id", read_only=True) + last_edited_by = UserBaseMinimumSerializer(read_only=True) + suggestion_text = ChoiceField( + choices=PatientConsultation.SUGGESTION_CHOICES, + read_only=True, + source="suggestion", + ) + + class Meta: + model = PatientConsultation + fields = [ + "id", + "is_kasp", + "facility_name", + "is_telemedicine", + "suggestion_text", + "kasp_enabled_date", + "admitted", + "admission_date", + "admitted", + "discharge_date", + "created_date", + "modified_date", + "last_edited_by", + "facility", + "patient", + ] + read_only_fields = TIMESTAMP_FIELDS + ( + "discharge_date", + "last_edited_by", + "created_by", + "kasp_enabled_date", + ) + + +class PatientConsulationDetailSerializer(PatientConsultationListSerializer): + id = serializers.CharField(source="external_id", read_only=True) + facility_name = serializers.CharField(source="facility.name", read_only=True) + suggestion_text = ChoiceField( + choices=PatientConsultation.SUGGESTION_CHOICES, + read_only=True, + source="suggestion", + ) + + symptoms = serializers.MultipleChoiceField(choices=SYMPTOM_CHOICES) + deprecated_covid_category = ChoiceField( + choices=COVID_CATEGORY_CHOICES, required=False + ) + category = ChoiceField(choices=CATEGORY_CHOICES, required=True) + + referred_to_object = FacilityBasicInfoSerializer( + source="referred_to", read_only=True + ) + referred_to = ExternalIdSerializerField( + queryset=Facility.objects.all(), + required=False, + ) + referred_to_external = serializers.CharField( + required=False, allow_null=True, allow_blank=True + ) + patient = ExternalIdSerializerField(queryset=PatientRegistration.objects.all()) + facility = ExternalIdSerializerField(read_only=True) + + assigned_to_object = UserAssignedSerializer(source="assigned_to", read_only=True) + + assigned_to = serializers.PrimaryKeyRelatedField( + queryset=User.objects.all(), required=False, allow_null=True + ) + + discharge_reason = serializers.ChoiceField( + choices=DISCHARGE_REASON_CHOICES, read_only=True, required=False + ) + discharge_notes = serializers.CharField(read_only=True) + + discharge_prescription = serializers.SerializerMethodField() + discharge_prn_prescription = serializers.SerializerMethodField() + + action = ChoiceField( + choices=PatientRegistration.ActionChoices, + write_only=True, + required=False, + ) + + review_interval = serializers.IntegerField(default=-1, required=False) + + last_edited_by = UserBaseMinimumSerializer(read_only=True) + created_by = UserBaseMinimumSerializer(read_only=True) + last_daily_round = DailyRoundSerializer(read_only=True) + + current_bed = ConsultationBedSerializer(read_only=True) + + bed = ExternalIdSerializerField(queryset=Bed.objects.all(), required=False) + + icd11_diagnoses_object = serializers.SerializerMethodField(read_only=True) + + icd11_provisional_diagnoses_object = serializers.SerializerMethodField( + read_only=True + ) + + def get_discharge_prescription(self, consultation): + return Prescription.objects.filter( + consultation=consultation, + prescription_type=PrescriptionType.DISCHARGE.value, + is_prn=False, + ).values() + + def get_discharge_prn_prescription(self, consultation): + return Prescription.objects.filter( + consultation=consultation, + prescription_type=PrescriptionType.DISCHARGE.value, + is_prn=True, + ).values() + + def get_icd11_diagnoses_object(self, consultation): + return get_icd11_diagnoses_objects_by_ids(consultation.icd11_diagnoses) + + def get_icd11_provisional_diagnoses_object(self, consultation): + return get_icd11_diagnoses_objects_by_ids( + consultation.icd11_provisional_diagnoses + ) + + class Meta: + model = PatientConsultation + read_only_fields = TIMESTAMP_FIELDS + ( + "last_updated_by_telemedicine", + "discharge_date", + "last_edited_by", + "created_by", + "kasp_enabled_date", + ) + exclude = ("deleted", "external_id") + + def validate_bed_number(self, bed_number): + try: + if not self.initial_data["admitted"]: + bed_number = None + except KeyError: + bed_number = None + return bed_number + + def update(self, instance, validated_data): + instance.last_edited_by = self.context["request"].user + + if instance.discharge_date: + raise ValidationError( + {"consultation": ["Discharged Consultation data cannot be updated"]} + ) + + if instance.suggestion == SuggestionChoices.OP: + instance.discharge_date = localtime(now()) + instance.save() + + if "action" in validated_data or "review_interval" in validated_data: + patient = instance.patient + + if "action" in validated_data: + action = validated_data.pop("action") + patient.action = action + + if "review_interval" in validated_data: + review_interval = validated_data.pop("review_interval") + instance.review_interval = review_interval + instance.save() + if review_interval >= 0: + patient.review_time = localtime(now()) + timedelta( + minutes=review_interval + ) + else: + patient.review_time = None + patient.save() + + validated_data["last_updated_by_telemedicine"] = ( + self.context["request"].user == instance.assigned_to + ) + + if "is_kasp" in validated_data: + if validated_data["is_kasp"] and (not instance.is_kasp): + validated_data["kasp_enabled_date"] = localtime(now()) + + _temp = instance.assigned_to + + consultation = super().update(instance, validated_data) + + if "assigned_to" in validated_data: + if validated_data["assigned_to"] != _temp and validated_data["assigned_to"]: + NotificationGenerator( + event=Notification.Event.PATIENT_CONSULTATION_ASSIGNMENT, + caused_by=self.context["request"].user, + caused_object=instance, + facility=instance.patient.facility, + notification_mediums=[ + Notification.Medium.SYSTEM, + Notification.Medium.WHATSAPP, + ], + ).generate() + + NotificationGenerator( + event=Notification.Event.PATIENT_CONSULTATION_UPDATED, + caused_by=self.context["request"].user, + caused_object=consultation, + facility=consultation.patient.facility, + ).generate() + + return consultation + + def create(self, validated_data): + action = -1 + review_interval = -1 + if "action" in validated_data: + action = validated_data.pop("action") + if "review_interval" in validated_data: + review_interval = validated_data.pop("review_interval") + + # Authorisation Check + + allowed_facilities = get_home_facility_queryset(self.context["request"].user) + if not allowed_facilities.filter( + id=self.validated_data["patient"].facility.id + ).exists(): + raise ValidationError( + {"facility": "Consultation creates are only allowed in home facility"} + ) + + # End Authorisation Checks + + if validated_data["patient"].last_consultation: + if ( + self.context["request"].user + == validated_data["patient"].last_consultation.assigned_to + ): + raise ValidationError( + { + "Permission Denied": "Only Facility Staff can create consultation for a Patient" + }, + ) + + if validated_data["patient"].last_consultation: + if not validated_data["patient"].last_consultation.discharge_date: + raise ValidationError( + {"consultation": "Exists please Edit Existing Consultation"} + ) + + if "is_kasp" in validated_data: + if validated_data["is_kasp"]: + validated_data["kasp_enabled_date"] = localtime(now()) + + bed = validated_data.pop("bed", None) + + validated_data["facility_id"] = validated_data[ + "patient" + ].facility_id # Coercing facility as the patient's facility + consultation = super().create(validated_data) + consultation.created_by = self.context["request"].user + consultation.last_edited_by = self.context["request"].user + consultation.save() + + if bed and consultation.suggestion == SuggestionChoices.A: + consultation_bed = ConsultationBed( + bed=bed, + consultation=consultation, + start_date=consultation.created_date, + ) + consultation_bed.save() + consultation.current_bed = consultation_bed + consultation.save(update_fields=["current_bed"]) + + patient = consultation.patient + if consultation.suggestion == SuggestionChoices.OP: + consultation.discharge_date = localtime(now()) + consultation.save() + patient.is_active = False + patient.allow_transfer = True + else: + patient.is_active = True + patient.last_consultation = consultation + + if action != -1: + patient.action = action + consultation.review_interval = review_interval + if review_interval > 0: + patient.review_time = localtime(now()) + timedelta(minutes=review_interval) + else: + patient.review_time = None + + patient.save() + NotificationGenerator( + event=Notification.Event.PATIENT_CONSULTATION_CREATED, + caused_by=self.context["request"].user, + caused_object=consultation, + facility=patient.facility, + ).generate() + + if consultation.assigned_to: + NotificationGenerator( + event=Notification.Event.PATIENT_CONSULTATION_ASSIGNMENT, + caused_by=self.context["request"].user, + caused_object=consultation, + facility=consultation.patient.facility, + notification_mediums=[ + Notification.Medium.SYSTEM, + Notification.Medium.WHATSAPP, + ], + ).generate() + + return consultation + + def validate(self, attrs): + validated = super().validate(attrs) + # TODO Add Bed Authorisation Validation + + if "suggestion" in validated: + if validated["suggestion"] is SuggestionChoices.R: + if not validated.get("referred_to") and not validated.get( + "referred_to_external" + ): + raise ValidationError( + { + "referred_to": [ + f"This field is required as the suggestion is {SuggestionChoices.R}." + ] + } + ) + if validated.get("referred_to_external"): + validated["referred_to"] = None + elif validated.get("referred_to"): + validated["referred_to_external"] = None + if validated["suggestion"] is SuggestionChoices.A: + if not validated.get("admission_date"): + raise ValidationError( + { + "admission_date": "This field is required as the patient has been admitted." + } + ) + if validated["admission_date"] > now(): + raise ValidationError( + {"admission_date": "This field value cannot be in the future."} + ) + + if "action" in validated: + if validated["action"] == PatientRegistration.ActionEnum.REVIEW: + if "review_interval" not in validated: + raise ValidationError( + { + "review_interval": [ + "This field is required as the patient has been requested Review." + ] + } + ) + if validated["review_interval"] <= 0: + raise ValidationError( + { + "review_interval": [ + "This field value is must be greater than 0." + ] + } + ) + from care.facility.static_data.icd11 import ICDDiseases + + if "icd11_diagnoses" in validated: + for diagnosis in validated["icd11_diagnoses"]: + try: + ICDDiseases.by.id[diagnosis] + except BaseException: + raise ValidationError( + { + "icd11_diagnoses": [ + f"{diagnosis} is not a valid ICD 11 Diagnosis ID" + ] + } + ) + + if "icd11_provisional_diagnoses" in validated: + for diagnosis in validated["icd11_provisional_diagnoses"]: + try: + ICDDiseases.by.id[diagnosis] + except BaseException: + raise ValidationError( + { + "icd11_provisional_diagnoses": [ + f"{diagnosis} is not a valid ICD 11 Diagnosis ID" + ] + } + ) + return validated diff --git a/care/facility/api/viewsets/patient_consultation.py b/care/facility/api/viewsets/patient_consultation.py index d147ea611d..211e4f4ca1 100644 --- a/care/facility/api/viewsets/patient_consultation.py +++ b/care/facility/api/viewsets/patient_consultation.py @@ -14,9 +14,10 @@ from care.facility.api.serializers.file_upload import FileUploadRetrieveSerializer from care.facility.api.serializers.patient_consultation import ( EmailDischargeSummarySerializer, + PatientConsulationDetailSerializer, PatientConsultationDischargeSerializer, PatientConsultationIDSerializer, - PatientConsultationSerializer, + PatientConsultationListSerializer, ) from care.facility.api.viewsets.mixins.access import AssetUserAccessMixin from care.facility.models.file_upload import FileUpload @@ -45,7 +46,7 @@ class PatientConsultationViewSet( GenericViewSet, ): lookup_field = "external_id" - serializer_class = PatientConsultationSerializer + serializer_class = PatientConsulationDetailSerializer permission_classes = ( IsAuthenticated, DRYPermissions, @@ -57,6 +58,8 @@ class PatientConsultationViewSet( filterset_class = PatientConsultationFilter def get_serializer_class(self): + if self.action == "list": + self.serializer_class = PatientConsultationListSerializer if self.action == "patient_from_asset": return PatientConsultationIDSerializer elif self.action == "discharge_patient": @@ -72,7 +75,7 @@ def get_permissions(self): return super().get_permissions() def get_queryset(self): - if self.serializer_class == PatientConsultationSerializer: + if self.serializer_class == PatientConsulationDetailSerializer: self.queryset = self.queryset.prefetch_related( "assigned_to", Prefetch( diff --git a/care/facility/tests/test_patient_consultation_api.py b/care/facility/tests/test_patient_consultation_api.py index 48de90f695..fc93c86f05 100644 --- a/care/facility/tests/test_patient_consultation_api.py +++ b/care/facility/tests/test_patient_consultation_api.py @@ -1,22 +1,175 @@ import datetime +import random +from enum import Enum from django.test import TestCase from django.utils.timezone import make_aware from rest_framework import status -from rest_framework.test import APIRequestFactory, APITestCase +from rest_framework.test import APIClient, APIRequestFactory, APITestCase +from rest_framework_simplejwt.tokens import RefreshToken from care.facility.api.viewsets.facility_users import FacilityUserViewSet from care.facility.api.viewsets.patient_consultation import PatientConsultationViewSet +from care.facility.models import Bed, ConsultationBed +from care.facility.models.asset import Asset, AssetClasses, AssetLocation from care.facility.models.facility import Facility from care.facility.models.patient_consultation import ( CATEGORY_CHOICES, PatientConsultation, ) from care.facility.tests.mixins import TestClassMixin -from care.users.models import Skill +from care.users.models import Skill, User from care.utils.tests.test_base import TestBase +class ExpectedPatientConsultationListKeys(Enum): + id = "id" + is_kasp = "is_kasp" + facility_name = "facility_name" + is_telemedicine = "is_telemedicine" + suggestion_text = "suggestion_text" + kasp_enabled_date = "kasp_enabled_date" + admitted = "admitted" + admission_date = "admission_date" + discharge_date = "discharge_date" + created_date = "created_date" + modified_date = "modified_date" + last_edited_by = "last_edited_by" + facility = "facility" + patient = "patient" + + +class ExpectedLastEditedByKeys(Enum): + ID = "id" + FIRST_NAME = "first_name" + USERNAME = "username" + EMAIL = "email" + LAST_NAME = "last_name" + USER_TYPE = "user_type" + LAST_LOGIN = "last_login" + + +class ExpectedPatientConsultationRetrieveKeys(Enum): + id = "id" + facility_name = "facility_name" + facility = "facility" + patient = "patient" + last_edited_by = "last_edited_by" + suggestion_text = "suggestion_text" + symptoms = "symptoms" + deprecated_covid_category = "deprecated_covid_category" + category = "category" + referred_to_object = "referred_to_object" + referred_to = "referred_to" + referred_to_external = "referred_to_external" + assigned_to_object = "assigned_to_object" + assigned_to = "assigned_to" + discharge_reason = "discharge_reason" + discharge_notes = "discharge_notes" + discharge_prescription = "discharge_prescription" + discharge_prn_prescription = "discharge_prn_prescription" + review_interval = "review_interval" + created_by = "created_by" + last_daily_round = "last_daily_round" + current_bed = "current_bed" + icd11_diagnoses_object = "icd11_diagnoses_object" + icd11_provisional_diagnoses_object = "icd11_provisional_diagnoses_object" + created_date = "created_date" + modified_date = "modified_date" + diagnosis = "diagnosis" + icd11_provisional_diagnoses = "icd11_provisional_diagnoses" + icd11_diagnoses = "icd11_diagnoses" + other_symptoms = "other_symptoms" + symptoms_onset_date = "symptoms_onset_date" + examination_details = "examination_details" + history_of_present_illness = "history_of_present_illness" + consultation_notes = "consultation_notes" + course_in_facility = "course_in_facility" + investigation = "investigation" + prescriptions = "prescriptions" + procedure = "procedure" + suggestion = "suggestion" + consultation_status = "consultation_status" + admitted = "admitted" + admission_date = "admission_date" + discharge_date = "discharge_date" + death_datetime = "death_datetime" + death_confirmed_doctor = "death_confirmed_doctor" + bed_number = "bed_number" + is_kasp = "is_kasp" + kasp_enabled_date = "kasp_enabled_date" + is_telemedicine = "is_telemedicine" + last_updated_by_telemedicine = "last_updated_by_telemedicine" + verified_by = "verified_by" + height = "height" + weight = "weight" + operation = "operation" + special_instruction = "special_instruction" + intubation_history = "intubation_history" + prn_prescription = "prn_prescription" + discharge_advice = "discharge_advice" + patient_no = "patient_no" + treatment_plan = "treatment_plan" + + +class ExpectedCreatedByKeys(Enum): + ID = "id" + FIRST_NAME = "first_name" + USERNAME = "username" + EMAIL = "email" + LAST_NAME = "last_name" + USER_TYPE = "user_type" + LAST_LOGIN = "last_login" + + +class LocalBodyKeys(Enum): + ID = "id" + NAME = "name" + BODY_TYPE = "body_type" + LOCALBODY_CODE = "localbody_code" + DISTRICT = "district" + + +class DistrictKeys(Enum): + ID = "id" + NAME = "name" + STATE = "state" + + +class StateKeys(Enum): + ID = "id" + NAME = "name" + + +class ExpectedReferredToKeys(Enum): + ID = "id" + NAME = "name" + LOCAL_BODY = "local_body" + DISTRICT = "district" + STATE = "state" + WARD_OBJECT = "ward_object" + LOCAL_BODY_OBJECT = "local_body_object" + DISTRICT_OBJECT = "district_object" + STATE_OBJECT = "state_object" + FACILITY_TYPE = "facility_type" + READ_COVER_IMAGE_URL = "read_cover_image_url" + FEATURES = "features" + PATIENT_COUNT = "patient_count" + BED_COUNT = "bed_count" + + +class WardKeys(Enum): + ID = "id" + NAME = "name" + NUMBER = "number" + LOCAL_BODY = "local_body" + + +class FacilityTypeKeys(Enum): + ID = "id" + NAME = "name" + + class FacilityUserTest(TestClassMixin, TestCase): def setUp(self): super().setUp() @@ -72,6 +225,11 @@ def setUp(self): self.consultation = self.create_consultation( suggestion="A", admission_date=make_aware(datetime.datetime(2020, 4, 1, 15, 30, 00)), + referred_to=random.choices(Facility.objects.all())[0], + ) + refresh_token = RefreshToken.for_user(self.user) + self.client.credentials( + HTTP_AUTHORIZATION=f"Bearer {refresh_token.access_token}" ) def create_admission_consultation(self, patient=None, **kwargs): @@ -292,3 +450,160 @@ def test_referred_to_external_valid_value(self): referred_to_external=referred_to_external, ) self.assertEqual(res.status_code, status.HTTP_200_OK) + + def test_list_patient_consultation(self): + client = APIClient() + client.credentials( + HTTP_AUTHORIZATION=f"Bearer {RefreshToken.for_user(self.super_user).access_token}" + ) + response = client.get("/api/v1/consultation/") + self.assertEqual(response.status_code, status.HTTP_200_OK) + + district_lab_admin = self.create_user( + district=self.district, + username="district_lab_admin", + user_type=User.TYPE_VALUE_MAP["DistrictLabAdmin"], + ) + client.credentials( + HTTP_AUTHORIZATION=f"Bearer {RefreshToken.for_user(district_lab_admin).access_token}" + ) + response = client.get("/api/v1/consultation/") + self.assertEqual(response.status_code, status.HTTP_200_OK) + + response = self.client.get("/api/v1/consultation/") + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertIsInstance(response.json()["results"], list) + + # Ensure only necessary data is being sent and no extra data + expected_keys = [key.value for key in ExpectedPatientConsultationListKeys] + + data = response.json()["results"][0] + + self.assertCountEqual(data.keys(), expected_keys) + + last_edited_by_keys = [key.value for key in ExpectedLastEditedByKeys] + + if data["last_edited_by"]: + self.assertCountEqual(data["last_edited_by"].keys(), last_edited_by_keys) + + def test_retrieve_patient_consultation(self): + response = self.client.get( + f"/api/v1/consultation/{self.consultation.external_id}/" + ) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + + # Ensure only necessary data is being sent and no extra data + expected_keys = [key.value for key in ExpectedPatientConsultationRetrieveKeys] + + data = response.json() + + self.assertCountEqual(data.keys(), expected_keys) + + last_edited_by_keys = [key.value for key in ExpectedLastEditedByKeys] + + if data["last_edited_by"]: + self.assertCountEqual(data["last_edited_by"].keys(), last_edited_by_keys) + + reffered_to_object_keys = [key.value for key in ExpectedReferredToKeys] + self.assertCountEqual( + data["referred_to_object"].keys(), + reffered_to_object_keys, + ) + + ward_object_keys = [key.value for key in WardKeys] + self.assertCountEqual( + data["referred_to_object"]["ward_object"].keys(), + ward_object_keys, + ) + + local_body_object_keys = [key.value for key in LocalBodyKeys] + self.assertCountEqual( + data["referred_to_object"]["local_body_object"].keys(), + local_body_object_keys, + ) + + district_object_keys = [key.value for key in DistrictKeys] + self.assertCountEqual( + data["referred_to_object"]["district_object"].keys(), + district_object_keys, + ) + + state_object_keys = [key.value for key in StateKeys] + self.assertCountEqual( + data["referred_to_object"]["state_object"].keys(), + state_object_keys, + ) + + facility_object_keys = [key.value for key in FacilityTypeKeys] + self.assertCountEqual( + data["referred_to_object"]["facility_type"].keys(), + facility_object_keys, + ) + + def test_generate_discharge_summary(self): + url = f"/api/v1/consultation/{self.consultation.external_id}/generate_discharge_summary/" + res = self.client.post(url) + self.assertEqual(res.status_code, status.HTTP_202_ACCEPTED) + self.assertEqual( + res.data["detail"], "Discharge Summary will be generated shortly" + ) + + def test_patient_from_asset(self): + asset1_location = AssetLocation.objects.create( + name="asset1 location", location_type=1, facility=self.facility + ) + asset = Asset.objects.create( + name="Test Asset", + current_location=asset1_location, + asset_type=50, + warranty_amc_end_of_validity=make_aware( + datetime.datetime(2020, 4, 1, 15, 30, 00) + ), + asset_class=AssetClasses.ONVIF.name, + meta={ + "asset_type": "CAMERA", + "local_ip_address": "192.168.0.65", + "camera_access_key": "remoteuser:aeAE55L5Po*S*C5:3af9acd0-2d4a-49e4-bb72-45cf7be0ae65", + "middleware_hostname": "ka-kr-mysore.10bedicu.in", + }, + ) + bed = Bed.objects.create( + name="Fake Bed", + description="This is a fake Bed", + bed_type=5, + facility=self.facility, + location=asset1_location, + ) + + bed.assets.add(asset) + self.user.asset = asset + self.user.save() + self.user.refresh_from_db() + + url = "/api/v1/consultation/patient_from_asset/" + res = self.client.get(url) + self.assertEqual(res.status_code, status.HTTP_404_NOT_FOUND) + + consultation_bed = ConsultationBed.objects.create( + consultation=self.consultation, + bed=bed, + start_date=make_aware(datetime.datetime(2020, 4, 1, 15, 30, 00)), + ) + self.consultation.current_bed = consultation_bed + self.consultation.save() + self.consultation.refresh_from_db() + consultation_bed.assets.add(asset) + consultation_bed.refresh_from_db() + + url = "/api/v1/consultation/patient_from_asset/" + res = self.client.get(url) + self.assertEqual(res.status_code, status.HTTP_200_OK) + + def test_preview_discharge_summary(self): + url = f"/api/v1/consultation/{self.consultation.external_id}/preview_discharge_summary/" + res = self.client.get(url) + self.assertEqual(res.status_code, status.HTTP_202_ACCEPTED) + self.assertEqual( + res.data["detail"], "Discharge Summary will be generated shortly" + ) diff --git a/care/utils/tests/test_base.py b/care/utils/tests/test_base.py index 25427225e3..677d84748c 100644 --- a/care/utils/tests/test_base.py +++ b/care/utils/tests/test_base.py @@ -23,7 +23,7 @@ PatientRegistration, User, ) -from care.users.models import District, State +from care.users.models import District, State, Ward from config.tests.helper import EverythingEquals, mock_equal @@ -83,7 +83,7 @@ def create_state(cls) -> State: @classmethod def create_facility( - cls, district: District, user: User = None, **kwargs + cls, district: District, user: User = None, ward=None, local_body=None, **kwargs ) -> Facility: user = user or cls.user data = { @@ -95,6 +95,8 @@ def create_facility( "oxygen_capacity": 10, "phone_number": "9998887776", "created_by": user, + "ward": ward or cls.ward, + "local_body": local_body or cls.local_body, } data.update(kwargs) f = Facility(**data) @@ -231,6 +233,8 @@ def setUpClass(cls) -> None: cls.user_type = User.TYPE_VALUE_MAP["Staff"] cls.user = cls.create_user(cls.district) cls.super_user = cls.create_super_user(district=cls.district) + cls.local_body = cls.create_local_body(cls.district) + cls.ward = cls.create_ward() cls.facility = cls.create_facility(cls.district) cls.patient = cls.create_patient() cls.state_admin = cls.create_user( @@ -455,3 +459,21 @@ def create_patient_note( ) self.client.post(f"/api/v1/patient/{patientId}/notes/", data=data) + + @classmethod + def create_ward(cls, local_body=None, name=None, number=10, **kwargs): + data = { + "local_body": local_body or cls.local_body, + "name": "Test Ward", + "number": number, + } + return Ward.objects.create(**data) + + @classmethod + def create_local_body(cls, district=None, name=None, body_type=1, **kwargs): + data = { + "district": district or cls.district, + "name": name or "Test Local Body", + "body_type": body_type, + } + return LocalBody.objects.create(**data)