Ejemplo n.º 1
0
    def test_should_not_save_snapshots_when_questionnaires_field_not_changed(
            self):
        self._create_form_model()
        form_model = get_form_model_by_code(self.manager, FORM_CODE_1)

        post = [{
            "title": "What is associated entity",
            "options": {
                "ddtype": self.default_ddtype.to_json()
            },
            "type": "text",
            "is_entity_question": True,
            "code": "ID",
            "name": "entity_question"
        }, {
            "title": "What is your name",
            "options": {
                "ddtype": self.default_ddtype.to_json()
            },
            "type": "text",
            "is_entity_question": False,
            "code": "Q1",
            "range_min": 5,
            "range_max": 10
        }]
        QuestionnaireBuilder(
            form_model, self.manager).update_questionnaire_with_questions(post)
        form_model.save()
        form_model = get_form_model_by_code(self.manager, FORM_CODE_1)

        self.assertEqual(0, len(form_model.snapshots))
Ejemplo n.º 2
0
def create_questionnaire(post, manager, name, language, reporter_id, question_set_json=None,
                         xform=None, is_open_survey=False):

    questionnaire_code = post['questionnaire-code'].lower()
    datasenders = json.loads(post.get('datasenders', "[]"))
    question_set = question_set_json if question_set_json else json.loads(post['question-set'])
    questionnaire = Project(manager, name=name,
                           fields=[], form_code=questionnaire_code, language=language,
                           devices=[u'sms', u'web', u'smartPhone'])
    questionnaire.xform = xform

    if is_open_survey:
        questionnaire.is_open_survey = post.get('is_open_survey')
        
    if reporter_id is not None:
        questionnaire.data_senders.append(reporter_id)

    if datasenders:
        questionnaire.data_senders.extend(filter(lambda ds: ds != reporter_id, datasenders))

    outgoing_sms_enabled = not xform and post.get('is_outgoing_sms_enabled', 'true')
    QuestionnaireBuilder(questionnaire, manager)\
        .update_questionnaire_with_questions(question_set)\
        .update_reminder(json.loads(post.get('reminder_and_deadline', '{}')))\
        .update_outgoing_sms_enabled_flag(outgoing_sms_enabled)

    return questionnaire
Ejemplo n.º 3
0
    def test_should_save_snapshots_when_questionnaires_field_modified(self):
        self._create_form_model()
        form_model = get_form_model_by_code(self.manager, FORM_CODE_1)
        original_fields = form_model._doc.json_fields
        revision = form_model._doc['_rev']

        post = [{
            "title": "q1",
            "type": "text",
            "choices": [],
            "is_entity_question": False,
            "code": "q1",
            "min_length": 1,
            "max_length": ""
        }, {
            "title": "q2",
            "type": "integer",
            "choices": [],
            "is_entity_question": False,
            "code": "q2",
            "range_min": 0,
            "range_max": 100
        }]
        QuestionnaireBuilder(
            form_model, self.manager).update_questionnaire_with_questions(post)
        form_model.save()
        form_model = get_form_model_by_code(self.manager, FORM_CODE_1)

        self.assertEqual(1, len(form_model.snapshots))
        self.assertEqual(revision, form_model.snapshots.keys()[-1])
        expect = [(each['code'], each['label']) for each in original_fields]
        self.assertListEqual(expect,
                             [(each.code, each.label)
                              for each in form_model.snapshots[revision]])
