Skip to content

Commit

Permalink
Aggregated all stakeholder into single field in assessment_registry.
Browse files Browse the repository at this point in the history
- Add dataloader in assessment_registry
  • Loading branch information
Rup-Narayan-Rajbanshi committed Aug 14, 2023
1 parent 68a2d44 commit 0ac4c8b
Show file tree
Hide file tree
Showing 19 changed files with 516 additions and 144 deletions.
265 changes: 265 additions & 0 deletions '
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
from rest_framework import serializers

from .utils import get_hierarchy_level
from drf_dynamic_fields import DynamicFieldsMixin
from user_resource.serializers import UserResourceSerializer
from deep.serializers import (
RemoveNullFieldsMixin,
ProjectPropertySerializerMixin,
TempClientIdMixin,
IntegerIDField,
)

from organization.serializers import (
SimpleOrganizationSerializer
)
from .models import (
AssessmentRegistry,
MethodologyAttribute,
AdditionalDocument,
SummaryIssue,
Summary,
SummarySubPillarIssue,
SummaryFocus,
SummarySubDimmensionIssue,
ScoreRating,
ScoreAnalyticalDensity,
Answer,
AssessmentRegistryOrganization,
)


class AssessmentRegistryOrganizationSerializer(
RemoveNullFieldsMixin,
DynamicFieldsMixin,
UserResourceSerializer,
serializers.ModelSerializer
):
organization_type_display = serializers.CharField(source='get_organization_type_display', read_only=True)
organization_details = SimpleOrganizationSerializer(source='organization', read_only=True)

class Meta:
model = AssessmentRegistryOrganization
fields = ('id', 'organization', 'organization_details', 'organization_type', 'organization_type_display')


class MethodologyAttributeSerializer(TempClientIdMixin, serializers.ModelSerializer):
id = IntegerIDField(required=False)

class Meta:
model = MethodologyAttribute
fields = (
"id", "client_id", "data_collection_technique", "sampling_approach", "sampling_size",
"proximity", "unit_of_analysis", "unit_of_reporting",
)


class AdditionalDocumentSerializer(TempClientIdMixin, UserResourceSerializer):
id = IntegerIDField(required=False)

class Meta:
model = AdditionalDocument
fields = ("id", "client_id", "document_type", "file", "external_link",)


class IssueSerializer(UserResourceSerializer):
class Meta:
model = SummaryIssue
fields = (
'sub_pillar', 'sub_dimmension', 'parent', 'label'
)

def validate(self, data):
sub_pillar = data.get('sub_pillar')
sub_dimmension = data.get('sub_dimmension')
parent = data.get('parent')

if all([sub_pillar, sub_dimmension]):
raise serializers.ValidationError("Cannot select both sub_pillar and sub_dimmension field.")
if not any([sub_pillar, sub_dimmension]):
raise serializers.ValidationError("Either sub_pillar or sub_dimmension must be selected")

if parent:
if sub_pillar and sub_pillar != parent.sub_pillar:
raise serializers.ValidationError("sub_pillar does not match between parent and child.")
if sub_dimmension and sub_dimmension != parent.sub_dimmension:
raise serializers.ValidationError("sub_dimmension does not match between child and parent.")

hierarchy_level = get_hierarchy_level(parent)
if hierarchy_level > 2:
raise serializers.ValidationError("Cannot create issue more than two level of hierarchy")
return data


class SummarySubPillarIssueSerializer(UserResourceSerializer, TempClientIdMixin):
id = IntegerIDField(required=False)

class Meta:
model = SummarySubPillarIssue
fields = ("id", "summary_issue", "text", "order", "lead_preview_text_ref")


class SummaryMetaSerializer(UserResourceSerializer):
id = IntegerIDField(required=False)

class Meta:
model = Summary
fields = (
"id", "total_people_assessed", "total_dead", "total_injured", "total_missing",
"total_people_facing_hum_access_cons", "percentage_of_people_facing_hum_access_cons",
)


class SummaryFocusMetaSerializer(UserResourceSerializer):
id = IntegerIDField(required=False)

