-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Aggregated all stakeholder into single field in assessment_registry.
- Add dataloader in assessment_registry
- Loading branch information
1 parent
68a2d44
commit 0ac4c8b
Showing
19 changed files
with
516 additions
and
144 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.