diff --git a/care/facility/migrations/0133_auto_20200710_2355.py b/care/facility/migrations/0133_auto_20200710_2355.py new file mode 100644 index 0000000000..1ebf2b299b --- /dev/null +++ b/care/facility/migrations/0133_auto_20200710_2355.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.11 on 2020-07-10 18:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('facility', '0132_patientsample_testing_facility'), + ] + + operations = [ + migrations.AlterField( + model_name='facilityrelatedsummary', + name='s_type', + field=models.CharField(choices=[('FacilityCapacity', 'FacilityCapacity'), ('PatientSummary', 'PatientSummary'), ('TestSummary', 'TestSummary')], max_length=100), + ), + ] diff --git a/care/facility/models/summary.py b/care/facility/models/summary.py index be99afdc54..1d63fc0ac1 100644 --- a/care/facility/models/summary.py +++ b/care/facility/models/summary.py @@ -10,8 +10,10 @@ SUMMARY_CHOICES = ( ("FacilityCapacity", "FacilityCapacity"), ("PatientSummary", "PatientSummary"), + ("TestSummary", "TestSummary") ) + class FacilityRelatedSummary(models.Model): id = models.UUIDField(primary_key=True, default=uuid4, unique=True, db_index=True) created_date = models.DateTimeField(auto_now_add=True, null=True, blank=True) diff --git a/care/facility/summarisation/tests_summary.py b/care/facility/summarisation/tests_summary.py new file mode 100644 index 0000000000..2394034d14 --- /dev/null +++ b/care/facility/summarisation/tests_summary.py @@ -0,0 +1,104 @@ +from django.core.exceptions import ObjectDoesNotExist +from django.conf import settings +from django.utils import timezone + +from celery.decorators import periodic_task +from celery.schedules import crontab + +from rest_framework.generics import get_object_or_404 +from rest_framework.mixins import ListModelMixin, RetrieveModelMixin +from rest_framework.permissions import IsAuthenticated +from rest_framework import serializers +from rest_framework.viewsets import GenericViewSet + +from care.facility.models import FacilityRelatedSummary, Facility, PatientSample + + +class TestsSummarySerializer(serializers.ModelSerializer): + class Meta: + model = FacilityRelatedSummary + exclude = ("id", "s_type", "facility") + + +class TestsSummaryViewSet( + RetrieveModelMixin, ListModelMixin, GenericViewSet + ): + lookup_field = "external_id" + queryset = FacilityRelatedSummary.objects.filter(s_type="TestSummary").order_by("-created_date") + permission_classes = (IsAuthenticated,) + serializer_class = TestsSummarySerializer + + def get_queryset(self): + user = self.request.user + queryset = self.queryset + if user.is_superuser: + return queryset + elif self.request.user.user_type >= settings.AUTH_USER_MODEL.TYPE_VALUE_MAP["DistrictAdmin"]: + return queryset.filter(facility__district=user.district) + elif self.request.user.user_type >= settings.AUTH_USER_MODEL.TYPE_VALUE_MAP["StateLabAdmin"]: + return queryset.filter(facility__state=user.state) + return queryset.filter(facility__users__id__exact=user.id) + + def get_object(self): + return get_object_or_404(self.get_queryset(), facility__external_id=self.kwargs.get("external_id")) + + +def tests_summary(): + facilities = Facility.objects.all() + for facility in facilities: + facility_total_patients_count = facility.consultations.all().distinct('patient_id').count() + facility_patients_samples = PatientSample.objects.filter(consultation__facility_id=facility.id) + total_tests_count = facility_patients_samples.count() + results_positive_count = facility_patients_samples.filter( + result=PatientSample.SAMPLE_TEST_RESULT_MAP['POSITIVE'] + ).count() + results_awaited_count = facility_patients_samples.filter( + result=PatientSample.SAMPLE_TEST_RESULT_MAP['AWAITING'] + ).count() + results_negative_count = facility_patients_samples.filter( + result=PatientSample.SAMPLE_TEST_RESULT_MAP['NEGATIVE'] + ).count() + test_discarded_count = facility_patients_samples.filter( + result=PatientSample.SAMPLE_TEST_RESULT_MAP['INVALID'] + ).count() + facility_tests_summarised_data = { + 'facility_name': facility.name, + 'district': facility.district.name, + 'total_patients': facility_total_patients_count, + 'total_tests': total_tests_count, + 'result_positive': results_positive_count, + 'result_awaited': results_awaited_count, + 'result_negative': results_negative_count, + 'test_discarded': test_discarded_count, + } + + try: + facility_test_summary = FacilityRelatedSummary.objects.get( + s_type="TestSummary", + created_date__startswith=timezone.now().date(), + facility=facility + ) + facility_test_summary.created_date = timezone.now() + facility_test_summary.data.pop('modified_date') + if not facility_test_summary.data == facility_tests_summarised_data: + facility_test_summary.data = facility_tests_summarised_data + latest_modification_date = timezone.now() + facility_test_summary.data.update( + {'modified_date': latest_modification_date.strftime('%d-%m-%Y %H:%M')} + ) + facility_test_summary.save() + except ObjectDoesNotExist: + modified_date = timezone.now() + facility_tests_summarised_data.update( + {'modified_date': modified_date.strftime('%d-%m-%Y %H:%M')} + ) + FacilityRelatedSummary.objects.create( + s_type="TestSummary", + facility=facility, + data=facility_tests_summarised_data + ) + + +@periodic_task(run_every=crontab(hour=23, minute=59)) +def run_midnight(): + tests_summary() diff --git a/config/api_router.py b/config/api_router.py index 3f917aa7c5..5ca8779f07 100644 --- a/config/api_router.py +++ b/config/api_router.py @@ -23,6 +23,7 @@ from care.facility.summarisation.facility_capacity import FacilityCapacitySummaryViewSet from care.facility.summarisation.patient_summary import PatientSummaryViewSet +from care.facility.summarisation.tests_summary import TestsSummaryViewSet if settings.DEBUG: router = DefaultRouter() @@ -54,6 +55,8 @@ # Summarisation router.register("facility_summary", FacilityCapacitySummaryViewSet, basename="summary-facility") router.register("patient_summary", PatientSummaryViewSet, basename="summary-patient") +router.register("tests_summary", TestsSummaryViewSet, basename="summary-tests") + router.register("items", FacilityInventoryItemViewSet)