From 322fc882a1ed786d95d1971ccacd1e4e8675e1b5 Mon Sep 17 00:00:00 2001 From: FrankApiyo Date: Thu, 11 Feb 2021 17:39:51 +0300 Subject: [PATCH] Merge select one and select multiple options at MergedXform creation This also reverts: b6b03437a --- .../serializers/merged_xform_serializer.py | 16 ++++++++++ .../test_merged_xform_serializer.py | 16 +++++++--- onadata/libs/utils/chart_tools.py | 30 ++++--------------- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/onadata/libs/serializers/merged_xform_serializer.py b/onadata/libs/serializers/merged_xform_serializer.py index eafae30375..35f7f4adcc 100644 --- a/onadata/libs/serializers/merged_xform_serializer.py +++ b/onadata/libs/serializers/merged_xform_serializer.py @@ -71,6 +71,7 @@ def get_merged_xform_survey(xforms): del merged_xform_dict['_xpath'] is_empty = True + xform_dicts = [json.loads(xform.json) for xform in xforms] for child in merged_xform_dict['children']: if child['name'] != 'meta' and is_empty: is_empty = False @@ -78,6 +79,21 @@ def get_merged_xform_survey(xforms): if 'bind' in child: del child['bind'] + # merge select one and select multiple options + if 'children' in child and child['type'] in SELECTS: + children = [] + for xform_dict in xform_dicts: + element_name = child['name'] + element_list = list( + filter(lambda x: x['name'] == element_name, + xform_dict['children'])) + if element_list: + element = element_list[0] + children += element['children'] + # remove duplicates + set_of_jsons = {json.dumps(d, sort_keys=True) for d in children} + child['children'] = [json.loads(t) for t in set_of_jsons] + if is_empty: raise serializers.ValidationError(_("No matching fields in xforms.")) diff --git a/onadata/libs/tests/serializers/test_merged_xform_serializer.py b/onadata/libs/tests/serializers/test_merged_xform_serializer.py index 77ffe00fc7..176bcd960e 100644 --- a/onadata/libs/tests/serializers/test_merged_xform_serializer.py +++ b/onadata/libs/tests/serializers/test_merged_xform_serializer.py @@ -2,6 +2,7 @@ """ Test MergedXFormSerializer """ +import copy from rest_framework import serializers from onadata.apps.api.tests.viewsets.test_abstract_viewset import \ @@ -218,11 +219,11 @@ def test_get_merged_xform_survey(self): u'type': u'text' }, { u'children': [{ - u'name': u'female', - u'label': u'Female' - }, { u'name': u'male', u'label': u'Male' + }, { + u'name': u'female', + u'label': u'Female' }], u'name': u'gender', u'label': u'Sex', @@ -249,7 +250,14 @@ def test_get_merged_xform_survey(self): get_merged_xform_survey([xform1]) survey = get_merged_xform_survey([xform1, xform2]) - self.assertEqual(survey.to_json_dict(), expected) + survey_dict = survey.to_json_dict() + + # this field seems to change 50% of the time + expected2 = copy.deepcopy(expected) + expected2['children'][1]['children'] = \ + [{'name': 'female', 'label': 'Female'}, + {'name': 'male', 'label': 'Male'}] + self.assertTrue(survey_dict == expected or survey_dict == expected2) # no matching fields with self.assertRaises(serializers.ValidationError): diff --git a/onadata/libs/utils/chart_tools.py b/onadata/libs/utils/chart_tools.py index 67f56a82fd..0af727ec2a 100644 --- a/onadata/libs/utils/chart_tools.py +++ b/onadata/libs/utils/chart_tools.py @@ -12,7 +12,6 @@ from rest_framework.exceptions import ParseError from onadata.apps.logger.models.data_view import DataView -from onadata.apps.logger.models.merged_xform import MergedXForm from onadata.apps.logger.models.xform import XForm from onadata.libs.data.query import \ get_form_submissions_aggregated_by_select_one @@ -436,16 +435,6 @@ def get_field_label(field, language_index=0): return field_label -def _get_form_field_from_name_or_xpath(xform, name=None, xpath=None): - """ - Given a name or xpath, get xform field - """ - if name: - return get_field_from_field_name(name, xform) - elif xpath: - return get_field_from_field_xpath(xpath, xform) - - def get_chart_data_for_field(field_name, xform, accepted_format, @@ -457,6 +446,9 @@ def get_chart_data_for_field(field_name, """ data = {} + if field_name: + field = get_field_from_field_name(field_name, xform) + if group_by: if len(group_by.split(',')) > 1: group_by = [ @@ -466,22 +458,10 @@ def get_chart_data_for_field(field_name, else: group_by = get_field_from_field_xpath(group_by, xform) - field = _get_form_field_from_name_or_xpath(xform, - name=field_name, - xpath=field_xpath) + if field_xpath: + field = get_field_from_field_xpath(field_xpath, xform) choices = get_field_choices(field, xform) - # check if xform is a MergedXForm and if it is, merge the field's choices - if xform.is_merged_dataset: - merged_xform = MergedXForm.objects.get(pk=xform.pk) - children = [] - for xform in merged_xform.xforms.all(): - form_field = _get_form_field_from_name_or_xpath(xform, - name=field_name, - xpath=field_xpath) - children += form_field.children - field.children = children - xform = merged_xform try: data = build_chart_data_for_field(