Ejemplo n.º 4
0
def save_questionnaire(request):
    manager = get_database_manager(request.user)
    if request.method == 'POST':
        questionnaire_code = request.POST['questionnaire-code']
        json_string = request.POST['question-set']
        question_set = json.loads(json_string)
        pid = request.POST['pid']
        project = Project.load(manager.database, pid)
        form_model = FormModel.get(manager, project.qid)
        old_fields = form_model.fields
        try:
            QuestionnaireBuilder(form_model, manager).update_questionnaire_with_questions(question_set)
        except QuestionCodeAlreadyExistsException as e:
            return HttpResponseServerError(e)
        except QuestionAlreadyExistsException as e:
            return HttpResponseServerError(e)
        except EntityQuestionAlreadyExistsException as e:
            return HttpResponseServerError(e.message)
        else:
            try:
                form_model.form_code = questionnaire_code.lower()
            except DataObjectAlreadyExists as e:
                if e.message.find("Form") >= 0:
                    return HttpResponseServerError("Questionnaire with this code already exists")
                return HttpResponseServerError(e.message)
            form_model.name = project.name
            form_model.entity_id = project.entity_type
            detail = utils.get_changed_questions(old_fields, form_model.fields, subject=False)
            form_model.save()
            UserActivityLog().log(request, project=project.name, action=EDITED_PROJECT, detail=json.dumps(detail))
            return HttpResponse(json.dumps({"response": "ok"}))
Ejemplo n.º 5
0
def update_questionnaire(questionnaire, post, manager):
    questionnaire.form_code = post['questionnaire-code'].lower()
    json_string = post['question-set']
    question_set = json.loads(json_string)
    QuestionnaireBuilder(
        questionnaire,
        manager).update_questionnaire_with_questions(question_set)
    return questionnaire
def create_questionnaire(post, manager, entity_type, name, language):
    entity_type = [entity_type] if is_string(entity_type) else entity_type
    questionnaire_code = post['questionnaire-code'].lower()
    json_string = post['question-set']
    question_set = json.loads(json_string)
    form_model = FormModel(manager, entity_type=entity_type, name=name, type='survey',
                           state=post['project_state'], fields=[], form_code=questionnaire_code, language=language)
    QuestionnaireBuilder(form_model, manager).update_questionnaire_with_questions(question_set)
    return form_model
def update_questionnaire(questionnaire, post, entity_type, name, manager, language):
    questionnaire.name = name
    questionnaire.activeLanguages = [language]
    questionnaire.entity_type = [entity_type] if is_string(entity_type) else entity_type
    questionnaire.form_code = post['questionnaire-code'].lower()
    json_string = post['question-set']
    question_set = json.loads(json_string)
    QuestionnaireBuilder(questionnaire, manager).update_questionnaire_with_questions(question_set)
    questionnaire.deactivate() if post['project_state'] == ProjectState.INACTIVE else questionnaire.set_test_mode()
    return questionnaire
    def test_should_remove_unique_id_validator_if_unique_id_field_is_not_present(
            self):
        dbm = Mock(spec=DatabaseManager)
        form_model = MagicMock(spec=FormModel)
        form_model.fields = [TextField('name', 'code', 'label')]
        form_model.entity_questions = []
        QuestionnaireBuilder(form_model, dbm)._update_unique_id_validator()

        form_model.remove_validator.assert_called_once_with(
            UniqueIdExistsValidator)
    def test_should_add_unique_id_validator_to_form_model_if_unique_id_field_is_present(
            self):
        dbm = Mock(spec=DatabaseManager)
        form_model = MagicMock(spec=FormModel)
        form_model.fields = [UniqueIdField('clinic', 'name', 'code', 'label')]

        QuestionnaireBuilder(form_model, dbm)._update_unique_id_validator()

        form_model.add_validator.assert_called_once_with(
            UniqueIdExistsValidator)
Ejemplo n.º 10
0
def _create_questionnaire(manager, questionnaire, question):
    question_set = [{
        'title': question,
        'type': 'text',
        "is_entity_question": False,
        "code": 'q1',
        "name": question,
        'required': True,
        "parent_field_code": '',
        "instruction": "Answer must be a text",
        'label': question
    }]
    QuestionnaireBuilder(
        questionnaire,
        manager).update_questionnaire_with_questions(question_set)
Ejemplo n.º 11
0
    def test_should_update_questionnaire_when_entity_type_is_not_reporter(
            self):
        self._create_form_model()
        form_model = self.manager.get(self.form_model__id, FormModel)
        post = [{
            "title": "What is your age",
            "code": "age",
            "type": "integer",
            "choices": [],
            "is_entity_question": False,
            "range_min": 0,
            "range_max": 100
        }]

        QuestionnaireBuilder(
            form_model, self.manager).update_questionnaire_with_questions(post)
        self.assertEquals(1, len(form_model.fields))