class Meta:
model = SummaryFocus
fields = (
"id", "focus", "percentage_of_people_affected", "total_people_affected", "percentage_of_moderate",
"percentage_of_severe", "percentage_of_critical", "percentage_in_need", "total_moderate",
"total_severe", "total_critical", "total_in_need", "total_pop_assessed", "total_not_affected",
"total_affected", "total_people_in_need", "total_people_moderately_in_need",
"total_people_severly_in_need", "total_people_critically_in_need",
)


class SummarySubDimmensionSerializer(UserResourceSerializer):
id = IntegerIDField(required=False)

class Meta:
model = SummarySubDimmensionIssue
fields = ("id", "summary_issue", "focus", "text", "order", "lead_preview_text_ref",)


class ScoreRatingSerializer(UserResourceSerializer, TempClientIdMixin):
id = IntegerIDField(required=False)

class Meta:
model = ScoreRating
fields = ("id", "client_id", "score_type", "rating", "reason",)


class ScoreAnalyticalDensitySerializer(UserResourceSerializer, TempClientIdMixin):
id = IntegerIDField(required=False)

class Meta:
model = ScoreAnalyticalDensity
fields = ("id", "client_id", "sector", "analysis_level_covered", "figure_provided",)


class CNAAnswerSerializer(TempClientIdMixin, UserResourceSerializer):
id = IntegerIDField(required=False)

class Meta:
model = Answer
fields = ("id", 'client_id', 'question', 'answer')


class AssessmentRegistrySerializer(UserResourceSerializer, ProjectPropertySerializerMixin):
stakeholders = AssessmentRegistryOrganizationSerializer(
source='projectorganization_set',
many=True,
)
methodology_attributes = MethodologyAttributeSerializer(
many=True, required=False
)
additional_documents = AdditionalDocumentSerializer(
many=True, required=False
)
score_ratings = ScoreRatingSerializer(
many=True, required=False
)
score_analytical_density = ScoreAnalyticalDensitySerializer(
source="analytical_density", many=True, required=False
)
cna = CNAAnswerSerializer(
source='answer',
many=True,
required=False
)
summary_pillar_meta = SummaryMetaSerializer(source='summary', required=False)

summary_sub_pillar_issue = SummarySubPillarIssueSerializer(
source="summary_sub_sector_issue_ary", many=True, required=False
)
summary_dimmension_meta = SummaryFocusMetaSerializer(
source='summary_focus', many=True, required=False
)
summary_sub_dimmension_issue = SummarySubDimmensionSerializer(
source="summary_focus_subsector_issue_ary", many=True, required=False
)

class Meta:
model = AssessmentRegistry
fields = (
"id",
"lead",
"bg_countries",
"bg_crisis_start_date",
"cost_estimates_usd",
"no_of_pages",
"data_collection_start_date",
"data_collection_end_date",
"publication_date",
"executive_summary",
"objectives",
"data_collection_techniques",
"sampling",
"limitations",
"locations",
"bg_crisis_type",
"bg_preparedness",
"external_support",
"coordinated_joint",
"details_type",
"family",
"frequency",
"confidentiality",
"stakeholders",
"language",
"focuses",
"sectors",
"protection_info_mgmts",
"affected_groups",
"methodology_attributes",
"additional_documents",
"score_ratings",
"score_analytical_density",
"cna",
"summary_pillar_meta",
"summary_sub_pillar_issue",
"summary_dimmension_meta",
"summary_sub_dimmension_issue",
)

def validate_score_ratings(self, data):
unique_score_types = set()
for d in data:
score_type = d.get("score_type")
if score_type in unique_score_types:
raise serializers.ValidationError("Score ratings should have unique score types")
unique_score_types.add(score_type)
return data

def validate_score_analytical_density(self, data):
unique_sector = set()
for d in data:
sector = d.get("sector")
if sector in unique_sector:
raise serializers.ValidationError("Score analytical density should have unique sectors")
unique_sector.add(sector)
return data

def validate(self, data):
data['project'] = self.project
return data

