Skip to content

Commit

Permalink
Merge 559c402 into 841e0b2
Browse files Browse the repository at this point in the history
  • Loading branch information
noliveleger committed Oct 23, 2018
2 parents 841e0b2 + 559c402 commit 1015f22
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 51 deletions.
5 changes: 4 additions & 1 deletion src/formpack/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
# represent the untranslated value.

# These two constants can be set to different values but they must
# not be equal
# not be equal.
# User-specified translations would always be a string,
# thus should never the boolean `False`.
# When formpack cannot find a label for the requested translation, it returns the XML name instead.
UNSPECIFIED_TRANSLATION = False

# This `UNTRANSLATED` will correspond to `null` in the schema where
Expand Down
50 changes: 40 additions & 10 deletions src/formpack/reporting/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import (unicode_literals, print_function, absolute_import,
division)

from inspect import isclass

try:
from cyordereddict import OrderedDict
Expand All @@ -29,6 +30,23 @@ def __init__(self, formpack, form_versions, lang=UNSPECIFIED_TRANSLATION,
version_id_keys=[],
multiple_select="both", copy_fields=(), force_index=False,
title="submissions", tag_cols_for_header=None):
"""
:param formpack: FormPack
:param form_versions: OrderedDict
:param lang: string, False (`constants.UNSPECIFIED_TRANSLATION`), or
None (`constants.UNTRANSLATED`).
:param group_sep: bool.
:param hierarchy_in_labels: bool.
:param version_id_keys: list.
:param multiple_select: string.
:param copy_fields: tuple. It can be a mix of strings and
`schema.fields.*CopyFields` classes (e.g.
`ValidationStatusCopyField`)
:param force_index: bool.
:param title: string
:param tag_cols_for_header: list
"""

