Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge select one and select multiple options at MergedXform creation #2015

Merged
merged 1 commit into from
Feb 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions onadata/libs/serializers/merged_xform_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,28 @@ 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
# Remove bind attributes from child elements
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 and element_list[0]:
children += element_list[0]['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."))

Expand Down
16 changes: 12 additions & 4 deletions onadata/libs/tests/serializers/test_merged_xform_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"""
Test MergedXFormSerializer
"""
import copy
from rest_framework import serializers

from onadata.apps.api.tests.viewsets.test_abstract_viewset import \
Expand Down Expand Up @@ -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',
Expand All @@ -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):
Expand Down
30 changes: 5 additions & 25 deletions onadata/libs/utils/chart_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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 = [
Expand All @@ -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(
Expand Down