Ejemplo n.º 12
0
 def test_should_update_questionnaire_when_entity_type_is_reporter(self):
     self._create_summary_form_model()
     post = [{
         "title": "q1",
         "type": "text",
         "choices": [],
         "is_entity_question": False,
         "code": "q1",
         "min_length": 1,
         "max_length": ""
     }, {
         "title": "q2",
         "type": "integer",
         "choices": [],
         "is_entity_question": False,
         "code": "code",
         "range_min": 0,
         "range_max": 100
     }, {
         "title": "q3",
         "type": "select",
         "code": "code",
         "choices": [{
             "value": "c1"
         }, {
             "value": "c2"
         }],
         "is_entity_question": False
     }]
     summary_form_model = self.manager.get(self.summary_form_model__id,
                                           FormModel)
     QuestionnaireBuilder(
         summary_form_model,
         self.manager).update_questionnaire_with_questions(post)
     self.assertEqual(4, len(summary_form_model.fields))
     self.assertEqual('eid', summary_form_model.fields[0].code)
     self.assertEqual('q1', summary_form_model.fields[1].code)
     self.assertEqual('q2', summary_form_model.fields[2].code)
     self.assertEqual('q3', summary_form_model.fields[3].code)
     entity_id_question = summary_form_model.entity_question
     self.assertEqual('eid', entity_id_question.code)
     self.assertEqual('I am submitting this data on behalf of',
                      entity_id_question.name)
     self.assertEqual("Choose Data Sender from this list.",
                      entity_id_question.instruction)
Ejemplo n.º 13
0
def save_questionnaire(request):
    manager = get_database_manager(request.user)
    if request.method == 'POST':
        new_short_code = request.POST['questionnaire-code'].lower()
        saved_short_code = request.POST['saved-questionnaire-code'].lower()

        form_model = get_form_model_by_code(manager, saved_short_code)
        detail_dict = dict()
        if new_short_code != saved_short_code:
            try:
                form_model.old_form_code = form_model.form_code
                form_model.form_code = new_short_code
                form_model.save()
                detail_dict.update({"form_code": new_short_code})
            except DataObjectAlreadyExists as e:
                if e.message.find("Form") >= 0:
                    return HttpResponse(json.dumps({'success': False, "code_has_error": True,
                                                    'error_message': ugettext(
                                                        "Questionnaire with same code already exists.")}))
                return HttpResponseServerError(e.message)

        json_string = request.POST['question-set']
        question_set = json.loads(json_string)
        try:
            saved_fields = form_model.fields
            QuestionnaireBuilder(form_model, manager).update_questionnaire_with_questions(question_set)
            form_model.save()
            changed = get_changed_questions(saved_fields, form_model.fields)
            changed.update(dict(entity_type=form_model.entity_type[0].capitalize()))
            detail_dict.update(changed)
            kwargs = dict()
            if request.POST.get("project-name") is not None:
                kwargs.update(dict(project=request.POST.get("project-name").capitalize()))
            UserActivityLog().log(request, action=EDITED_REGISTRATION_FORM, detail=json.dumps(detail_dict), **kwargs)
            return HttpResponse(json.dumps({'success': True, 'form_code': form_model.form_code}))
        except QuestionCodeAlreadyExistsException as e:
            return HttpResponse(json.dumps({'success': False, 'error_message': _(e.message)}))
        except QuestionAlreadyExistsException as e:
            return HttpResponse(json.dumps({'success': False, 'error_message': _(e.message)}))
        except EntityQuestionAlreadyExistsException as e:
            return HttpResponse(json.dumps({'success': False, 'error_message': _(e.message)}))
