Skip to content

Commit

Permalink
use signals to update patient and bed count of facilities
Browse files Browse the repository at this point in the history
  • Loading branch information
sainak committed Jun 12, 2023
1 parent 0f67f1e commit 0759354
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 19 deletions.
24 changes: 10 additions & 14 deletions care/facility/api/serializers/facility.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
from rest_framework import serializers

from care.facility.models import FACILITY_TYPES, Facility, FacilityLocalGovtBody
from care.facility.models.bed import Bed
from care.facility.models.facility import FEATURE_CHOICES
from care.facility.models.patient import PatientRegistration
from care.users.api.serializers.lsg import (
DistrictSerializer,
LocalBodySerializer,
Expand Down Expand Up @@ -49,16 +47,6 @@ class FacilityBasicInfoSerializer(serializers.ModelSerializer):
facility_type = serializers.SerializerMethodField()
read_cover_image_url = serializers.CharField(read_only=True)
features = serializers.MultipleChoiceField(choices=FEATURE_CHOICES)
patient_count = serializers.SerializerMethodField()
bed_count = serializers.SerializerMethodField()

def get_bed_count(self, facility):
return Bed.objects.filter(facility=facility).count()

def get_patient_count(self, facility):
return PatientRegistration.objects.filter(
facility=facility, is_active=True
).count()

def get_facility_type(self, facility):
return {
Expand All @@ -84,6 +72,10 @@ class Meta:
"patient_count",
"bed_count",
)
read_only_fields = (
"patient_count",
"bed_count",
)


class FacilitySerializer(FacilityBasicInfoSerializer):
Expand All @@ -97,7 +89,6 @@ class FacilitySerializer(FacilityBasicInfoSerializer):
read_cover_image_url = serializers.URLField(read_only=True)
# location = PointField(required=False)
features = serializers.MultipleChoiceField(choices=FEATURE_CHOICES)
bed_count = serializers.SerializerMethodField()

class Meta:
model = Facility
Expand Down Expand Up @@ -135,7 +126,12 @@ class Meta:
"patient_count",
"bed_count",
]
read_only_fields = ("modified_date", "created_date")
read_only_fields = (
"modified_date",
"created_date",
"patient_count",
"bed_count",
)

def validate_middleware_address(self, value):
value = value.strip()
Expand Down
5 changes: 1 addition & 4 deletions care/facility/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,4 @@ class FacilityConfig(AppConfig):
verbose_name = _("Facility Management")

def ready(self):
try:
import care.facility.signals # noqa F401
except ImportError:
pass
import care.facility.signals # noqa F401
47 changes: 47 additions & 0 deletions care/facility/migrations/0361_set_patient_and_bed_count.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Generated by Django 2.2.11 on 2023-06-08 16:14

from django.db import migrations, models


def set_patient_and_bed_count(apps, schema_editor):
Facility = apps.get_model("facility", "Facility")

facilities = Facility.objects.filter(deleted=False, is_active=True).annotate(
annotated_patient_count=models.Count(
"patientregistration",
filter=models.Q(
patientregistration__is_active=True, patientregistration__deleted=False
),
),
annotated_bed_count=models.Count("bed", filter=models.Q(bed__deleted=False)),
)

updated_facilities = []
for facility in facilities:
facility.patient_count = facility.annotated_patient_count
facility.bed_count = facility.annotated_bed_count
updated_facilities.append(facility)

Facility.objects.bulk_update(updated_facilities, ["patient_count", "bed_count"])


class Migration(migrations.Migration):
dependencies = [
("facility", "0360_auto_20230608_1750"),
]

operations = [
migrations.AddField(
model_name="facility",
name="bed_count",
field=models.IntegerField(default=0),
),
migrations.AddField(
model_name="facility",
name="patient_count",
field=models.IntegerField(default=0),
),
migrations.RunPython(
set_patient_and_bed_count, reverse_code=migrations.RunPython.noop
),
]
3 changes: 3 additions & 0 deletions care/facility/models/facility.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ class Facility(FacilityBaseModel, FacilityPermissionMixin):
through_fields=("facility", "user"),
)

bed_count = models.IntegerField(default=0)
patient_count = models.IntegerField(default=0)

cover_image_url = models.CharField(
blank=True, null=True, default=None, max_length=500
)
Expand Down
1 change: 1 addition & 0 deletions care/facility/signals/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .facility_related_count import * # noqa
59 changes: 59 additions & 0 deletions care/facility/signals/facility_related_count.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
from django.db.models import Q
from django.db.models.signals import post_delete, post_save
from django.dispatch import receiver

from care.facility.models.bed import Bed
from care.facility.models.facility import Facility
from care.facility.models.patient import PatientRegistration
from care.utils.models.aggregators import update_related_count_for_single_object


def update_patient_count(facility: Facility):
update_related_count_for_single_object(
facility,
{
"patient_count": (
"patientregistration_set",
Q(
is_active=True,
deleted=False,
),
)
},
)


def update_bed_count(facility: Facility):
update_related_count_for_single_object(
facility,
{
"bed_count": ("bed_set", Q(is_active=True, deleted=False)),
},
)


@receiver(post_save, sender=PatientRegistration)
def patient_post_save(sender, instance, created, raw, using, update_fields, **kwargs):
if raw:
return
if (
created or (update_fields is not None and "is_active" in update_fields)
) and instance.facility is not None:
update_patient_count(instance.facility)


@receiver(post_delete, sender=PatientRegistration)
def patient_post_delete(sender, instance, **kwargs):
if instance.facility is not None:
update_patient_count(instance.facility)


@receiver(post_save, sender=Bed)
def bed_post_save(sender, instance, created, raw, using, update_fields, **kwargs):
if created:
update_bed_count(instance.facility)


@receiver(post_delete, sender=Bed)
def bed_post_delete(sender, instance, **kwargs):
update_bed_count(instance.facility)
2 changes: 1 addition & 1 deletion care/utils/tests/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ def setUpClass(cls) -> None:
cls.user = cls.create_user(cls.district)
cls.super_user = cls.create_super_user(district=cls.district)
cls.facility = cls.create_facility(cls.district)
cls.patient = cls.create_patient()
cls.patient = cls.create_patient(facility=cls.facility)

cls.user_data = cls.get_user_data(cls.district, cls.user_type)
cls.facility_data = cls.get_facility_data(cls.district)
Expand Down

0 comments on commit 0759354

Please sign in to comment.