'
return form
@@ -712,7 +722,6 @@ def subRecordForm(self, external_record, form_spec='', *args, **kwargs):
The form and event numbers are mapped to form names and event names in
the order they were provided in the call to configure
-
If the REDCap project is not longitudinal (i.e. Survey or Data Forms
Classic) the event number is not required and will be ignored if
included
diff --git a/ehb_datasources/drivers/redcap/formBuilderJson.py b/ehb_datasources/drivers/redcap/formBuilderJson.py
index 24ca844..613d9da 100644
--- a/ehb_datasources/drivers/redcap/formBuilderJson.py
+++ b/ehb_datasources/drivers/redcap/formBuilderJson.py
@@ -20,6 +20,36 @@ class redcapTemplate(Template):
class FormBuilderJson(object):
+ # this method can be used to add a field not already defined in meta data to all forms
+ def add_new_field_to_form (self, meta, field_name="", form_name="", field_type="", field_label="", select_choices_or_calculations="",
+ section_header="", field_note="", text_validation_type_or_show_slider_number="",
+ text_validation_min="",text_validation_max="",identifier="", branching_logic="",
+ required_field="", custom_alignment="", question_number="", matrix_group_name="",
+ matrix_ranking="", field_annotation=""):
+ new_field = {}
+ new_field["field_name"] = field_name
+ new_field["form_name"] = form_name
+ new_field["section_header"] = section_header
+ new_field["field_type"] = field_type
+ new_field ["field_label"] = field_label
+ new_field["select_choices_or_calculations"]= select_choices_or_calculations
+ new_field["field_note"] = field_note
+ new_field["text_validation_type_or_show_slider_number"] = text_validation_type_or_show_slider_number
+ new_field["text_validation_min"] = text_validation_min
+ new_field["text_validation_max"] = text_validation_max
+ new_field["identifier"] = identifier
+ new_field["branching_logic"] = branching_logic
+ new_field["required_field"] = required_field
+ new_field["custom_alignment"] = custom_alignment
+ new_field["question_number"] = question_number
+ new_field["matrix_group_name"] = matrix_group_name
+ new_field["matrix_ranking"]= matrix_ranking
+ new_field["field_annotation"] = field_annotation
+ new_field = json.dumps (new_field)
+ new_field = json.loads(new_field)
+ meta.append(new_field)
+ return meta
+
def construct_form(self, meta, record_set, form_name, record_id,
event_num=None, unique_event_names=None,
event_labels=None, session=None, record_id_field=None):
@@ -64,6 +94,14 @@ def construct_form(self, meta, record_set, form_name, record_id,
return '''
There was an error retrieving this record from REDCap
'''
+
+ # construct the field name for adding completion status to redcap forms
+ completion_field_name = form_name + "_complete"
+ # add completion field to all redcap forms
+ meta = self.add_new_field_to_form (meta, field_name=completion_field_name, form_name=form_name,
+ field_type="dropdown", field_label="Form Completion Status", select_choices_or_calculations="0, Incomplete | 1, Unverified | 2, Complete",
+ section_header="Form Status", required_field="y")
+
form_fields = [
item for item in meta if item.get("form_name") == form_name
]
diff --git a/ehb_datasources/tests/unit_tests/test_form_builder.py b/ehb_datasources/tests/unit_tests/test_form_builder.py
index 6d701dc..101bc13 100644
--- a/ehb_datasources/tests/unit_tests/test_form_builder.py
+++ b/ehb_datasources/tests/unit_tests/test_form_builder.py
@@ -20,6 +20,7 @@ def test_construct_form(form_builder, redcap_metadata_json, redcap_record_json):
assert '' in form
assert '' in form
assert '' in form
+ assert 'Form Completion Status' in form
def test_construct_form2_branch_logic_functions(form_builder, redcap_metadata_json2, redcap_record_json2):
form = form_builder.construct_form(
@@ -84,3 +85,9 @@ def test_construct_form_bad_redcap_record(form_builder, redcap_metadata_json2):
'study_id'
)
assert 'There was an error retrieving this record from REDCap' in form
+
+def test_add_new_field_to_form(form_builder, redcap_metadata_json):
+ metadata_json = json.loads(redcap_metadata_json.decode('utf-8'))
+ new_field = form_builder.add_new_field_to_form(metadata_json, field_name="test_new_field")
+ last_index = len(new_field)-1
+ assert 'test_new_field' in new_field[last_index]['field_name']
diff --git a/ehb_datasources/tests/unit_tests/test_redcap_driver.py b/ehb_datasources/tests/unit_tests/test_redcap_driver.py
index 5e1ef77..687b840 100644
--- a/ehb_datasources/tests/unit_tests/test_redcap_driver.py
+++ b/ehb_datasources/tests/unit_tests/test_redcap_driver.py
@@ -788,3 +788,25 @@ def test_write_records_badresp(mocker, driver, redcap_payload):
{'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'text/xml'},
'content=record&data=%3Crecords%3E%3Citem%3E%3Cstudy_id%3E%3C%21%5BCDATA%5B0GUQDBCDE0EAWN9Q%3A8LAG76CHO%5D%5D%3E%3C%2Fstudy_id%3E%3Credcap_event_name%3E%3C%21%5BCDATA%5Bvisit_arm_1%5D%5D%3E%3C%2Fredcap_event_name%3E%3Ccolonoscopy_date%3E%3C%21%5BCDATA%5B2016-08-31%5D%5D%3E%3C%2Fcolonoscopy_date%3E%3Cgeneral_ibd%3E%3C%21%5BCDATA%5B2016-08-31%5D%5D%3E%3C%2Fgeneral_ibd%3E%3Ctransferrin_b%3E%3C%21%5BCDATA%5B102%5D%5D%3E%3C%2Ftransferrin_b%3E%3Cmeds___2%3E%3C%21%5BCDATA%5B0%5D%5D%3E%3C%2Fmeds___2%3E%3Cmeal_date%3E%3C%21%5BCDATA%5B2016-08-31%5D%5D%3E%3C%2Fmeal_date%3E%3Culcerative_colitis%3E%3C%21%5BCDATA%5B2016-08-31%5D%5D%3E%3C%2Fulcerative_colitis%3E%3Cmeds___1%3E%3C%21%5BCDATA%5B1%5D%5D%3E%3C%2Fmeds___1%3E%3Ccomments%3E%3C%21%5BCDATA%5BTest+Data%5D%5D%3E%3C%2Fcomments%3E%3Cweight%3E%3C%21%5BCDATA%5B20%5D%5D%3E%3C%2Fweight%3E%3Cchrons%3E%3C%21%5BCDATA%5B2016-08-31%5D%5D%3E%3C%2Fchrons%3E%3Cchol_b%3E%3C%21%5BCDATA%5B101%5D%5D%3E%3C%2Fchol_b%3E%3Ccolonoscopy%3E%3C%21%5BCDATA%5B0%5D%5D%3E%3C%2Fcolonoscopy%3E%3Cprealb_b%3E%3C%21%5BCDATA%5B19%5D%5D%3E%3C%2Fprealb_b%3E%3Cheight%3E%3C%21%5BCDATA%5B100%5D%5D%3E%3C%2Fheight%3E%3Ccreat_b%3E%3C%21%5BCDATA%5B0.6%5D%5D%3E%3C%2Fcreat_b%3E%3Cibd_flag%3E%3C%21%5BCDATA%5B1%5D%5D%3E%3C%2Fibd_flag%3E%3Cmeds___5%3E%3C%21%5BCDATA%5B0%5D%5D%3E%3C%2Fmeds___5%3E%3Cmeds___4%3E%3C%21%5BCDATA%5B0%5D%5D%3E%3C%2Fmeds___4%3E%3Cmeds___3%3E%3C%21%5BCDATA%5B0%5D%5D%3E%3C%2Fmeds___3%3E%3C%2Fitem%3E%3C%2Frecords%3E&format=xml&overwriteBehavior=overwrite&token=foo&type=flat'
)
+
+
+def test_srsf_redcap_completion_codes(mocker, driver, driver_configuration_long, redcap_metadata_json, redcap_record_json):
+ # Mocks
+ # Metadata request
+ driver.meta = mocker.MagicMock(return_value=redcap_metadata_json)
+ driver.configure(driver_configuration_long)
+ # Record Request
+ MockREDCapResponse = mocker.MagicMock(
+ spec=HTTPResponse,
+ status=200)
+ MockREDCapResponse.read = mocker.MagicMock(return_value=redcap_record_json)
+ driver.POST = mocker.MagicMock(return_value=MockREDCapResponse)
+
+ redcap_form_complete_codes = {}
+ redcap_form_complete_codes[(str(1)+"_"+str(3))] = 2
+ redcap_form_complete_codes[(str(0)+"_"+str(0))] = 1
+ form = driver.subRecordSelectionForm(form_url='/test/', redcap_form_complete_codes=redcap_form_complete_codes)
+ assert 'btn-success' in form
+ assert 'fa-circle' in form
+ assert 'btn-warning' in form
+ assert 'fa-adjust' in form