Ejemplo n.º 14
0
def create_questionnaire(post, manager, name, language, reporter_id):
    questionnaire_code = post['questionnaire-code'].lower()
    datasenders = json.loads(post.get('datasenders', "[]"))
    json_string = post['question-set']
    question_set = json.loads(json_string)
    questionnaire = Project(manager,
                            name=name,
                            fields=[],
                            form_code=questionnaire_code,
                            language=language,
                            devices=[u'sms', u'web', u'smartPhone'])
    if reporter_id is not None:
        questionnaire.data_senders.append(reporter_id)

    if datasenders:
        questionnaire.data_senders.extend(
            filter(lambda ds: ds != reporter_id, datasenders))

    QuestionnaireBuilder(questionnaire, manager)\
        .update_questionnaire_with_questions(question_set)\
        .update_reminder(json.loads(post.get('reminder_and_deadline', '{}')))

    return questionnaire
Ejemplo n.º 15
0
    def post(self, request, project_id):

        manager = get_database_manager(request.user)
        questionnaire = Project.get(manager, project_id)
        file_content = None
        tmp_file = None
        try:
            file_content = request.raw_post_data

            file_errors, file_extension = _perform_file_validations(request)
            tmp_file = NamedTemporaryFile(delete=True, suffix=file_extension)

            if file_errors:
                logger.info(
                    "User: %s. Edit upload File validation failed: %s. File name: %s, size: %d",
                    request.user.username, json.dumps(file_errors),
                    request.GET.get("qqfile"),
                    int(request.META.get('CONTENT_LENGTH')))

                return HttpResponse(content_type='application/json',
                                    content=json.dumps({
                                        'success': False,
                                        'error_msg': file_errors
                                    }))

            tmp_file.write(file_content)
            tmp_file.seek(0)

            xls_parser_response = XlsFormParser(tmp_file, questionnaire.name,
                                                manager).parse()

            send_email_if_unique_id_type_question_has_no_registered_unique_ids(
                xls_parser_response, request, questionnaire.name)

            profile = request.user.get_profile()
            organization = Organization.objects.get(org_id=profile.org_id)
            if xls_parser_response.is_multiple_languages:
                logger.info(
                    "Edit Questionnaire %s with Multi Language support for organization : %s(%s) and email: %s",
                    questionnaire.name, organization.name, profile.org_id,
                    profile.user.email)

            if xls_parser_response.errors:
                info_list = list(xls_parser_response.errors)
                logger.info("User: %s. Edit upload Errors: %s",
                            request.user.username, json.dumps(info_list))

                return HttpResponse(
                    content_type='application/json',
                    content=json.dumps({
                        'success':
                        False,
                        'error_msg':
                        info_list,
                        'message_prefix':
                        _("Sorry! Current version of DataWinners does not support"
                          ),
                        'message_suffix':
                        _("Update your XLSForm and upload again.")
                    }))

            mangrove_service = MangroveService(
                request,
                questionnaire_code=questionnaire.form_code,
                project_name=questionnaire.name,
                xls_parser_response=xls_parser_response)

            questionnaire.xform = mangrove_service.xform_with_form_code
            QuestionnaireBuilder(questionnaire,
                                 manager).update_questionnaire_with_questions(
                                     xls_parser_response.json_xform_data)

            tmp_file.seek(0)
            questionnaire.update_media_field_flag()
            questionnaire.save(process_post_update=False)

            base_name, extension = os.path.splitext(tmp_file.name)
            questionnaire.update_attachments(tmp_file,
                                             'questionnaire%s' % extension)
            self._purge_submissions(manager, questionnaire)
            self._purge_feed_documents(questionnaire, request)
            self._purge_media_details_documents(manager, questionnaire)
            self.recreate_submissions_mapping(manager, questionnaire)
            if xls_parser_response.info:
                info_list = list(xls_parser_response.info)
                logger.info("User: %s. Edit upload Errors: %s",
                            request.user.username, json.dumps(info_list))
                return HttpResponse(content_type='application/json',
                                    content=json.dumps({
                                        'success':
                                        True,
                                        'information':
                                        info_list,
                                    }))
        except PyXFormError as e:
            logger.info("User: %s. Upload Error: %s", request.user.username,
                        e.message)

            message = transform_error_message(e.message)
            if 'name_type_error' in message or 'choice_name_type_error' in message:
                if 'choice_name_type_error' in message:
                    message_prefix = _(
                        "On your \"choices\" sheet the first and second column must be \"list_name\" and \"name\".  Possible errors:"
                    )
                else:
                    message_prefix = _(
                        "On your \"survey\" sheet the first and second column must be \"type\" and \"name\".  Possible errors:"
                    )
                return HttpResponse(
                    content_type='application/json',
                    content=json.dumps({
                        'success':
                        False,
                        'error_msg': [
                            _("Columns are missing"),
                            _("Column name is misspelled"),
                            _("Additional space in column name")
                        ],
                        'message_prefix':
                        message_prefix,
                        'message_suffix':
                        _("Update your XLSForm and upload again.")
                    }))
            else:
                return HttpResponse(
                    content_type='application/json',
                    content=json.dumps({
                        'success':
                        False,
                        'error_msg': [
                            message if message else ugettext(
                                "all XLSForm features. Please check the list of unsupported features."
                            )
                        ]
                    }))

        except QuestionAlreadyExistsException as e:
            logger.info("User: %s. Upload Error: %s", request.user.username,
                        e.message)

            return HttpResponse(
                content_type='application/json',
                content=json.dumps({
                    'success':
                    False,
                    'error_msg': [
                        _("Duplicate labels. All questions (labels) must be unique."
                          )
                    ],
                    'message_prefix':
                    _("Sorry! Current version of DataWinners does not support"
                      ),
                    'message_suffix':
                    _("Update your XLSForm and upload again.")
                }))

        except UnicodeDecodeError as e:
            logger.info("User: %s. Upload Error: %s", request.user.username,
                        e.message)

            return HttpResponse(
                content_type='application/json',
                content=json.dumps({
                    'success':
                    False,
                    'error_msg': [
                        _("Check your columns for errors.<br>There are missing symbols (like $ for relevant or calculate) or incorrect characters<br>"
                          ) + _("Update your XLSForm and upload again.")
                    ],
                }))

        except Exception as e:

            logger.info("User: %s. Edit Upload Exception message: %s",
                        request.user.username, e.message)

            message = e.message if e.message else _("Some error in excel")
            odk_message = ''
            if not 'ODK Validate Errors:' in e.message:
                send_email_on_exception(
                    request.user,
                    "Questionnaire Edit",
                    traceback.format_exc(),
                    additional_details={'file_contents': file_content})
            else:
                odk_message = translate_odk_message(e.message)
            message = odk_message if odk_message else message
            return HttpResponse(content_type='application/json',
                                content=json.dumps({
                                    'error_msg': [message],
                                    'success': False,
                                }))

        finally:
            if tmp_file:
                tmp_file.close()

        return HttpResponse(
            json.dumps({
                "success":
                True,
                "project_name":
                questionnaire.name,
                "project_id":
                questionnaire.id,
                "file_name":
                "%s%s" % (slugify(questionnaire.name), extension),
                # "xls_dict": XlsProjectParser().parse(file_content)
            }),
            content_type='application/json')