# def create(self, data):
# summary_data = data.pop('summary')
# instance = super().create(data)
# Summary.objects.create(
# assessment_registry=instance,
# **summary_data,
# )
# return instance
5 changes: 0 additions & 5 deletions apps/assessment_registry/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,6 @@ class AssessmentRegistryAdmin(admin.ModelAdmin):
'modified_by',
'project',
'bg_countries',
'lead_organizations',
'international_partners',
'donors',
'national_partners',
'governments',
'locations',
)
inlines = [
Expand Down
24 changes: 24 additions & 0 deletions apps/assessment_registry/dataloaders.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@

from collections import defaultdict
from promise import Promise

from django.utils.functional import cached_property
from utils.graphene.dataloaders import DataLoaderWithContext, WithContextMixin

from .models import AssessmentRegistryOrganization


class AssessmentRegistryOrganizationsLoader(DataLoaderWithContext):
def batch_load_fn(self, keys):
qs = AssessmentRegistryOrganization.objects.filter(assessment_registry__in=keys)
_map = defaultdict(list)
for org in qs.all():
_map[org.assessment_registry_id].append(org)
return Promise.resolve([_map.get(key) for key in keys])


class DataLoaders(WithContextMixin):

@cached_property
def stakeholders(self):
return AssessmentRegistryOrganizationsLoader(context=self.context)
5 changes: 5 additions & 0 deletions apps/assessment_registry/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
ScoreAnalyticalDensity,
Question,
SummarySubDimmensionIssue,
AssessmentRegistryOrganization,
)

AssessmentRegistryCrisisTypeEnum = convert_enum_to_graphene_enum(
Expand Down Expand Up @@ -106,6 +107,9 @@
AssessmentRegistrySummarySubPillarTypeEnum = convert_enum_to_graphene_enum(
SummaryIssue.SubPillar, name='AssessmentRegistrySummarySubPillarTypeEnum'
)
AssessmentRegistryOrganizationTypeEnum = convert_enum_to_graphene_enum(
AssessmentRegistryOrganization.Type, name='AssessmentRegistryOrganizationTypeEnum'
)
enum_map = {
get_enum_name_from_django_field(field): enum
for field, enum in (
Expand Down Expand Up @@ -137,5 +141,6 @@
(SummaryIssue.sub_pillar, AssessmentRegistrySummarySubPillarTypeEnum),
(SummaryIssue.sub_dimmension, AssessmentRegistrySummarySubDimmensionTypeEnum),
(SummaryFocus.focus, AssessmentRegistrySectorTypeEnum),
(AssessmentRegistryOrganization.organization_type, AssessmentRegistryOrganizationTypeEnum),
)
}
45 changes: 0 additions & 45 deletions apps/assessment_registry/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,48 +100,3 @@ def bg_countries(self, create, extracted, **kwargs):
if extracted:
for country in extracted:
self.bg_countries.add(country)

@factory.post_generation
def lead_organizations(self, create, extracted, **kwargs):
if not create:
return

if extracted:
for org in extracted:
self.lead_organizations.add(org)

@factory.post_generation
def international_partners(self, create, extracted, **kwargs):
if not create:
return

if extracted:
for partner in extracted:
self.international_partners.add(partner)

@factory.post_generation
def donors(self, create, extracted, **kwargs):
if not create:
return

if extracted:
for donor in extracted:
self.donors.add(donor)

@factory.post_generation
def national_partners(self, create, extracted, **kwargs):
if not create:
return

if extracted:
for partner in extracted:
self.national_partners.add(partner)

@factory.post_generation
def governments(self, create, extracted, **kwargs):
if not create:
return

if extracted:
for gov in extracted:
self.governments.add(gov)
2 changes: 1 addition & 1 deletion apps/assessment_registry/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def filter_assessment_registry(self, qs, name, value):
).distinct()


class IssueGQFilterSet(django_filters.FilterSet):
class AssessmentRegistryIssueGQFilterSet(django_filters.FilterSet):
sub_pillar = SimpleInputFilter(AssessmentRegistrySummarySubPillarTypeEnum)
sub_dimmension = SimpleInputFilter(AssessmentRegistrySummarySubDimmensionTypeEnum)

Expand Down
Loading

0 comments on commit 0ac4c8b

Please sign in to comment.