Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed: Added depth in consultation model for symptoms #1063

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 52 additions & 3 deletions care/facility/api/serializers/patient_consultation.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@
SYMPTOM_CHOICES,
SuggestionChoices,
)
from care.facility.models.patient_consultation import PatientConsultation
from care.facility.models.patient_consultation import (
PatientConsultation,
PatientConsultationSymptom,
)
from care.facility.static_data.icd11 import get_icd11_diagnoses_objects_by_ids
from care.users.api.serializers.user import (
UserAssignedSerializer,
Expand All @@ -37,6 +40,24 @@
from config.serializers import ChoiceField


class PatientConsultationSymptomSerializer(serializers.ModelSerializer):
id = serializers.CharField(source="external_id", read_only=True)
consultation = ExternalIdSerializerField(
queryset=PatientConsultation.objects.all(),
required=False,
)
symptom = ChoiceField(choices=SYMPTOM_CHOICES)

class Meta:
model = PatientConsultationSymptom
fields = (
"id",
"symptom",
"symptom_onset_date",
"consultation",
)


class PatientConsultationSerializer(serializers.ModelSerializer):
id = serializers.CharField(source="external_id", read_only=True)
facility_name = serializers.CharField(source="facility.name", read_only=True)
Expand All @@ -46,7 +67,9 @@ class PatientConsultationSerializer(serializers.ModelSerializer):
source="suggestion",
)

symptoms = serializers.MultipleChoiceField(choices=SYMPTOM_CHOICES)
patient_symptoms = serializers.ListSerializer(
child=PatientConsultationSymptomSerializer(), required=False
)
deprecated_covid_category = ChoiceField(
choices=COVID_CATEGORY_CHOICES, required=False
)
Expand Down Expand Up @@ -182,9 +205,23 @@ def update(self, instance, validated_data):
validated_data["kasp_enabled_date"] = localtime(now())

_temp = instance.assigned_to

symptoms = validated_data.pop("patient_symptoms", [])
consultation = super().update(instance, validated_data)

PatientConsultationSymptom.objects.filter(consultation=consultation).update(
deleted=True
)
if consultation.is_asymptomatic is False:
symptoms_list = []
for symptom in symptoms:
symptoms_list.append(
PatientConsultationSymptom(consultation=consultation, **symptom)
)
if symptoms_list:
PatientConsultationSymptom.objects.bulk_create(
symptoms_list, ignore_conflicts=True
)

if "assigned_to" in validated_data:
if validated_data["assigned_to"] != _temp and validated_data["assigned_to"]:
NotificationGenerator(
Expand Down Expand Up @@ -249,6 +286,7 @@ def create(self, validated_data):
validated_data["kasp_enabled_date"] = localtime(now())

bed = validated_data.pop("bed", None)
symptoms = validated_data.pop("patient_symptoms", [])

validated_data["facility_id"] = validated_data[
"patient"
Expand All @@ -268,6 +306,17 @@ def create(self, validated_data):
consultation.current_bed = consultation_bed
consultation.save(update_fields=["current_bed"])

if consultation.is_asymptomatic is False:
symptoms_list = []
for symptom in symptoms:
symptoms_list.append(
PatientConsultationSymptom(consultation=consultation, **symptom)
)
if symptoms_list:
PatientConsultationSymptom.objects.bulk_create(
symptoms_list, ignore_conflicts=True
)

patient = consultation.patient
if consultation.suggestion == SuggestionChoices.OP:
consultation.discharge_date = localtime(now())
Expand Down
123 changes: 123 additions & 0 deletions care/facility/migrations/0322_auto_20220930_1825.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Generated by Django 2.2.11 on 2022-09-30 12:55

from datetime import datetime
from django.db import migrations, models
import django.db.models.deletion
import partial_index


def populate_data(apps, schema_editor):
patient_consultation = apps.get_model("facility", "PatientConsultation")
patients_cons = patient_consultation.objects.all()

patient_consultation_symptom = apps.get_model(
"facility", "PatientConsultationSymptom"
)
patient_symptom_objs = []
for patient_cons in patients_cons:
for patient_symptom in patient_cons.symptoms:
onset_date = datetime.now()
if patient_cons.symptoms_onset_date():
onset_date = patient_cons.symptoms_onset_date.date()
patient_symptom_objs.append(
patient_consultation_symptom(
consultation=patient_cons,
symptom=patient_symptom,
symptom_onset_date=onset_date,
)
)

patient_consultation_symptom.objects.bulk_create(patient_symptom_objs)


class Migration(migrations.Migration):

dependencies = [
("facility", "0321_merge_20220921_2255"),
]

operations = [
migrations.CreateModel(
name="PatientConsultationSymptom",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"symptom",
models.IntegerField(
blank=True,
choices=[
(1, "ASYMPTOMATIC"),
(2, "FEVER"),
(3, "SORE THROAT"),
(4, "COUGH"),
(5, "BREATHLESSNESS"),
(6, "MYALGIA"),
(7, "ABDOMINAL DISCOMFORT"),
(8, "VOMITING/DIARRHOEA"),
(9, "OTHERS"),
(10, "SARI"),
(11, "SPUTUM"),
(12, "NAUSEA"),
(13, "CHEST PAIN"),
(14, "HEMOPTYSIS"),
(15, "NASAL DISCHARGE"),
(16, "BODY ACHE"),
],
default=1,
null=True,
),
),
(
"symptom_onset_date",
models.DateField(blank=True, null=True),
),
(
"deleted",
models.BooleanField(default=False),
),
(
"consultation",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="patient_symptoms",
to="facility.PatientConsultation",
),
),
],
),
migrations.AddIndex(
model_name="patientconsultationsymptom",
index=partial_index.PartialIndex(
fields=["consultation", "symptom"],
name="facility_pa_consult_6f7ce1_partial",
unique=True,
where=partial_index.PQ(deleted=False),
),
),
migrations.RunPython(populate_data, migrations.RunPython.noop),
migrations.AddField(
model_name="patientconsultation",
name="is_asymptomatic",
field=models.BooleanField(default=False),
),
migrations.RemoveField(
model_name="patientconsultation",
name="other_symptoms",
),
migrations.RemoveField(
model_name="patientconsultation",
name="symptoms",
),
migrations.RemoveField(
model_name="patientconsultation",
name="symptoms_onset_date",
),
]
14 changes: 14 additions & 0 deletions care/facility/migrations/0325_merge_20221014_1415.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Generated by Django 2.2.11 on 2022-10-14 08:45

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('facility', '0322_auto_20220930_1825'),
('facility', '0324_merge_20221013_0053'),
]