Ejemplo n.º 16
0
def _edit_questionnaire(request,
                        project_id,
                        excel_file=None,
                        excel_as_dict=None):
    manager = get_database_manager(request.user)
    questionnaire = Project.get(manager, project_id)
    try:
        xls_parser_response = _try_parse_xls(manager, request,
                                             questionnaire.name, excel_file)

        if isinstance(xls_parser_response, HttpResponse):
            return xls_parser_response

        doc = deepcopy(questionnaire._doc)
        doc.xform = MangroveService(
            request,
            questionnaire_code=questionnaire.form_code,
            xls_parser_response=xls_parser_response).xform_with_form_code
        new_questionnaire = Project.new_from_doc(manager, doc)
        QuestionnaireBuilder(new_questionnaire,
                             manager).update_questionnaire_with_questions(
                                 xls_parser_response.json_xform_data)
        xform_rules = get_all_rules()
        if excel_file is None:
            excel_file = _temp_file(request)
        else:
            excel_file.seek(0)
        questionnaire_wrapper = Questionnaire(excel_file)
        activity_log_detail = {}
        XFormEditor(
            Submission(manager, get_database_name(request.user), xform_rules),
            Validator(xform_rules),
            questionnaire_wrapper).edit(new_questionnaire, questionnaire,
                                        activity_log_detail)
        questionnaire = Project.get(manager, project_id)
        _save_questionnaire_as_dict_for_builder(questionnaire, excel_as_dict,
                                                excel_file)
        UserActivityLog().log(request,
                              action=EDITED_QUESTIONNAIRE,
                              project=questionnaire.name,
                              detail=json.dumps(activity_log_detail))

    except UnsupportedXformEditException as e:
        return HttpResponse(
            content_type='application/json',
            content=json.dumps({
                'success': False,
                'unsupported': True,
                'error_msg': [_("Unsupported edit operation")],
                "status": "error",
                'reason':
                "Unsupported edit operation",  # TODO: i18n translation
                'details': e.message
            }))
    except QuestionAlreadyExistsException as e:
        return HttpResponse(
            content_type='application/json',
            content=json.dumps({
                'success': False,
                'error_msg': [_(e.message)],
                "status": "error",
                'reason': "Save Failed",  # TODO: i18n translation
                'details': _(e.message)
            }))
    return HttpResponse(
        json.dumps({
            "success": True,
            "status": "success",
            'reason': 'Successfully updated'  # TODO: i18n translation
        }),
        content_type='application/json')
