Skip to content

Commit

Permalink
Fix a race condition which allowed duplicate consultations to be created
Browse files Browse the repository at this point in the history
  • Loading branch information
sainak committed Jul 9, 2024
1 parent 7d756d6 commit dbeb92d
Showing 1 changed file with 34 additions and 39 deletions.
73 changes: 34 additions & 39 deletions care/facility/api/serializers/patient_consultation.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,55 +353,50 @@ def create(self, validated_data):

create_diagnosis = validated_data.pop("create_diagnoses")
create_symptoms = validated_data.pop("create_symptoms")
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")

action = validated_data.pop("action", -1)
review_interval = validated_data.get("review_interval", -1)

# Authorisation Check

allowed_facilities = get_home_facility_queryset(self.context["request"].user)
user = self.context["request"].user
allowed_facilities = get_home_facility_queryset(user)
if not allowed_facilities.filter(
id=self.validated_data["patient"].facility.id
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
):
patient = PatientRegistration.objects.select_for_update().get(
id=validated_data["patient"].id
)

if patient.last_consultation:
if patient.last_consultation.assigned_to == user:
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:
if not 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())
validated_data["kasp_enabled_date"] = now()

Check warning on line 392 in care/facility/api/serializers/patient_consultation.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_consultation.py#L392

Added line #L392 was not covered by tests

bed = validated_data.pop("bed", None)
# Coercing facility as the patient's facility
validated_data["facility_id"] = patient.facility_id

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
patient = consultation.patient
consultation: PatientConsultation = super().create(validated_data)
consultation.created_by = user
consultation.last_edited_by = user
consultation.previous_consultation = patient.last_consultation
last_consultation = patient.last_consultation
if (
Expand All @@ -413,7 +408,6 @@ def create(self, validated_data):
> consultation.encounter_date
):
consultation.is_readmission = True
consultation.save()

diagnosis = ConsultationDiagnosis.objects.bulk_create(
[
Expand All @@ -422,7 +416,7 @@ def create(self, validated_data):
diagnosis_id=obj["diagnosis"].id,
is_principal=obj["is_principal"],
verification_status=obj["verification_status"],
created_by=self.context["request"].user,
created_by=user,
)
for obj in create_diagnosis
]
Expand All @@ -436,11 +430,12 @@ def create(self, validated_data):
cure_date=obj.get("cure_date"),
clinical_impression_status=obj.get("clinical_impression_status"),
other_symptom=obj.get("other_symptom") or "",
created_by=self.context["request"].user,
created_by=user,
)
for obj in create_symptoms
)

bed = validated_data.pop("bed", None)
if bed and consultation.suggestion == SuggestionChoices.A:
consultation_bed = ConsultationBed(
bed=bed,
Expand All @@ -449,11 +444,9 @@ def create(self, validated_data):
)
consultation_bed.save()
consultation.current_bed = consultation_bed
consultation.save(update_fields=["current_bed"])

if consultation.suggestion == SuggestionChoices.OP:
consultation.discharge_date = localtime(now())
consultation.save()
consultation.discharge_date = now()
patient.is_active = False
patient.allow_transfer = True
else:
Expand All @@ -462,19 +455,14 @@ def create(self, validated_data):

if action != -1:
patient.action = action
consultation.review_interval = review_interval

if review_interval > 0:
patient.review_time = localtime(now()) + timedelta(minutes=review_interval)
patient.review_time = now() + timedelta(minutes=review_interval)

Check warning on line 460 in care/facility/api/serializers/patient_consultation.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_consultation.py#L460

Added line #L460 was not covered by tests
else:
patient.review_time = None

consultation.save()
patient.save()
NotificationGenerator(
event=Notification.Event.PATIENT_CONSULTATION_CREATED,
caused_by=self.context["request"].user,
caused_object=consultation,
facility=patient.facility,
).generate()

create_consultation_events(
consultation.id,
Expand All @@ -483,10 +471,17 @@ def create(self, validated_data):
consultation.created_date,
)

NotificationGenerator(
event=Notification.Event.PATIENT_CONSULTATION_CREATED,
caused_by=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_by=user,
caused_object=consultation,
facility=consultation.patient.facility,
notification_mediums=[
Expand Down

0 comments on commit dbeb92d

Please sign in to comment.