Skip to content

Commit

Permalink
Add query for Assessment registry Count
Browse files Browse the repository at this point in the history
- total assessment count
- total stakeholder count
- collection technique count
- multisector and single sector assessment
  • Loading branch information
sudan45 committed Aug 10, 2023
1 parent d19221d commit f696909
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 24 deletions.
138 changes: 114 additions & 24 deletions apps/assessment_registry/dashboard_schema.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
from dataclasses import dataclass
import itertools
import graphene
from .models import AssessmentRegistry, MethodologyAttribute
from .enums import (
AssessmentRegistryCoordinationTypeEnum,
AssessmentRegistryDataCollectionTechniqueTypeEnum,
)
from django.db.models import Count
from django.db import models
from deep.caches import CacheHelper
from collections import defaultdict


def get_global_filters(_filter: dict, date_field="created_at"):
return {
f"{date_field}__gte": _filter["date_from"],
f"{date_field}__lte": _filter["date_to"],
}


@dataclass
class AssessmentDashboardStat:
cache_key: str
assessment_registry_qs: models.QuerySet
methodology_attribute_qs: models.QuerySet


class AssessmentFilterInputType(graphene.InputObjectType):
date_from = graphene.Date(required=True)
date_to = graphene.Date(required=True)


class AssessmentCountType(graphene.ObjectType):
Expand All @@ -13,8 +37,7 @@ class AssessmentCountType(graphene.ObjectType):
count = graphene.Int()

def resolve_coordinated_joint_display(self, info):
return AssessmentRegistry.CoordinationType(
self.coordinated_joint).label
return AssessmentRegistry.CoordinationType(self.coordinated_joint).label


class StakeholderCountType(graphene.ObjectType):
Expand All @@ -36,18 +59,63 @@ def resolve_data_collection_technique_display(self, info):


class AssessmentDashboardStatisticsType(graphene.ObjectType):
total_assessment = graphene.Int(required=True)
total_stakeholder = graphene.Int(required=True)
total_collection_technique = graphene.Int(required=True)
assessment_count = graphene.List(AssessmentCountType)
stakeholder_count = graphene.List(StakeholderCountType)
collection_technique_count = graphene.List(CollectionTechniqueCountType)
model = AssessmentRegistry
total_multisector_assessment = graphene.Int(required=True)
total_singlesector_assessment = graphene.Int(required=True)

@staticmethod
def custom_resolver(info, _filter):
assessment_qs = AssessmentRegistry.objects.filter(
project=info.context.active_project,
**get_global_filters(_filter),
)
methodology_attribute_qs = MethodologyAttribute.objects.filter(
assessment_registry__project_id=info.context.active_project,
**get_global_filters(_filter),
)
cache_key = CacheHelper.generate_hash(_filter.__dict__)
return AssessmentDashboardStat(
cache_key=cache_key,
assessment_registry_qs=assessment_qs,
methodology_attribute_qs=methodology_attribute_qs,
)

@staticmethod
def resolve_total_assessment(root: AssessmentDashboardStat, info) -> int:
return root.assessment_registry_qs.count()

@staticmethod
def resolve_total_stakeholder(root: AssessmentDashboardStat, info) -> int:
qs = root.assessment_registry_qs.values_list(
"international_partners__title",
"donors__title",
"lead_organizations__title",
"national_partners__title",
"governments__title",
)
return len(set(list(itertools.chain(*qs))))

def resolve_assessment_count(self, info):
@staticmethod
def resolve_total_collection_technique(root: AssessmentDashboardStat, info) -> int:
return (
root.methodology_attribute_qs.values("data_collection_technique").annotate(
count=Count("data_collection_technique")
)
).count()

@staticmethod
def resolve_assessment_count(root: AssessmentDashboardStat, info):
assessment = (
self.model.objects.filter(project=info.context.active_project)
.values("coordinated_joint")
root.assessment_registry_qs.values("coordinated_joint")
.annotate(count=Count("coordinated_joint"))
.order_by("coordinated_joint")
)

return [
AssessmentCountType(
coordinated_joint=assessment["coordinated_joint"],
Expand All @@ -56,27 +124,35 @@ def resolve_assessment_count(self, info):
for assessment in assessment
]

def resolve_stakeholder_count(self, info):
stakeholder = (
self.model.objects.filter(project=info.context.active_project)
.values("lead_organizations", "lead_organizations__title")
.annotate(count=Count("lead_organizations"))
.order_by("lead_organizations")
)
@staticmethod
def resolve_stakeholder_count(root: AssessmentDashboardStat, info):
stakeholder_counts = defaultdict(int)

organization_type_fields = [
"lead_organizations__organization_type__title",
"international_partners__organization_type__title",
"donors__organization_type__title",
"national_partners__organization_type__title",
"governments__organization_type__title",
]

for field in organization_type_fields:
stakeholders = root.assessment_registry_qs.values(field)
for stakeholder in stakeholders:
if organization_type_title := stakeholder.get(field):
stakeholder_counts[organization_type_title] += 1
return [
StakeholderCountType(
stakeholder=stakeholder["lead_organizations__title"],
count=stakeholder["count"],
stakeholder=org_type_title,
count=count,
)
for stakeholder in stakeholder
for org_type_title, count in stakeholder_counts.items()
]

def resolve_collection_technique_count(self, info):
@staticmethod
def resolve_collection_technique_count(root: AssessmentDashboardStat, info):
data_collection_technique = (
MethodologyAttribute.objects.filter(
assessment_registry__project_id=info.context.active_project
)
.values("data_collection_technique")
root.methodology_attribute_qs.values("data_collection_technique")
.annotate(count=Count("data_collection_technique"))
.order_by("data_collection_technique")
)
Expand All @@ -88,11 +164,25 @@ def resolve_collection_technique_count(self, info):
for technique in data_collection_technique
]

@staticmethod
def resolve_total_multisector_assessment(
root: AssessmentDashboardStat, info
) -> int:
return sum(1 for a in root.assessment_registry_qs if len(a.sectors) > 1)

@staticmethod
def resolve_total_singlesector_assessment(
root: AssessmentDashboardStat, info
) -> int:
return sum(1 for a in root.assessment_registry_qs if len(a.sectors) < 1)


class Query:
assessment_dashboard_statistics = graphene.Field(
AssessmentDashboardStatisticsType)
AssessmentDashboardStatisticsType,
filter=AssessmentFilterInputType(),
)

@staticmethod
def resolve_assessment_dashboard_statistics(root, info, **kwargs):
return AssessmentDashboardStatisticsType
def resolve_assessment_dashboard_statistics(root, info, filter):
return AssessmentDashboardStatisticsType.custom_resolver(info, filter)
28 changes: 28 additions & 0 deletions apps/assessment_registry/filter_set.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import django_filters

from user_resource.filters import UserResourceGqlFilterSet
from .models import AssessmentRegistry
from utils.graphene.filters import IDListFilter


class AssessmentDashboardFilterSet(UserResourceGqlFilterSet):
search = django_filters.CharFilter(method="filter_title")
stakeholder = IDListFilter(distinct=True)
lead_organization = IDListFilter(distinct=True)
location = IDListFilter(distinct=True)
sector = IDListFilter(distinct=True)
affected_group = IDListFilter(distinct=True)
family = IDListFilter(distinct=True)
frequency = IDListFilter(distinct=True)
coordination_type = IDListFilter(distinct=True)

class Meta:
model = AssessmentRegistry
fields = ()

def filter_search(self, qs, _, value):
return qs if value is None else qs.filter(project__title=value)

@property
def qs(self):
return super().qs.distinct()

0 comments on commit f696909

Please sign in to comment.