Ejemplo n.º 17
0
    def _overwrite(self, project_id, request):
        try:
            manager = get_database_manager(request.user)
            questionnaire = Project.get(manager, project_id)
            xls_parser_response = _try_parse_xls(manager, request,
                                                 questionnaire.name)
            if isinstance(xls_parser_response, HttpResponse):
                return xls_parser_response
            send_email_if_unique_id_type_question_has_no_registered_unique_ids(
                xls_parser_response, request, questionnaire.name)
            mangrove_service = MangroveService(
                request,
                questionnaire_code=questionnaire.form_code,
                project_name=questionnaire.name,
                xls_parser_response=xls_parser_response)
            questionnaire.xform = mangrove_service.xform_with_form_code
            QuestionnaireBuilder(questionnaire,
                                 manager).update_questionnaire_with_questions(
                                     xls_parser_response.json_xform_data)
            questionnaire.update_media_field_flag()
            questionnaire.save(process_post_update=False)
            UserActivityLog().log(self.request,
                                  action=EDITED_QUESTIONNAIRE,
                                  project=questionnaire.name,
                                  detail=questionnaire.name)
            tmp_file = _temp_file(request)
            base_name, extension = os.path.splitext(tmp_file.name)
            questionnaire.update_attachments(tmp_file,
                                             'questionnaire%s' % extension)
            questionnaire.update_external_itemset(
                mangrove_service.itemsets_csv)
            self._purge_submissions(manager, questionnaire)
            self._purge_feed_documents(questionnaire, request)
            self._purge_media_details_documents(manager, questionnaire)
            self.recreate_submissions_mapping(manager, questionnaire)
            excel_file = _temp_file(request)
            excel_file.seek(0)
            _save_questionnaire_as_dict_for_builder(questionnaire,
                                                    excel_file=excel_file)
            if xls_parser_response.info:
                info_list = list(xls_parser_response.info)
                logger.info("User: %s. Edit upload Errors: %s",
                            request.user.username, json.dumps(info_list))
                return HttpResponse(content_type='application/json',
                                    content=json.dumps({
                                        'success':
                                        True,
                                        'information':
                                        info_list,
                                    }))

        except QuestionAlreadyExistsException as e:
            return HttpResponse(
                content_type='application/json',
                content=json.dumps({
                    'success': False,
                    'error_msg': [_(e.message)],
                    "status": "error",
                    'reason': "Save Failed",  # TODO: i18n translation
                    'details': _(e.message)
                }))

        return HttpResponse(
            json.dumps({
                "success":
                True,
                "project_name":
                questionnaire.name,
                "project_id":
                questionnaire.id,
                "file_name":
                "%s%s" % (slugify(questionnaire.name), extension),
                # "xls_dict": XlsProjectParser().parse(file_content)
            }),
            content_type='application/json')