From 335f66a21648fcd23818c9aac183075355c3786e Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Tue, 12 Mar 2024 15:03:05 +0530 Subject: [PATCH 01/19] drop field `age` and compute age on demand --- care/facility/api/serializers/patient.py | 21 +++++++-- care/facility/api/serializers/patient_icmr.py | 2 +- ...toricalpatientregistration_age_and_more.py | 20 ++++++++ care/facility/models/patient.py | 46 ++++++++++--------- 4 files changed, 61 insertions(+), 28 deletions(-) create mode 100644 care/facility/migrations/0420_remove_historicalpatientregistration_age_and_more.py diff --git a/care/facility/api/serializers/patient.py b/care/facility/api/serializers/patient.py index 721df68fbe..0c9484f92a 100644 --- a/care/facility/api/serializers/patient.py +++ b/care/facility/api/serializers/patient.py @@ -115,6 +115,14 @@ def get_approved_claim_amount(self, patient): ) return claim.total_claim_amount if claim is not None else None + death_datetime = serializers.DateTimeField( + source="last_consultation__death_datetime", + read_only=True, + allow_null=True, + ) + age = serializers.IntegerField(read_only=True) + age_days = serializers.IntegerField(read_only=True) + class Meta: model = PatientRegistration exclude = ( @@ -223,7 +231,6 @@ class Meta: model = PatientRegistration exclude = ( "deleted", - "year_of_birth", "countries_travelled_old", "external_id", ) @@ -252,11 +259,15 @@ def validate(self, attrs): validated = super().validate(attrs) if ( not self.partial - and not validated.get("age") + and not validated.get("year_of_birth") and not validated.get("date_of_birth") ): raise serializers.ValidationError( - {"non_field_errors": ["Either age or date_of_birth should be passed"]} + { + "non_field_errors": [ + "Either year_of_birth or date_of_birth should be passed" + ] + } ) if validated.get("is_vaccinated"): @@ -361,8 +372,8 @@ def update(self, instance, validated_data): if meta_info: if patient.meta_info is None: - meta_info_obj = PatientMetaInfo.objects.create(**meta_info) - patient.meta_info = meta_info_obj + meta_info_obj = PatientMetaInfo.objects.create(**meta_info) + patient.meta_info = meta_info_obj else: for key, value in meta_info.items(): setattr(patient.meta_info, key, value) diff --git a/care/facility/api/serializers/patient_icmr.py b/care/facility/api/serializers/patient_icmr.py index e252ea4631..2d6056b33f 100644 --- a/care/facility/api/serializers/patient_icmr.py +++ b/care/facility/api/serializers/patient_icmr.py @@ -11,7 +11,7 @@ class ICMRPersonalDetails(serializers.ModelSerializer): - age_years = serializers.IntegerField() + age_years = serializers.IntegerField(source="age") age_months = serializers.IntegerField() gender = ChoiceField(choices=GENDER_CHOICES) email = serializers.EmailField(allow_blank=True) diff --git a/care/facility/migrations/0420_remove_historicalpatientregistration_age_and_more.py b/care/facility/migrations/0420_remove_historicalpatientregistration_age_and_more.py new file mode 100644 index 0000000000..88a0d80a7c --- /dev/null +++ b/care/facility/migrations/0420_remove_historicalpatientregistration_age_and_more.py @@ -0,0 +1,20 @@ +# Generated by Django 4.2.8 on 2024-03-12 05:46 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("facility", "0419_alter_patientconsultation_patient_no"), + ] + + operations = [ + migrations.RemoveField( + model_name="historicalpatientregistration", + name="age", + ), + migrations.RemoveField( + model_name="patientregistration", + name="age", + ), + ] diff --git a/care/facility/models/patient.py b/care/facility/models/patient.py index 1c5408bebe..3946a17230 100644 --- a/care/facility/models/patient.py +++ b/care/facility/models/patient.py @@ -1,10 +1,11 @@ -import datetime import enum +from dateutil.relativedelta import relativedelta from django.contrib.postgres.aggregates import ArrayAgg from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models from django.db.models import JSONField +from django.utils import timezone from simple_history.models import HistoricalRecords from care.abdm.models import AbhaNumber @@ -109,7 +110,6 @@ class TestTypeEnum(enum.Enum): # name_old = EncryptedCharField(max_length=200, default="") name = models.CharField(max_length=200, default="") - age = models.PositiveIntegerField(null=True, blank=True) gender = models.IntegerField(choices=GENDER_CHOICES, blank=False) # phone_number_old = EncryptedCharField(max_length=14, validators=[phone_number_regex], default="") @@ -426,7 +426,26 @@ class TestTypeEnum(enum.Enum): objects = BaseManager() def __str__(self): - return "{} - {} - {}".format(self.name, self.age, self.get_gender_display()) + return "{} - {} - {}".format( + self.name, self.year_of_birth, self.get_gender_display() + ) + + def get_age_delta(self): + start = self.date_of_birth or timezone.datetime(self.year_of_birth, 1, 1).date() + end = ( + self.last_consultation + and self.last_consultation.death_datetime + or timezone.now() + ).date() + return relativedelta(end, start) + + @property + def age(self): + return self.get_age_delta().years + + @property + def age_days(self): + return self.get_age_delta().days @property def tele_consultation_history(self): @@ -458,30 +477,13 @@ def save(self, *args, **kwargs) -> None: if self.district is not None: self.state = self.district.state - self.year_of_birth = ( - self.date_of_birth.year - if self.date_of_birth is not None - else datetime.datetime.now().year - self.age - ) - - today = datetime.date.today() - if self.date_of_birth: - self.age = ( - today.year - - self.date_of_birth.year - - ( - (today.month, today.day) - < (self.date_of_birth.month, self.date_of_birth.day) - ) - ) - elif self.year_of_birth: - self.age = today.year - self.year_of_birth + self.year_of_birth = self.date_of_birth.year self.date_of_receipt_of_information = ( self.date_of_receipt_of_information if self.date_of_receipt_of_information is not None - else datetime.datetime.now() + else timezone.now() ) self._alias_recovery_to_recovered() From 9ce7e6aa4fdfcad003c1f4c47f90cb15404f0a35 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Tue, 12 Mar 2024 15:17:54 +0530 Subject: [PATCH 02/19] Update filters and related usages --- care/facility/admin.py | 2 +- care/facility/api/viewsets/patient.py | 12 +++++++----- care/facility/models/patient_icmr.py | 21 +-------------------- 3 files changed, 9 insertions(+), 26 deletions(-) diff --git a/care/facility/admin.py b/care/facility/admin.py index bc5b3fb650..bfc524b658 100644 --- a/care/facility/admin.py +++ b/care/facility/admin.py @@ -147,7 +147,7 @@ class AmbulanceDriverAdmin(DjangoQLSearchMixin, admin.ModelAdmin): class PatientAdmin(DjangoQLSearchMixin, admin.ModelAdmin): - list_display = ("id", "name", "age", "gender") + list_display = ("id", "name", "gender") djangoql_completion_enabled_by_default = True diff --git a/care/facility/api/viewsets/patient.py b/care/facility/api/viewsets/patient.py index 631928d5f4..c948850e70 100644 --- a/care/facility/api/viewsets/patient.py +++ b/care/facility/api/viewsets/patient.py @@ -99,9 +99,13 @@ class PatientFilterSet(filters.FilterSet): field_name="last_consultation__patient_no", lookup_expr="icontains" ) gender = filters.NumberFilter(field_name="gender") - age = filters.NumberFilter(field_name="age") - age_min = filters.NumberFilter(field_name="age", lookup_expr="gte") - age_max = filters.NumberFilter(field_name="age", lookup_expr="lte") + year_of_birth = filters.NumberFilter(field_name="year_of_birth") + year_of_birth_min = filters.NumberFilter( + field_name="year_of_birth", lookup_expr="gte" + ) + year_of_birth_max = filters.NumberFilter( + field_name="year_of_birth", lookup_expr="lte" + ) deprecated_covid_category = filters.ChoiceFilter( field_name="last_consultation__deprecated_covid_category", choices=COVID_CATEGORY_CHOICES, @@ -643,14 +647,12 @@ def get_queryset(self): "year_of_birth", "phone_number", "name", - "age", ] else: search_keys = [ "date_of_birth", "year_of_birth", "phone_number", - "age", ] search_fields = { key: serializer.validated_data[key] diff --git a/care/facility/models/patient_icmr.py b/care/facility/models/patient_icmr.py index 5d33c25ed3..40c6f06ed6 100644 --- a/care/facility/models/patient_icmr.py +++ b/care/facility/models/patient_icmr.py @@ -1,7 +1,5 @@ import datetime -from dateutil.relativedelta import relativedelta - from care.facility.models import ( DISEASE_CHOICES_MAP, SYMPTOM_CHOICES, @@ -45,26 +43,9 @@ class Meta: # instance.__class__ = PatientSampleICMR # return instance - @property - def age_years(self): - if self.date_of_birth is not None: - age_years = relativedelta(datetime.datetime.now(), self.date_of_birth).years - else: - age_years = relativedelta( - datetime.datetime.now(), - datetime.datetime(year=self.year_of_birth, month=1, day=1), - ).years - return age_years - @property def age_months(self): - if self.date_of_birth is None or self.year_of_birth is None: - age_months = 0 - else: - age_months = relativedelta( - datetime.datetime.now(), self.date_of_birth - ).months - return age_months + return self.get_age_delta().months @property def email(self): From 4f9b8069a72b01ba3b73ae4e39cae4d3f4fe09ba Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Tue, 12 Mar 2024 19:09:45 +0530 Subject: [PATCH 03/19] add min value validator for year of birth --- ...toricalpatientregistration_age_and_more.py | 23 +++++++++++++++++-- care/facility/models/patient.py | 4 +++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/care/facility/migrations/0420_remove_historicalpatientregistration_age_and_more.py b/care/facility/migrations/0420_remove_historicalpatientregistration_age_and_more.py index 88a0d80a7c..c688ef68cf 100644 --- a/care/facility/migrations/0420_remove_historicalpatientregistration_age_and_more.py +++ b/care/facility/migrations/0420_remove_historicalpatientregistration_age_and_more.py @@ -1,6 +1,7 @@ -# Generated by Django 4.2.8 on 2024-03-12 05:46 +# Generated by Django 4.2.8 on 2024-03-12 13:39 -from django.db import migrations +import django.core.validators +from django.db import migrations, models class Migration(migrations.Migration): @@ -17,4 +18,22 @@ class Migration(migrations.Migration): model_name="patientregistration", name="age", ), + migrations.AlterField( + model_name="historicalpatientregistration", + name="year_of_birth", + field=models.IntegerField( + default=0, + null=True, + validators=[django.core.validators.MinValueValidator(1900)], + ), + ), + migrations.AlterField( + model_name="patientregistration", + name="year_of_birth", + field=models.IntegerField( + default=0, + null=True, + validators=[django.core.validators.MinValueValidator(1900)], + ), + ), ] diff --git a/care/facility/models/patient.py b/care/facility/models/patient.py index 3946a17230..f70083b5ec 100644 --- a/care/facility/models/patient.py +++ b/care/facility/models/patient.py @@ -128,7 +128,9 @@ class TestTypeEnum(enum.Enum): pincode = models.IntegerField(default=0, blank=True, null=True) date_of_birth = models.DateField(default=None, null=True) - year_of_birth = models.IntegerField(default=0, null=True) + year_of_birth = models.IntegerField( + validators=[MinValueValidator(1900)], default=0, null=True + ) nationality = models.CharField( max_length=255, default="", verbose_name="Nationality of Patient" From 8f8a67f10b9afa82b08b2f128a5000353614fa41 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Tue, 12 Mar 2024 19:09:55 +0530 Subject: [PATCH 04/19] remove age from test utils --- care/utils/tests/test_utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/care/utils/tests/test_utils.py b/care/utils/tests/test_utils.py index ccc6b17628..a4d366c39b 100644 --- a/care/utils/tests/test_utils.py +++ b/care/utils/tests/test_utils.py @@ -238,7 +238,6 @@ def create_facility( def get_patient_data(cls, district, state) -> dict: return { "name": "Foo", - "age": 32, "date_of_birth": date(1992, 4, 1), "gender": 2, "is_medical_worker": True, From 7c4fbb316036d877b07afec67959a97321d8a412 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Tue, 12 Mar 2024 19:10:56 +0530 Subject: [PATCH 05/19] remove unnecessary default --- ...emove_historicalpatientregistration_age_and_more.py | 10 +++------- care/facility/models/patient.py | 4 +--- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/care/facility/migrations/0420_remove_historicalpatientregistration_age_and_more.py b/care/facility/migrations/0420_remove_historicalpatientregistration_age_and_more.py index c688ef68cf..858699a923 100644 --- a/care/facility/migrations/0420_remove_historicalpatientregistration_age_and_more.py +++ b/care/facility/migrations/0420_remove_historicalpatientregistration_age_and_more.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.8 on 2024-03-12 13:39 +# Generated by Django 4.2.8 on 2024-03-12 13:40 import django.core.validators from django.db import migrations, models @@ -22,18 +22,14 @@ class Migration(migrations.Migration): model_name="historicalpatientregistration", name="year_of_birth", field=models.IntegerField( - default=0, - null=True, - validators=[django.core.validators.MinValueValidator(1900)], + null=True, validators=[django.core.validators.MinValueValidator(1900)] ), ), migrations.AlterField( model_name="patientregistration", name="year_of_birth", field=models.IntegerField( - default=0, - null=True, - validators=[django.core.validators.MinValueValidator(1900)], + null=True, validators=[django.core.validators.MinValueValidator(1900)] ), ), ] diff --git a/care/facility/models/patient.py b/care/facility/models/patient.py index f70083b5ec..20ce06c6f5 100644 --- a/care/facility/models/patient.py +++ b/care/facility/models/patient.py @@ -128,9 +128,7 @@ class TestTypeEnum(enum.Enum): pincode = models.IntegerField(default=0, blank=True, null=True) date_of_birth = models.DateField(default=None, null=True) - year_of_birth = models.IntegerField( - validators=[MinValueValidator(1900)], default=0, null=True - ) + year_of_birth = models.IntegerField(validators=[MinValueValidator(1900)], null=True) nationality = models.CharField( max_length=255, default="", verbose_name="Nationality of Patient" From 031572347a7d3bb840da61b80c0817ba1479c9aa Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Wed, 13 Mar 2024 15:08:56 +0530 Subject: [PATCH 06/19] Add field `death_datetime` in patient registration --- care/facility/admin.py | 2 +- care/facility/api/serializers/patient.py | 15 ++-- care/facility/api/serializers/patient_icmr.py | 2 +- care/facility/api/viewsets/patient.py | 81 ++++++++++++------- ...toricalpatientregistration_age_and_more.py | 35 -------- ..._add_patientregistration_death_datetime.py | 63 +++++++++++++++ care/facility/models/patient.py | 23 +----- care/facility/models/patient_consultation.py | 3 + care/facility/models/patient_icmr.py | 12 +++ 9 files changed, 143 insertions(+), 93 deletions(-) delete mode 100644 care/facility/migrations/0420_remove_historicalpatientregistration_age_and_more.py create mode 100644 care/facility/migrations/0420_remove_patientregistration_age_and_add_patientregistration_death_datetime.py diff --git a/care/facility/admin.py b/care/facility/admin.py index bfc524b658..db0ac6a173 100644 --- a/care/facility/admin.py +++ b/care/facility/admin.py @@ -147,7 +147,7 @@ class AmbulanceDriverAdmin(DjangoQLSearchMixin, admin.ModelAdmin): class PatientAdmin(DjangoQLSearchMixin, admin.ModelAdmin): - list_display = ("id", "name", "gender") + list_display = ("id", "name", "year_of_birth", "gender") djangoql_completion_enabled_by_default = True diff --git a/care/facility/api/serializers/patient.py b/care/facility/api/serializers/patient.py index 0c9484f92a..3fe441f241 100644 --- a/care/facility/api/serializers/patient.py +++ b/care/facility/api/serializers/patient.py @@ -115,11 +115,6 @@ def get_approved_claim_amount(self, patient): ) return claim.total_claim_amount if claim is not None else None - death_datetime = serializers.DateTimeField( - source="last_consultation__death_datetime", - read_only=True, - allow_null=True, - ) age = serializers.IntegerField(read_only=True) age_days = serializers.IntegerField(read_only=True) @@ -129,13 +124,12 @@ class Meta: "created_by", "deleted", "ongoing_medication", - "year_of_birth", "meta_info", "countries_travelled_old", "allergies", "external_id", ) - read_only = TIMESTAMP_FIELDS + read_only = TIMESTAMP_FIELDS + ("death_datetime",) class PatientContactDetailsSerializer(serializers.ModelSerializer): @@ -235,7 +229,12 @@ class Meta: "external_id", ) include = ("contacted_patients",) - read_only = TIMESTAMP_FIELDS + ("last_edited", "created_by", "is_active") + read_only = TIMESTAMP_FIELDS + ( + "last_edited", + "created_by", + "is_active", + "death_datetime", + ) # def get_last_consultation(self, obj): # last_consultation = PatientConsultation.objects.filter(patient=obj).last() diff --git a/care/facility/api/serializers/patient_icmr.py b/care/facility/api/serializers/patient_icmr.py index 2d6056b33f..e252ea4631 100644 --- a/care/facility/api/serializers/patient_icmr.py +++ b/care/facility/api/serializers/patient_icmr.py @@ -11,7 +11,7 @@ class ICMRPersonalDetails(serializers.ModelSerializer): - age_years = serializers.IntegerField(source="age") + age_years = serializers.IntegerField() age_months = serializers.IntegerField() gender = ChoiceField(choices=GENDER_CHOICES) email = serializers.EmailField(allow_blank=True) diff --git a/care/facility/api/viewsets/patient.py b/care/facility/api/viewsets/patient.py index c948850e70..c587604cc0 100644 --- a/care/facility/api/viewsets/patient.py +++ b/care/facility/api/viewsets/patient.py @@ -5,7 +5,8 @@ from django.conf import settings from django.contrib.postgres.search import TrigramSimilarity from django.db import models -from django.db.models import Case, OuterRef, Q, Subquery, When +from django.db.models import Case, F, Func, OuterRef, Q, Subquery, Value, When +from django.db.models.functions import Coalesce, Now from django.db.models.query import QuerySet from django_filters import rest_framework as filters from djqscsv import render_to_csv_response @@ -99,13 +100,9 @@ class PatientFilterSet(filters.FilterSet): field_name="last_consultation__patient_no", lookup_expr="icontains" ) gender = filters.NumberFilter(field_name="gender") - year_of_birth = filters.NumberFilter(field_name="year_of_birth") - year_of_birth_min = filters.NumberFilter( - field_name="year_of_birth", lookup_expr="gte" - ) - year_of_birth_max = filters.NumberFilter( - field_name="year_of_birth", lookup_expr="lte" - ) + age = filters.NumberFilter(field_name="age") + age_min = filters.NumberFilter(field_name="age", lookup_expr="gte") + age_max = filters.NumberFilter(field_name="age", lookup_expr="lte") deprecated_covid_category = filters.ChoiceFilter( field_name="last_consultation__deprecated_covid_category", choices=COVID_CATEGORY_CHOICES, @@ -337,25 +334,53 @@ class PatientViewSet( ] permission_classes = (IsAuthenticated, DRYPermissions) lookup_field = "external_id" - queryset = PatientRegistration.objects.all().select_related( - "local_body", - "district", - "state", - "ward", - "assigned_to", - "facility", - "facility__ward", - "facility__local_body", - "facility__district", - "facility__state", - # "nearest_facility", - # "nearest_facility__local_body", - # "nearest_facility__district", - # "nearest_facility__state", - "last_consultation", - "last_consultation__assigned_to", - "last_edited", - "created_by", + queryset = ( + PatientRegistration.objects.all() + .select_related( + "local_body", + "district", + "state", + "ward", + "assigned_to", + "facility", + "facility__ward", + "facility__local_body", + "facility__district", + "facility__state", + # "nearest_facility", + # "nearest_facility__local_body", + # "nearest_facility__district", + # "nearest_facility__state", + "last_consultation", + "last_consultation__assigned_to", + "last_edited", + "created_by", + ) + .annotate( + age=Func( + Value("year"), + Func( + Case( + When(death_datetime__isnull=True, then=Now()), + default=F("death_datetime__date"), + ), + Coalesce( + "date_of_birth", + Func( + F("year_of_birth"), + Value(1), + Value(1), + function="MAKE_DATE", + output_field=models.DateField(), + ), + output_field=models.DateField(), + ), + function="age", + ), + function="date_part", + output_field=models.IntegerField(), + ), + ) ) ordering_fields = [ "facility__name", @@ -647,12 +672,14 @@ def get_queryset(self): "year_of_birth", "phone_number", "name", + "age", ] else: search_keys = [ "date_of_birth", "year_of_birth", "phone_number", + "age", ] search_fields = { key: serializer.validated_data[key] diff --git a/care/facility/migrations/0420_remove_historicalpatientregistration_age_and_more.py b/care/facility/migrations/0420_remove_historicalpatientregistration_age_and_more.py deleted file mode 100644 index 858699a923..0000000000 --- a/care/facility/migrations/0420_remove_historicalpatientregistration_age_and_more.py +++ /dev/null @@ -1,35 +0,0 @@ -# Generated by Django 4.2.8 on 2024-03-12 13:40 - -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("facility", "0419_alter_patientconsultation_patient_no"), - ] - - operations = [ - migrations.RemoveField( - model_name="historicalpatientregistration", - name="age", - ), - migrations.RemoveField( - model_name="patientregistration", - name="age", - ), - migrations.AlterField( - model_name="historicalpatientregistration", - name="year_of_birth", - field=models.IntegerField( - null=True, validators=[django.core.validators.MinValueValidator(1900)] - ), - ), - migrations.AlterField( - model_name="patientregistration", - name="year_of_birth", - field=models.IntegerField( - null=True, validators=[django.core.validators.MinValueValidator(1900)] - ), - ), - ] diff --git a/care/facility/migrations/0420_remove_patientregistration_age_and_add_patientregistration_death_datetime.py b/care/facility/migrations/0420_remove_patientregistration_age_and_add_patientregistration_death_datetime.py new file mode 100644 index 0000000000..6099d27306 --- /dev/null +++ b/care/facility/migrations/0420_remove_patientregistration_age_and_add_patientregistration_death_datetime.py @@ -0,0 +1,63 @@ +# Generated by Django 4.2.8 on 2024-03-13 07:03 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("facility", "0419_alter_patientconsultation_patient_no"), + ] + + def populate_patientregistration_death_datetime(apps, schema_editor): + PatientRegistration = apps.get_model("facility", "PatientRegistration") + + patients = PatientRegistration.objects.filter( + last_consultation__death_datetime__isnull=False + ).annotate(new_death_datetime=models.F("last_consultation__death_datetime")) + + for patient in patients: + patient.death_datetime = patient.new_death_datetime + + PatientRegistration.objects.bulk_update( + patients, ["death_datetime"], batch_size=1000 + ) + + operations = [ + migrations.RemoveField( + model_name="historicalpatientregistration", + name="age", + ), + migrations.RemoveField( + model_name="patientregistration", + name="age", + ), + migrations.AddField( + model_name="historicalpatientregistration", + name="death_datetime", + field=models.DateTimeField(default=None, null=True), + ), + migrations.AddField( + model_name="patientregistration", + name="death_datetime", + field=models.DateTimeField(default=None, null=True), + ), + migrations.AlterField( + model_name="historicalpatientregistration", + name="year_of_birth", + field=models.IntegerField( + null=True, validators=[django.core.validators.MinValueValidator(1900)] + ), + ), + migrations.AlterField( + model_name="patientregistration", + name="year_of_birth", + field=models.IntegerField( + null=True, validators=[django.core.validators.MinValueValidator(1900)] + ), + ), + migrations.RunPython( + populate_patientregistration_death_datetime, + migrations.RunPython.noop, + ), + ] diff --git a/care/facility/models/patient.py b/care/facility/models/patient.py index 20ce06c6f5..090fee13fe 100644 --- a/care/facility/models/patient.py +++ b/care/facility/models/patient.py @@ -1,6 +1,5 @@ import enum -from dateutil.relativedelta import relativedelta from django.contrib.postgres.aggregates import ArrayAgg from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models @@ -129,6 +128,7 @@ class TestTypeEnum(enum.Enum): date_of_birth = models.DateField(default=None, null=True) year_of_birth = models.IntegerField(validators=[MinValueValidator(1900)], null=True) + death_datetime = models.DateTimeField(default=None, null=True) nationality = models.CharField( max_length=255, default="", verbose_name="Nationality of Patient" @@ -426,26 +426,7 @@ class TestTypeEnum(enum.Enum): objects = BaseManager() def __str__(self): - return "{} - {} - {}".format( - self.name, self.year_of_birth, self.get_gender_display() - ) - - def get_age_delta(self): - start = self.date_of_birth or timezone.datetime(self.year_of_birth, 1, 1).date() - end = ( - self.last_consultation - and self.last_consultation.death_datetime - or timezone.now() - ).date() - return relativedelta(end, start) - - @property - def age(self): - return self.get_age_delta().years - - @property - def age_days(self): - return self.get_age_delta().days + return f"{self.name} - {self.year_of_birth} - {self.get_gender_display()}" @property def tele_consultation_history(self): diff --git a/care/facility/models/patient_consultation.py b/care/facility/models/patient_consultation.py index 5c9d8802f3..4e780cf327 100644 --- a/care/facility/models/patient_consultation.py +++ b/care/facility/models/patient_consultation.py @@ -277,6 +277,9 @@ def save(self, *args, **kwargs): self.patient.facility = self.referred_to or self.facility self.patient.save() """ + if self.death_datetime and self.patient.death_datetime != self.death_datetime: + self.patient.death_datetime = self.death_datetime + self.patient.save(update_fields=["death_datetime"]) super(PatientConsultation, self).save(*args, **kwargs) class Meta: diff --git a/care/facility/models/patient_icmr.py b/care/facility/models/patient_icmr.py index 40c6f06ed6..9f78befce0 100644 --- a/care/facility/models/patient_icmr.py +++ b/care/facility/models/patient_icmr.py @@ -1,5 +1,8 @@ import datetime +from dateutil.relativedelta import relativedelta +from django.utils import timezone + from care.facility.models import ( DISEASE_CHOICES_MAP, SYMPTOM_CHOICES, @@ -43,6 +46,15 @@ class Meta: # instance.__class__ = PatientSampleICMR # return instance + def get_age_delta(self): + start = self.date_of_birth or timezone.datetime(self.year_of_birth, 1, 1).date() + end = (self.death_datetime or timezone.now()).date() + return relativedelta(end - start) + + @property + def age_years(self): + return self.get_age_delta().years + @property def age_months(self): return self.get_age_delta().months From 4819851a35acf0c5ace62b0d9815a800971624f5 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Wed, 13 Mar 2024 15:56:41 +0530 Subject: [PATCH 07/19] annotate age in days --- care/facility/api/viewsets/patient.py | 52 ++++++++++++++++++--------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/care/facility/api/viewsets/patient.py b/care/facility/api/viewsets/patient.py index c587604cc0..bc475d50f6 100644 --- a/care/facility/api/viewsets/patient.py +++ b/care/facility/api/viewsets/patient.py @@ -5,8 +5,18 @@ from django.conf import settings from django.contrib.postgres.search import TrigramSimilarity from django.db import models -from django.db.models import Case, F, Func, OuterRef, Q, Subquery, Value, When -from django.db.models.functions import Coalesce, Now +from django.db.models import ( + Case, + ExpressionWrapper, + F, + Func, + OuterRef, + Q, + Subquery, + Value, + When, +) +from django.db.models.functions import Coalesce, ExtractDay, Now from django.db.models.query import QuerySet from django_filters import rest_framework as filters from djqscsv import render_to_csv_response @@ -356,30 +366,38 @@ class PatientViewSet( "last_edited", "created_by", ) + .annotate( + coalesced_dob=Coalesce( + "date_of_birth", + Func( + F("year_of_birth"), + Value(1), + Value(1), + function="MAKE_DATE", + output_field=models.DateField(), + ), + output_field=models.DateField(), + ), + age_end=Case( + When(death_datetime__isnull=True, then=Now()), + default=F("death_datetime__date"), + ), + ) .annotate( age=Func( Value("year"), Func( - Case( - When(death_datetime__isnull=True, then=Now()), - default=F("death_datetime__date"), - ), - Coalesce( - "date_of_birth", - Func( - F("year_of_birth"), - Value(1), - Value(1), - function="MAKE_DATE", - output_field=models.DateField(), - ), - output_field=models.DateField(), - ), + F("age_end"), + F("coalesced_dob"), function="age", ), function="date_part", output_field=models.IntegerField(), ), + age_days=ExpressionWrapper( + ExtractDay(F("age_end") - F("coalesced_dob")), + output_field=models.IntegerField(), + ), ) ) ordering_fields = [ From 110a708807299b496d6cb40fb55fb70290a0d2bd Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Wed, 13 Mar 2024 16:21:01 +0530 Subject: [PATCH 08/19] suggestion from code review --- care/facility/api/serializers/patient.py | 6 ++---- care/facility/models/patient_icmr.py | 9 ++++----- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/care/facility/api/serializers/patient.py b/care/facility/api/serializers/patient.py index 3fe441f241..55f1e68a45 100644 --- a/care/facility/api/serializers/patient.py +++ b/care/facility/api/serializers/patient.py @@ -256,10 +256,8 @@ def validate_countries_travelled(self, value): def validate(self, attrs): validated = super().validate(attrs) - if ( - not self.partial - and not validated.get("year_of_birth") - and not validated.get("date_of_birth") + if not self.partial and not ( + validated.get("year_of_birth") or validated.get("date_of_birth") ): raise serializers.ValidationError( { diff --git a/care/facility/models/patient_icmr.py b/care/facility/models/patient_icmr.py index 9f78befce0..ed6968803b 100644 --- a/care/facility/models/patient_icmr.py +++ b/care/facility/models/patient_icmr.py @@ -1,6 +1,5 @@ import datetime -from dateutil.relativedelta import relativedelta from django.utils import timezone from care.facility.models import ( @@ -49,14 +48,14 @@ class Meta: def get_age_delta(self): start = self.date_of_birth or timezone.datetime(self.year_of_birth, 1, 1).date() end = (self.death_datetime or timezone.now()).date() - return relativedelta(end - start) + return end - start @property - def age_years(self): - return self.get_age_delta().years + def age_years(self) -> int: + return self.get_age_delta().year @property - def age_months(self): + def age_months(self) -> int: return self.get_age_delta().months @property From b2390de2db85ca078aac56b54d324cc041773fa8 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Wed, 13 Mar 2024 16:23:30 +0530 Subject: [PATCH 09/19] revert unintended changes --- care/facility/models/patient_icmr.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/care/facility/models/patient_icmr.py b/care/facility/models/patient_icmr.py index ed6968803b..677b278322 100644 --- a/care/facility/models/patient_icmr.py +++ b/care/facility/models/patient_icmr.py @@ -1,5 +1,6 @@ import datetime +from dateutil.relativedelta import relativedelta from django.utils import timezone from care.facility.models import ( @@ -48,7 +49,7 @@ class Meta: def get_age_delta(self): start = self.date_of_birth or timezone.datetime(self.year_of_birth, 1, 1).date() end = (self.death_datetime or timezone.now()).date() - return end - start + return relativedelta(end, start) @property def age_years(self) -> int: From ced7877168f0a2f059bab709bdf9936fcdb95f92 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Thu, 14 Mar 2024 21:47:02 +0530 Subject: [PATCH 10/19] skip serializing age --- care/facility/api/serializers/patient.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/care/facility/api/serializers/patient.py b/care/facility/api/serializers/patient.py index 55f1e68a45..5ba675a734 100644 --- a/care/facility/api/serializers/patient.py +++ b/care/facility/api/serializers/patient.py @@ -115,9 +115,6 @@ def get_approved_claim_amount(self, patient): ) return claim.total_claim_amount if claim is not None else None - age = serializers.IntegerField(read_only=True) - age_days = serializers.IntegerField(read_only=True) - class Meta: model = PatientRegistration exclude = ( From 4c72575cc7845deaa6e475737b8f99c3267d1486 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Thu, 14 Mar 2024 22:11:48 +0530 Subject: [PATCH 11/19] rebase migrations --- ...istration_age_and_add_patientregistration_death_datetime.py} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename care/facility/migrations/{0420_remove_patientregistration_age_and_add_patientregistration_death_datetime.py => 0421_remove_patientregistration_age_and_add_patientregistration_death_datetime.py} (96%) diff --git a/care/facility/migrations/0420_remove_patientregistration_age_and_add_patientregistration_death_datetime.py b/care/facility/migrations/0421_remove_patientregistration_age_and_add_patientregistration_death_datetime.py similarity index 96% rename from care/facility/migrations/0420_remove_patientregistration_age_and_add_patientregistration_death_datetime.py rename to care/facility/migrations/0421_remove_patientregistration_age_and_add_patientregistration_death_datetime.py index 6099d27306..0d911801ce 100644 --- a/care/facility/migrations/0420_remove_patientregistration_age_and_add_patientregistration_death_datetime.py +++ b/care/facility/migrations/0421_remove_patientregistration_age_and_add_patientregistration_death_datetime.py @@ -6,7 +6,7 @@ class Migration(migrations.Migration): dependencies = [ - ("facility", "0419_alter_patientconsultation_patient_no"), + ("facility", "0420_migrate_shifting_facility_type"), ] def populate_patientregistration_death_datetime(apps, schema_editor): From 24c813e0dcc90036610bc2d95f30642e56c99b81 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Mon, 18 Mar 2024 18:23:47 +0530 Subject: [PATCH 12/19] rebase migrations --- ...istration_age_and_add_patientregistration_death_datetime.py} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename care/facility/migrations/{0421_remove_patientregistration_age_and_add_patientregistration_death_datetime.py => 0422_remove_patientregistration_age_and_add_patientregistration_death_datetime.py} (97%) diff --git a/care/facility/migrations/0421_remove_patientregistration_age_and_add_patientregistration_death_datetime.py b/care/facility/migrations/0422_remove_patientregistration_age_and_add_patientregistration_death_datetime.py similarity index 97% rename from care/facility/migrations/0421_remove_patientregistration_age_and_add_patientregistration_death_datetime.py rename to care/facility/migrations/0422_remove_patientregistration_age_and_add_patientregistration_death_datetime.py index 0d911801ce..026d0cd939 100644 --- a/care/facility/migrations/0421_remove_patientregistration_age_and_add_patientregistration_death_datetime.py +++ b/care/facility/migrations/0422_remove_patientregistration_age_and_add_patientregistration_death_datetime.py @@ -6,7 +6,7 @@ class Migration(migrations.Migration): dependencies = [ - ("facility", "0420_migrate_shifting_facility_type"), + ("facility", "0421_merge_20240318_1434"), ] def populate_patientregistration_death_datetime(apps, schema_editor): From 9964b853e24e30ff332a8c38128cd484510f8c6f Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Mon, 18 Mar 2024 18:30:08 +0530 Subject: [PATCH 13/19] drop age from dummy data --- data/dummy/facility.json | 38 -------------------------------------- 1 file changed, 38 deletions(-) diff --git a/data/dummy/facility.json b/data/dummy/facility.json index 16e4c2fab2..cfcf5cd2ae 100644 --- a/data/dummy/facility.json +++ b/data/dummy/facility.json @@ -3807,7 +3807,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient", - "age": 18, "gender": 1, "phone_number": "+919987455444", "emergency_phone_number": "+919898797775", @@ -3888,7 +3887,6 @@ "nearest_facility": null, "meta_info": null, "name": "Test E2E User", - "age": 22, "gender": 1, "phone_number": "+919765259927", "emergency_phone_number": "+919228973557", @@ -3969,7 +3967,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 1", - "age": 22, "gender": 1, "phone_number": "+919192495353", "emergency_phone_number": "+919460491040", @@ -4050,7 +4047,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 2", - "age": 22, "gender": 1, "phone_number": "+919112608904", "emergency_phone_number": "+919110616234", @@ -4131,7 +4127,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 3", - "age": 22, "gender": 1, "phone_number": "+919640229897", "emergency_phone_number": "+919135436547", @@ -4212,7 +4207,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 4", - "age": 22, "gender": 1, "phone_number": "+919762277015", "emergency_phone_number": "+919342634016", @@ -4293,7 +4287,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 5", - "age": 22, "gender": 1, "phone_number": "+919303212282", "emergency_phone_number": "+919229738916", @@ -4374,7 +4367,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 6", - "age": 22, "gender": 1, "phone_number": "+919740701377", "emergency_phone_number": "+919321666516", @@ -4455,7 +4447,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 7", - "age": 22, "gender": 1, "phone_number": "+919148299129", "emergency_phone_number": "+919267280161", @@ -4536,7 +4527,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 8", - "age": 22, "gender": 1, "phone_number": "+919490490290", "emergency_phone_number": "+919828674710", @@ -4617,7 +4607,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 9", - "age": 22, "gender": 1, "phone_number": "+919983927490", "emergency_phone_number": "+919781111140", @@ -4698,7 +4687,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 10", - "age": 22, "gender": 1, "phone_number": "+919849511866", "emergency_phone_number": "+919622326248", @@ -4779,7 +4767,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 11", - "age": 22, "gender": 1, "phone_number": "+919343556704", "emergency_phone_number": "+919967920474", @@ -4860,7 +4847,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 12", - "age": 22, "gender": 1, "phone_number": "+919320374643", "emergency_phone_number": "+919493558024", @@ -4941,7 +4927,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 13", - "age": 22, "gender": 1, "phone_number": "+919292990239", "emergency_phone_number": "+919992258784", @@ -5022,7 +5007,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 14", - "age": 22, "gender": 1, "phone_number": "+919650206292", "emergency_phone_number": "+919596454242", @@ -5103,7 +5087,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 15", - "age": 22, "gender": 1, "phone_number": "+919266236581", "emergency_phone_number": "+919835286558", @@ -5184,7 +5167,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 16", - "age": 22, "gender": 1, "phone_number": "+919243083817", "emergency_phone_number": "+919924971004", @@ -5442,7 +5424,6 @@ "deleted": false, "srf_id": "00/EKM/0000", "name": "Patient 1", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5473,7 +5454,6 @@ "deleted": false, "srf_id": "00/EKM/0001", "name": "Patient 2", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5504,7 +5484,6 @@ "deleted": false, "srf_id": "00/EKM/0002", "name": "Patient 3", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5535,7 +5514,6 @@ "deleted": false, "srf_id": "00/EKM/0003", "name": "Patient 4", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5566,7 +5544,6 @@ "deleted": false, "srf_id": "00/EKM/0004", "name": "Patient 5", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5597,7 +5574,6 @@ "deleted": false, "srf_id": "00/EKM/0005", "name": "Patient 6", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5628,7 +5604,6 @@ "deleted": false, "srf_id": "00/EKM/0006", "name": "Patient 7", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5659,7 +5634,6 @@ "deleted": false, "srf_id": "00/EKM/0007", "name": "Patient 8", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5690,7 +5664,6 @@ "deleted": false, "srf_id": "00/EKM/0008", "name": "Patient 9", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5721,7 +5694,6 @@ "deleted": false, "srf_id": "00/EKM/0009", "name": "Patient 10", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5752,7 +5724,6 @@ "deleted": false, "srf_id": "00/EKM/0010", "name": "Patient 11", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5783,7 +5754,6 @@ "deleted": false, "srf_id": "00/EKM/0011", "name": "Patient 12", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5814,7 +5784,6 @@ "deleted": false, "srf_id": "00/EKM/0012", "name": "Patient 13", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5845,7 +5814,6 @@ "deleted": false, "srf_id": "00/EKM/0013", "name": "Patient 14", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5876,7 +5844,6 @@ "deleted": false, "srf_id": "00/EKM/0014", "name": "Patient 15", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5907,7 +5874,6 @@ "deleted": false, "srf_id": "00/EKM/0015", "name": "Patient 16", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5938,7 +5904,6 @@ "deleted": false, "srf_id": "00/EKM/0016", "name": "Patient 17", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5969,7 +5934,6 @@ "deleted": false, "srf_id": "00/EKM/0017", "name": "Patient 18", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -6000,7 +5964,6 @@ "deleted": false, "srf_id": "00/EKM/0018", "name": "Patient 19", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -6031,7 +5994,6 @@ "deleted": false, "srf_id": "00/EKM/0019", "name": "Patient 20", - "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", From 039188092b3811f8e5884206c309fc619d7e753f Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Mon, 18 Mar 2024 18:40:12 +0530 Subject: [PATCH 14/19] Revert "drop age from dummy data" This reverts commit 9964b853e24e30ff332a8c38128cd484510f8c6f. --- data/dummy/facility.json | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/data/dummy/facility.json b/data/dummy/facility.json index cfcf5cd2ae..16e4c2fab2 100644 --- a/data/dummy/facility.json +++ b/data/dummy/facility.json @@ -3807,6 +3807,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient", + "age": 18, "gender": 1, "phone_number": "+919987455444", "emergency_phone_number": "+919898797775", @@ -3887,6 +3888,7 @@ "nearest_facility": null, "meta_info": null, "name": "Test E2E User", + "age": 22, "gender": 1, "phone_number": "+919765259927", "emergency_phone_number": "+919228973557", @@ -3967,6 +3969,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 1", + "age": 22, "gender": 1, "phone_number": "+919192495353", "emergency_phone_number": "+919460491040", @@ -4047,6 +4050,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 2", + "age": 22, "gender": 1, "phone_number": "+919112608904", "emergency_phone_number": "+919110616234", @@ -4127,6 +4131,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 3", + "age": 22, "gender": 1, "phone_number": "+919640229897", "emergency_phone_number": "+919135436547", @@ -4207,6 +4212,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 4", + "age": 22, "gender": 1, "phone_number": "+919762277015", "emergency_phone_number": "+919342634016", @@ -4287,6 +4293,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 5", + "age": 22, "gender": 1, "phone_number": "+919303212282", "emergency_phone_number": "+919229738916", @@ -4367,6 +4374,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 6", + "age": 22, "gender": 1, "phone_number": "+919740701377", "emergency_phone_number": "+919321666516", @@ -4447,6 +4455,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 7", + "age": 22, "gender": 1, "phone_number": "+919148299129", "emergency_phone_number": "+919267280161", @@ -4527,6 +4536,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 8", + "age": 22, "gender": 1, "phone_number": "+919490490290", "emergency_phone_number": "+919828674710", @@ -4607,6 +4617,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 9", + "age": 22, "gender": 1, "phone_number": "+919983927490", "emergency_phone_number": "+919781111140", @@ -4687,6 +4698,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 10", + "age": 22, "gender": 1, "phone_number": "+919849511866", "emergency_phone_number": "+919622326248", @@ -4767,6 +4779,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 11", + "age": 22, "gender": 1, "phone_number": "+919343556704", "emergency_phone_number": "+919967920474", @@ -4847,6 +4860,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 12", + "age": 22, "gender": 1, "phone_number": "+919320374643", "emergency_phone_number": "+919493558024", @@ -4927,6 +4941,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 13", + "age": 22, "gender": 1, "phone_number": "+919292990239", "emergency_phone_number": "+919992258784", @@ -5007,6 +5022,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 14", + "age": 22, "gender": 1, "phone_number": "+919650206292", "emergency_phone_number": "+919596454242", @@ -5087,6 +5103,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 15", + "age": 22, "gender": 1, "phone_number": "+919266236581", "emergency_phone_number": "+919835286558", @@ -5167,6 +5184,7 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 16", + "age": 22, "gender": 1, "phone_number": "+919243083817", "emergency_phone_number": "+919924971004", @@ -5424,6 +5442,7 @@ "deleted": false, "srf_id": "00/EKM/0000", "name": "Patient 1", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5454,6 +5473,7 @@ "deleted": false, "srf_id": "00/EKM/0001", "name": "Patient 2", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5484,6 +5504,7 @@ "deleted": false, "srf_id": "00/EKM/0002", "name": "Patient 3", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5514,6 +5535,7 @@ "deleted": false, "srf_id": "00/EKM/0003", "name": "Patient 4", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5544,6 +5566,7 @@ "deleted": false, "srf_id": "00/EKM/0004", "name": "Patient 5", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5574,6 +5597,7 @@ "deleted": false, "srf_id": "00/EKM/0005", "name": "Patient 6", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5604,6 +5628,7 @@ "deleted": false, "srf_id": "00/EKM/0006", "name": "Patient 7", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5634,6 +5659,7 @@ "deleted": false, "srf_id": "00/EKM/0007", "name": "Patient 8", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5664,6 +5690,7 @@ "deleted": false, "srf_id": "00/EKM/0008", "name": "Patient 9", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5694,6 +5721,7 @@ "deleted": false, "srf_id": "00/EKM/0009", "name": "Patient 10", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5724,6 +5752,7 @@ "deleted": false, "srf_id": "00/EKM/0010", "name": "Patient 11", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5754,6 +5783,7 @@ "deleted": false, "srf_id": "00/EKM/0011", "name": "Patient 12", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5784,6 +5814,7 @@ "deleted": false, "srf_id": "00/EKM/0012", "name": "Patient 13", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5814,6 +5845,7 @@ "deleted": false, "srf_id": "00/EKM/0013", "name": "Patient 14", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5844,6 +5876,7 @@ "deleted": false, "srf_id": "00/EKM/0014", "name": "Patient 15", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5874,6 +5907,7 @@ "deleted": false, "srf_id": "00/EKM/0015", "name": "Patient 16", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5904,6 +5938,7 @@ "deleted": false, "srf_id": "00/EKM/0016", "name": "Patient 17", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5934,6 +5969,7 @@ "deleted": false, "srf_id": "00/EKM/0017", "name": "Patient 18", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5964,6 +6000,7 @@ "deleted": false, "srf_id": "00/EKM/0018", "name": "Patient 19", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", @@ -5994,6 +6031,7 @@ "deleted": false, "srf_id": "00/EKM/0019", "name": "Patient 20", + "age": 24, "age_in": "years", "gender": "m", "address": "CSN HQ\nKochi, Kerala", From 2d4b2eaf2e7c9dd9683b7bd795198fe55a330a1a Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Mon, 18 Mar 2024 19:00:14 +0530 Subject: [PATCH 15/19] drop patient registration's age from dummy data --- data/dummy/facility.json | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/data/dummy/facility.json b/data/dummy/facility.json index 16e4c2fab2..1cc3b31575 100644 --- a/data/dummy/facility.json +++ b/data/dummy/facility.json @@ -3807,7 +3807,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient", - "age": 18, "gender": 1, "phone_number": "+919987455444", "emergency_phone_number": "+919898797775", @@ -3888,7 +3887,6 @@ "nearest_facility": null, "meta_info": null, "name": "Test E2E User", - "age": 22, "gender": 1, "phone_number": "+919765259927", "emergency_phone_number": "+919228973557", @@ -3969,7 +3967,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 1", - "age": 22, "gender": 1, "phone_number": "+919192495353", "emergency_phone_number": "+919460491040", @@ -4050,7 +4047,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 2", - "age": 22, "gender": 1, "phone_number": "+919112608904", "emergency_phone_number": "+919110616234", @@ -4131,7 +4127,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 3", - "age": 22, "gender": 1, "phone_number": "+919640229897", "emergency_phone_number": "+919135436547", @@ -4212,7 +4207,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 4", - "age": 22, "gender": 1, "phone_number": "+919762277015", "emergency_phone_number": "+919342634016", @@ -4293,7 +4287,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 5", - "age": 22, "gender": 1, "phone_number": "+919303212282", "emergency_phone_number": "+919229738916", @@ -4374,7 +4367,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 6", - "age": 22, "gender": 1, "phone_number": "+919740701377", "emergency_phone_number": "+919321666516", @@ -4455,7 +4447,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 7", - "age": 22, "gender": 1, "phone_number": "+919148299129", "emergency_phone_number": "+919267280161", @@ -4536,7 +4527,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 8", - "age": 22, "gender": 1, "phone_number": "+919490490290", "emergency_phone_number": "+919828674710", @@ -4617,7 +4607,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 9", - "age": 22, "gender": 1, "phone_number": "+919983927490", "emergency_phone_number": "+919781111140", @@ -4698,7 +4687,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 10", - "age": 22, "gender": 1, "phone_number": "+919849511866", "emergency_phone_number": "+919622326248", @@ -4779,7 +4767,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 11", - "age": 22, "gender": 1, "phone_number": "+919343556704", "emergency_phone_number": "+919967920474", @@ -4860,7 +4847,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 12", - "age": 22, "gender": 1, "phone_number": "+919320374643", "emergency_phone_number": "+919493558024", @@ -4941,7 +4927,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 13", - "age": 22, "gender": 1, "phone_number": "+919292990239", "emergency_phone_number": "+919992258784", @@ -5022,7 +5007,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 14", - "age": 22, "gender": 1, "phone_number": "+919650206292", "emergency_phone_number": "+919596454242", @@ -5103,7 +5087,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 15", - "age": 22, "gender": 1, "phone_number": "+919266236581", "emergency_phone_number": "+919835286558", @@ -5184,7 +5167,6 @@ "nearest_facility": null, "meta_info": null, "name": "Dummy Patient 16", - "age": 22, "gender": 1, "phone_number": "+919243083817", "emergency_phone_number": "+919924971004", From acca03bb8b88143604ec2e4161070e1cd816712a Mon Sep 17 00:00:00 2001 From: Rithvik Nishad Date: Tue, 19 Mar 2024 16:19:26 +0530 Subject: [PATCH 16/19] select only `last_consultation` in custom migration Co-authored-by: Aakash Singh --- ...gistration_age_and_add_patientregistration_death_datetime.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/care/facility/migrations/0422_remove_patientregistration_age_and_add_patientregistration_death_datetime.py b/care/facility/migrations/0422_remove_patientregistration_age_and_add_patientregistration_death_datetime.py index 026d0cd939..7ff83cb965 100644 --- a/care/facility/migrations/0422_remove_patientregistration_age_and_add_patientregistration_death_datetime.py +++ b/care/facility/migrations/0422_remove_patientregistration_age_and_add_patientregistration_death_datetime.py @@ -12,7 +12,7 @@ class Migration(migrations.Migration): def populate_patientregistration_death_datetime(apps, schema_editor): PatientRegistration = apps.get_model("facility", "PatientRegistration") - patients = PatientRegistration.objects.filter( + patients = PatientRegistration.objects.only("last_consultation").filter( last_consultation__death_datetime__isnull=False ).annotate(new_death_datetime=models.F("last_consultation__death_datetime")) From 0b258ffde9e1e2b7db6d936bb915200d10d992b7 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Tue, 19 Mar 2024 16:31:39 +0530 Subject: [PATCH 17/19] format code --- ...tion_age_and_add_patientregistration_death_datetime.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/care/facility/migrations/0422_remove_patientregistration_age_and_add_patientregistration_death_datetime.py b/care/facility/migrations/0422_remove_patientregistration_age_and_add_patientregistration_death_datetime.py index 7ff83cb965..919fab421f 100644 --- a/care/facility/migrations/0422_remove_patientregistration_age_and_add_patientregistration_death_datetime.py +++ b/care/facility/migrations/0422_remove_patientregistration_age_and_add_patientregistration_death_datetime.py @@ -12,9 +12,11 @@ class Migration(migrations.Migration): def populate_patientregistration_death_datetime(apps, schema_editor): PatientRegistration = apps.get_model("facility", "PatientRegistration") - patients = PatientRegistration.objects.only("last_consultation").filter( - last_consultation__death_datetime__isnull=False - ).annotate(new_death_datetime=models.F("last_consultation__death_datetime")) + patients = ( + PatientRegistration.objects.only("last_consultation") + .filter(last_consultation__death_datetime__isnull=False) + .annotate(new_death_datetime=models.F("last_consultation__death_datetime")) + ) for patient in patients: patient.death_datetime = patient.new_death_datetime From a0f5fe141306d896f431fc5a550127934ed9c0b5 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Mon, 25 Mar 2024 18:05:55 +0530 Subject: [PATCH 18/19] rebase migrations --- ...istration_age_and_add_patientregistration_death_datetime.py} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename care/facility/migrations/{0422_remove_patientregistration_age_and_add_patientregistration_death_datetime.py => 0423_remove_patientregistration_age_and_add_patientregistration_death_datetime.py} (97%) diff --git a/care/facility/migrations/0422_remove_patientregistration_age_and_add_patientregistration_death_datetime.py b/care/facility/migrations/0423_remove_patientregistration_age_and_add_patientregistration_death_datetime.py similarity index 97% rename from care/facility/migrations/0422_remove_patientregistration_age_and_add_patientregistration_death_datetime.py rename to care/facility/migrations/0423_remove_patientregistration_age_and_add_patientregistration_death_datetime.py index 919fab421f..04ab72227c 100644 --- a/care/facility/migrations/0422_remove_patientregistration_age_and_add_patientregistration_death_datetime.py +++ b/care/facility/migrations/0423_remove_patientregistration_age_and_add_patientregistration_death_datetime.py @@ -6,7 +6,7 @@ class Migration(migrations.Migration): dependencies = [ - ("facility", "0421_merge_20240318_1434"), + ("facility", "0422_merge_20240325_1411"), ] def populate_patientregistration_death_datetime(apps, schema_editor): From 5bd404a7e6a6c92378b8a1910625db6d5283b551 Mon Sep 17 00:00:00 2001 From: rithviknishad Date: Sat, 30 Mar 2024 16:24:05 +0530 Subject: [PATCH 19/19] rebase migrations --- ...istration_age_and_add_patientregistration_death_datetime.py} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename care/facility/migrations/{0423_remove_patientregistration_age_and_add_patientregistration_death_datetime.py => 0424_remove_patientregistration_age_and_add_patientregistration_death_datetime.py} (96%) diff --git a/care/facility/migrations/0423_remove_patientregistration_age_and_add_patientregistration_death_datetime.py b/care/facility/migrations/0424_remove_patientregistration_age_and_add_patientregistration_death_datetime.py similarity index 96% rename from care/facility/migrations/0423_remove_patientregistration_age_and_add_patientregistration_death_datetime.py rename to care/facility/migrations/0424_remove_patientregistration_age_and_add_patientregistration_death_datetime.py index 04ab72227c..e051559ba8 100644 --- a/care/facility/migrations/0423_remove_patientregistration_age_and_add_patientregistration_death_datetime.py +++ b/care/facility/migrations/0424_remove_patientregistration_age_and_add_patientregistration_death_datetime.py @@ -6,7 +6,7 @@ class Migration(migrations.Migration): dependencies = [ - ("facility", "0422_merge_20240325_1411"), + ("facility", "0423_patientconsultation_consent_records_and_more"), ] def populate_patientregistration_death_datetime(apps, schema_editor):