operations = [
]
14 changes: 14 additions & 0 deletions care/facility/migrations/0327_merge_20221027_1959.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Generated by Django 2.2.11 on 2022-10-27 14:29

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('facility', '0326_auto_20221018_1526'),
('facility', '0322_auto_20220930_1825'),
]

operations = [
]
35 changes: 35 additions & 0 deletions care/facility/migrations/0328_auto_20221027_1959.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Generated by Django 2.2.11 on 2022-10-27 14:29

from django.db import migrations, models
import uuid


class Migration(migrations.Migration):

dependencies = [
("facility", "0327_merge_20221027_1959"),
]

operations = [
migrations.AddField(
model_name="patientconsultationsymptom",
name="created_date",
field=models.DateTimeField(
auto_now_add=True, db_index=True, null=True
),
),
migrations.AddField(
model_name="patientconsultationsymptom",
name="external_id",
field=models.UUIDField(
db_index=True, default=uuid.uuid4, unique=True
),
),
migrations.AddField(
model_name="patientconsultationsymptom",
name="modified_date",
field=models.DateTimeField(
auto_now=True, db_index=True, null=True
),
),
]
47 changes: 38 additions & 9 deletions care/facility/models/patient_consultation.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.contrib.postgres.fields import ArrayField, JSONField
from django.core.validators import MinValueValidator
from django.db import models
from multiselectfield import MultiSelectField
from partial_index import PQ, PartialIndex

from care.facility.models import (
CATEGORY_CHOICES,
Expand All @@ -22,6 +22,7 @@
reverse_choices,
)
from care.users.models import User
from care.utils.models.base import BaseManager


class PatientConsultation(PatientBaseModel, PatientRelatedPermissionMixin):
Expand All @@ -42,6 +43,7 @@ class PatientConsultation(PatientBaseModel, PatientRelatedPermissionMixin):
)

ip_no = models.CharField(max_length=100, default="", null=True, blank=True)
is_asymptomatic = models.BooleanField(default=False)
op_no = models.CharField(max_length=100, default="", null=True, blank=True)

facility = models.ForeignKey(
Expand All @@ -54,11 +56,6 @@ class PatientConsultation(PatientBaseModel, PatientRelatedPermissionMixin):
icd11_diagnoses = ArrayField(
models.CharField(max_length=100), default=[], blank=True, null=True
)
symptoms = MultiSelectField(
choices=SYMPTOM_CHOICES, default=1, null=True, blank=True
)
other_symptoms = models.TextField(default="", blank=True)
symptoms_onset_date = models.DateTimeField(null=True, blank=True)
deprecated_covid_category = models.CharField(
choices=COVID_CATEGORY_CHOICES,
max_length=8,
Expand Down Expand Up @@ -191,8 +188,8 @@ class PatientConsultation(PatientBaseModel, PatientRelatedPermissionMixin):
CSV_MAPPING = {
"consultation_created_date": "Date of Consultation",
"admission_date": "Date of Admission",
"symptoms_onset_date": "Date of Onset of Symptoms",
"symptoms": "Symptoms at time of consultation",
# "symptoms_onset_date": "Date of Onset of Symptoms",
# "symptoms": "Symptoms at time of consultation",
"deprecated_covid_category": "Covid Category",
"category": "Category",
"examination_details": "Examination Details",
Expand Down Expand Up @@ -245,7 +242,7 @@ class Meta:
check=models.Q(admitted=False) | models.Q(admission_date__isnull=False),
),
]

def has_object_discharge_patient_permission(self, request):
return self.has_object_update_permission(request)

Expand All @@ -254,3 +251,35 @@ def has_object_email_discharge_summary_permission(self, request):

def has_object_generate_discharge_summary_permission(self, request):
return self.has_object_read_permission(request)


class PatientConsultationSymptom(PatientBaseModel, PatientRelatedPermissionMixin):
consultation = models.ForeignKey(
PatientConsultation,
on_delete=models.CASCADE,
related_name="patient_symptoms",
)
symptom = models.IntegerField(
choices=SYMPTOM_CHOICES, default=1, null=True, blank=True
)
symptom_onset_date = models.DateField(null=True, blank=True)
deleted = models.BooleanField(default=False)
objects = BaseManager()

class Meta:
indexes = [
PartialIndex(
fields=["consultation", "symptom"],
aeswibon marked this conversation as resolved.
Show resolved Hide resolved
unique=True,
where=PQ(deleted=False),
)
]

def __str__(self):
return (
self.patient_consultation.patient.name + " - " + self.get_symptom_display()
)

def get_symptom_display(self):
return SYMPTOM_CHOICES[self.symptom - 1][1]