self.formpack = formpack
self.lang = lang
Expand All @@ -45,14 +63,17 @@ def __init__(self, formpack, form_versions, lang=UNSPECIFIED_TRANSLATION,
tag_cols_for_header = []
self.tag_cols_for_header = tag_cols_for_header

# If some fields need to be arbitrarly copied, add them
# If some fields need to be arbitrarily copied, add them
# to the first section
if copy_fields:
for version in iter(form_versions.values()):
first_section = next(iter(version.sections.values()))
for name in copy_fields:
dumb_field = CopyField(name, section=first_section)
first_section.fields[name] = dumb_field
for copy_field in copy_fields:
if isclass(copy_field):
dumb_field = copy_field(section=first_section)
else:
dumb_field = CopyField(copy_field, section=first_section)
first_section.fields[dumb_field.name] = dumb_field

# this deals with merging all form versions headers and labels
params = (
Expand Down Expand Up @@ -170,8 +191,13 @@ def get_fields_labels_tags_for_all_versions(self,
auto_field_names.append('_parent_index')
# Add extra fields
for copy_field in self.copy_fields:
auto_field_names.append(
"_submission_{}".format(copy_field))
if isclass(copy_field):
auto_field_names.append(
"_submission_{}".format(copy_field.FIELD_NAME))
else:
auto_field_names.append(
"_submission_{}".format(copy_field))


# Flatten field labels and names. Indeed, field.get_labels()
# and self.names return a list because a multiple select field can
Expand Down Expand Up @@ -324,9 +350,14 @@ def format_one_submission(self, submission, current_section):
extra_mapping_values = self.__get_extra_mapping_values(current_section.parent)
if extra_mapping_values:
for extra_mapping_field in self.copy_fields:
row[
u"_submission_{}".format(extra_mapping_field)
] = extra_mapping_values.get(extra_mapping_field, "")
if isclass(extra_mapping_field):
row[
u"_submission_{}".format(extra_mapping_field.FIELD_NAME)
] = extra_mapping_values.get(extra_mapping_field, "")
else:
row[
u"_submission_{}".format(extra_mapping_field)
] = extra_mapping_values.get(extra_mapping_field, "")

rows.append(list(row.values()))

Expand Down Expand Up @@ -430,7 +461,6 @@ def to_table(self, submissions):
return table

def to_xlsx(self, filename, submissions):

workbook = xlsxwriter.Workbook(filename, {'constant_memory': True})
workbook.use_zip64()

Expand Down
30 changes: 28 additions & 2 deletions src/formpack/schema/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from __future__ import (unicode_literals, print_function, absolute_import,
division)

import re

from operator import itemgetter
Expand All @@ -23,7 +22,7 @@
import statistics

from ..utils.xform_tools import normalize_data_type
from ..constants import UNSPECIFIED_TRANSLATION, UNTRANSLATED
from ..constants import UNSPECIFIED_TRANSLATION
from .datadef import FormDataDef, FormChoice


Expand Down Expand Up @@ -534,6 +533,33 @@ def get_labels(self, *args, **kwargs):
return [self.name]


class ValidationStatusCopyField(CopyField):

# `FIELD_NAME` specifies both the name of the field in the source data and
# the label that will be appended to `_submission` and used in exports. For
# example, `_validation_status` will export as a column whose header is
# `_submission_validation_status`
FIELD_NAME = "_validation_status"

def __init__(self, section=None, *args, **kwargs):
super(ValidationStatusCopyField, self).__init__(
self.FIELD_NAME,
section=section,
*args, **kwargs)

def format(self, val, lang=UNSPECIFIED_TRANSLATION, context=None):

if isinstance(val, dict):
if lang == UNSPECIFIED_TRANSLATION:
value = {self.name: val.get("uid", "")}
else:
value = {self.name: val.get("label", "")}
else:
value = super(CopyField, self).format(val=val, lang=lang, context=context)

return value


class FormGPSField(FormField):

def __init__(self, name, labels, data_type, hierarchy=None,
Expand Down
29 changes: 25 additions & 4 deletions tests/fixtures/customer_satisfaction/v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,40 @@
"customer_enjoyment": "yes",
"restaurant_name": "Felipes",
"_uuid": "90dd7750f83011e590707c7a9125d07d",
"_submission_time": "2016-04-01 19:57:45.306805"
"_submission_time": "2016-04-01 19:57:45.306805",
"_validation_status": {
"by_whom": "user1",
"timestamp": 1531158682,
"uid": "validation_status_approved",
"color": "#00ff00",
"label":"Approved"
}
},
{
"customer_enjoyment": "no",
"restaurant_name": "Dunkin Donuts",
"_uuid": "90dd7750f83011e590707c7a9125d08d",
"_submission_time": "2016-04-02 19:57:45.306805"
"_submission_time": "2016-04-02 19:57:45.306805",
"_validation_status": {
"by_whom": "user1",
"timestamp": 1531158682,
"uid": "validation_status_approved",
"color": "#00ff00",
"label":"Approved"
}
},
{
"customer_enjoyment": "no",
"restaurant_name": "McDonalds",
"_uuid": "90dd7750f83011e590707c7a9125d09d",
"_submission_time": "2016-04-03 19:57:45.306805"
"_submission_time": "2016-04-03 19:57:45.306805",
"_validation_status": {
"by_whom": "user1",
"timestamp": 1531158682,
"uid": "validation_status_approved",
"color": "#00ff00",
"label":"Approved"
}
}
]
}
}
2 changes: 1 addition & 1 deletion tests/fixtures/grouped_repeatable/v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,4 @@
"meta/formUID": "9677d34e6ad14302afed5aa2951c28ab"
}
]
}
}
14 changes: 14 additions & 0 deletions tests/fixtures/nested_grouped_repeatable/v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@
},
"submissions": [
{
"_validation_status": {
"by_whom": "user1",
"timestamp": 1531158682,
"uid": "validation_status_approved",
"color": "#00ff00",
"label":"Approved"
},
"meta/instanceID": "uuid:f16d9a3f-0892-413e-81d4-758ab188ea0b",
"end": "2017-12-27T15:58:20.000-05:00",
"_submission_time": "2017-12-27T20:58:25",
Expand Down Expand Up @@ -165,6 +172,13 @@
"formhub/uuid": "ddd2f25ff0f5464a9f91ad65130f1460"
},
{
"_validation_status": {
"by_whom": "user1",
"timestamp": 1531158682,
"uid": "validation_status_not_approved",
"color": "#00ff00",
"label":"Not approved"
},
"meta/instanceID": "uuid:790af158-7b24-4651-b584-27bf65b9e397",
"end": "2017-12-27T15:58:50.000-05:00",
"_submission_time": "2017-12-27T20:58:55",
Expand Down

0 comments on commit 1015f22

Please sign in to comment.