Example #1
0
 def setUpClass(cls):
     FormModelDocument.registered_functions = []
     cls.db_name = uniq('mangrove-test')
     cls.manager = get_db_manager('http://localhost:5984/', cls.db_name)
     initializer._create_views(cls.manager)
     create_views(cls.manager)
     question1 = UniqueIdField(unique_id_type='clinic',
                               name="entity_question",
                               code="ID",
                               label="What is associated entity")
     question2 = TextField(name="question1_Name",
                           code="Q1",
                           label="What is your name",
                           defaultValue="some default value",
                           constraints=[TextLengthConstraint(5, 10)])
     cls.project1 = Project(dbm=cls.manager,
                            name=project1_name,
                            goals="Testing",
                            devices=['web'],
                            form_code="abc",
                            fields=[question1, question2])
     cls.project1_id = cls.project1.save()
     cls.project2 = Project(dbm=cls.manager,
                            name=project2_name,
                            goals="Testing",
                            devices=['web'],
                            form_code="def",
                            fields=[question1, question2])
     cls.project2_id = cls.project2.save()
Example #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
Example #3
0
 def test_should_delete_datasender_from_project(self):
     self.project1 = Project.get(self.manager, self.project1_id)
     self.project1.data_senders = ['rep1', 'rep2']
     datasender_to_be_deleted = 'rep1'
     self.project1.delete_datasender(self.manager, datasender_to_be_deleted)
     self.project1 = Project.get(self.manager, self.project1_id)
     expected_data_senders = ['rep2']
     self.assertEqual(self.project1.data_senders, expected_data_senders)
Example #4
0
    def test_should_throw_unsupported_xform_edit_exception(self):
        new_questionnaire = Project.new_from_doc(DatabaseManagerStub(), ProjectDocument())
        old_questionnaire = Project.new_from_doc(DatabaseManagerStub(), ProjectDocument())
        validator = Mock(Validator)
        validator.valid.return_value = False

        self.assertRaises(UnsupportedXformEditException,
                          XFormEditor(Mock(Submission), validator, Mock(Questionnaire)).edit,
                          new_questionnaire, old_questionnaire, {})
Example #5
0
    def test_should_save_questionnaire_and_update_submission_when_valid_change(self):
        new_questionnaire = Project.new_from_doc(DatabaseManagerStub(), ProjectDocument())
        old_questionnaire = Project.new_from_doc(DatabaseManagerStub(), ProjectDocument())
        submission = Mock(Submission)
        validator = Mock(Validator)
        questionnaire = Mock(Questionnaire)
        validator.valid.return_value = True

        XFormEditor(submission, validator, questionnaire).edit(new_questionnaire, old_questionnaire, {})
        questionnaire.save.assert_called_once_with(new_questionnaire)
        submission.update_all.assert_called_once_with(new_questionnaire.id)
Example #6
0
    def test_should_update_project(self):
        self.project1 = Project.get(self.manager, self.project1_id)
        self.project1.update(
            dict(name=project1_name, devices=['web', 'sms'],
                 goals="New goals"))
        project1_id = self.project1.save()

        project = Project.get(self.manager, project1_id)
        self.assertEquals(project.name, project1_name)
        self.assertEquals(project.goals, 'New goals')
        self.assertEquals(project.devices, ['web', 'sms'])
Example #7
0
 def test_get_deadline_day(self):
     reminder_and_deadline_for_month = {
         "reminders_enabled": "True",
         "deadline_month": "5",
         "deadline_type": "current",
         "frequency_enabled": "True",
         "has_deadline": "True",
         "frequency_period": "month"
     }
     project_reminders = Project(self.manager, name="ReminderProject")
     project_reminders.reminder_and_deadline = reminder_and_deadline_for_month
     self.assertEquals(5, project_reminders.get_deadline_day())
Example #8
0
 def test_project_name_should_be_case_insensitively_unique(self):
     questionnaire = Project(self.manager,
                             name=project2_name.upper(),
                             goals="Testing",
                             devices=['web'])
     with self.assertRaises(Exception) as cm:
         questionnaire.save()
     the_exception = cm.exception
     self.assertEqual(
         the_exception.message,
         "Questionnaire with Name = '%s' already exists." %
         project2_name.upper())
Example #9
0
 def test_project_name_should_be_unique(self):
     questionnaire = Project(dbm=self.manager,
                             name=project2_name,
                             goals="Testing",
                             devices=['web'],
                             form_code="name_form",
                             fields=[])
     with self.assertRaises(Exception) as cm:
         questionnaire.save()
     the_exception = cm.exception
     self.assertEqual(
         the_exception.message,
         "Questionnaire with Name = '%s' already exists." % project2_name)
    def process(self, form_code, submission_values):
        form_model = get_form_model_by_code(self.dbm, form_code)
        project = Project.from_form_model(form_model=form_model)
        reporter_entity = self.request.get('reporter_entity')

        if project.is_open_survey or (reporter_entity.short_code == "test" or \
                isinstance(form_model, EntityFormModel) or \
                        reporter_entity.short_code in Project.from_form_model(form_model).data_senders):
            self.check_answers_numbers()
            return None

        self.check_answers_numbers(linked_datasender=False)
        return self._get_response(form_code)
Example #11
0
 def setUp(self):
     MangroveTestCase.setUp(self)
     initializer.run(self.manager)
     self.ds1 = self.create_datasender()
     self.ds2 = self.create_datasender()
     self.project = Project(self.manager,
                            name="Test reminders",
                            form_code="abc",
                            fields=[],
                            goals="This project is for automation",
                            devices=["sms", "web", "smartPhone"],
                            sender_group="close")
     self.manager._save_document(
         SurveyResponseDocument(channel="transport",
                                destination=12345,
                                form_model_id=self.project.id,
                                values={
                                    'Q1': 'ans1',
                                    'Q2': 'ans2'
                                },
                                status=False,
                                error_message="",
                                data_record_id='2345678',
                                owner_uid=self.ds1.id,
                                event_time=datetime.datetime(2011, 9, 1)))
     self.manager._save_document(
         SurveyResponseDocument(channel="transport",
                                destination=12345,
                                form_model_id=self.project.id,
                                values={
                                    'Q1': 'ans12',
                                    'Q2': 'ans22'
                                },
                                owner_uid=self.ds1.id,
                                status=False,
                                error_message="",
                                data_record_id='1234567',
                                event_time=datetime.datetime(2011, 3, 2)))
     self.manager._save_document(
         SurveyResponseDocument(channel="transport",
                                destination=12345,
                                form_model_id=self.project.id,
                                values={
                                    'Q1': 'ans123',
                                    'Q2': 'ans222'
                                },
                                owner_uid=self.ds2.id,
                                status=False,
                                error_message="",
                                data_record_id='1234567',
                                event_time=datetime.datetime(2011, 3, 3)))
Example #12
0
def get_customized_message_for_questionnaire(dbm,
                                             request,
                                             message_code,
                                             form_code,
                                             placeholder_dict=None,
                                             form_model=None):
    if form_model is None:
        try:
            form_model = get_form_model_by_code(dbm, form_code)
        except:
            pass

    if form_model is None or isinstance(
            form_model, EntityFormModel):  #For UniqueId registration
        message = _get_customized_message_for_language(
            dbm,
            request.get('organization').language, message_code)
    else:  # For questionnaire submission
        project = Project.from_form_model(form_model)
        message = _get_customized_message_for_language(dbm, project.language,
                                                       message_code)
        request[
            'is_outgoing_reply_sms_enabled'] = project.is_outgoing_sms_replies_enabled
    if placeholder_dict:
        message = _replace_placeholders_in_message(message, placeholder_dict)
    return message
Example #13
0
def remove_deleted_ds_from_project(db_name):
    logger = logging.getLogger(db_name)
    try:
        dbm = get_db_manager(db_name)
        logger.info("starting data fix for " + db_name)
        all_data_senders = set(get_all_active_data_senders(dbm))
        for project_doc in dbm.database.view("project_names/project_names",
                                             include_docs=True):
            try:
                project_data_senders = set(project_doc["doc"]["data_senders"])

                invalid_ds = project_data_senders.difference(all_data_senders)

                project_doc = Project._wrap_row(project_doc)
                for ds in invalid_ds:
                    logger.info("Found invalid data senders in project : " +
                                str(project_doc) + " " + str(invalid_ds))
                    project_doc.data_senders.remove(ds)
                    project_doc.save()

            except Exception as e:
                print "Error : " + db_name + " : " + str(
                    project_doc) + e.message
                traceback.print_exc(file=sys.stdout)
        logger.info("done:" + db_name)
        mark_as_completed(db_name)

    except Exception as e:
        logger.exception(e.message)
Example #14
0
def update_submission_search_for_subject_edition(dbm, unique_id_type,
                                                 short_code, last_name):
    projects = []
    for row in dbm.load_all_rows_in_view('projects_by_subject_type',
                                         key=unique_id_type[0],
                                         include_docs=True):
        projects.append(
            Project.new_from_doc(dbm, ProjectDocument.wrap(row['doc'])))
    for project in projects:
        entity_field_code = None
        for field in project.entity_questions:
            if [field.unique_id_type] == unique_id_type:
                entity_field_code = field.code

        if entity_field_code:
            unique_id_field_name = es_questionnaire_field_name(
                entity_field_code, project.id)

            fields_mapping = {unique_id_field_name: last_name}
            args = {
                es_unique_id_code_field_name(unique_id_field_name): short_code
            }

            query = _get_submissions_for_unique_id_entry(args, dbm, project)

            for survey_response in query.values_dict('void'):
                SubmissionIndexUpdateHandler(
                    dbm.database_name,
                    project.id).update_field_in_submission_index(
                        survey_response._id, fields_mapping)
Example #15
0
def edit_xform_submission_post(request, survey_response_id):
    manager = get_database_manager(request.user)
    survey_response = get_survey_response_by_id(manager, survey_response_id)
    activity_log = UserActivityLog()
    questionnaire = Project.get(manager, survey_response.form_model_id)
    old_data = survey_response._doc.values

    try:
        response = XFormWebSubmissionHandler(request=request). \
            update_submission_response(survey_response_id)
        new_survey_response = get_survey_response_by_id(
            manager, survey_response_id)
        new_data = new_survey_response._doc.values

        edit_details = _details_for_activity_log(new_data, old_data,
                                                 questionnaire)
        activity_log.log(request,
                         action=EDITED_DATA_SUBMISSION_ADV_QUEST,
                         project=questionnaire.name,
                         detail=json.dumps(edit_details))

        return response

    except Exception as e:
        logger.exception("Exception in submission : \n%s" % e)
        send_email_on_exception(request.user,
                                "Edit Web Submission",
                                traceback.format_exc(),
                                additional_details={
                                    'survey_response_id': survey_response_id,
                                    'submitted-data': request.POST['form_data']
                                })
        return HttpResponseBadRequest()
Example #16
0
    def post(self, request, project_id):
        data = request.POST['data']
        file_type = request.POST['file_type']
        is_draft = request.POST['is_draft']
        try:
            excel_as_dict = json.loads(data, object_pairs_hook=OrderedDict)
            if is_draft and is_draft.lower().strip() == 'true':
                manager = get_database_manager(request.user)
                questionnaire = Project.get(manager, project_id)
                _save_questionnaire_as_dict_for_builder(
                    questionnaire, excel_as_dict=excel_as_dict)
                return HttpResponse(json.dumps({
                    "status": "success",
                    "project_id": project_id,
                    'reason': 'Successfully updated',
                    'details': ''
                }),
                                    content_type='application/json')

            excel_raw_stream = convert_json_to_excel(excel_as_dict, file_type)
            excel_file = _temp_file(request, excel_raw_stream, file_type)
            return _edit_questionnaire(request, project_id, excel_file,
                                       excel_as_dict)

        except Exception as e:
            logger.exception('Unable to save questionnaire from builder')
            return HttpResponse(
                json.dumps({
                    "status": "error",
                    "project_id": project_id,
                    'reason': 'Unable to save',  # TODO: i18n translation
                    'details': e.message
                }),
                content_type='application/json')
Example #17
0
def my_poll_recipients_count(request, project_id):
    dbm = get_database_manager(request.user)
    questionnaire = Project.get(dbm, project_id)
    contact_dict = _get_poll_recipients(dbm, questionnaire)
    return HttpResponse(content_type='application/json',
                        content=json.dumps(
                            {'my_poll_recipients': contact_dict}))
Example #18
0
def geo_json_for_project(request, project_id, entity_type=None):
    dbm = get_database_manager(request.user)
    location_list = []

    try:
        if entity_type:
            first_geocode_field = _get_first_geocode_field_for_entity_type(
                dbm, entity_type)
            if first_geocode_field:
                unique_ids = get_all_entities(dbm, [entity_type], limit=1000)
                location_list.extend(
                    get_location_list_for_entities(first_geocode_field,
                                                   unique_ids))
        else:
            questionnaire = Project.get(dbm, project_id)
            unique_ids = by_short_codes(dbm,
                                        questionnaire.data_senders,
                                        ["reporter"],
                                        limit=1000)
            location_list.extend(get_location_list_for_datasenders(unique_ids))

    except DataObjectNotFound:
        pass

    location_geojson = {"type": "FeatureCollection", "features": location_list}
    return HttpResponse(json.dumps(location_geojson))
Example #19
0
 def _associate_datasender_to_poll_questionnaire(self, current_project_id,
                                                 dbm, short_codes):
     questionnaire = Project.get(dbm, current_project_id)
     questionnaire.associate_data_sender_to_project(dbm, short_codes)
     questionnaire.save()
     for short_code in short_codes:
         update_datasender_index_by_id(short_code, dbm)
Example #20
0
def send_reminders_for_an_organization(org,
                                       on_date,
                                       sms_client,
                                       from_number,
                                       dbm,
                                       charged_sms=False):
    """
    Sends out all reminders for an organization, scheduled for the given date.
    """
    reminders_grouped_by_proj = _get_reminders_grouped_by_project_for_organization(
        org.org_id)
    logger.info("Projects with reminders:- %d" %
                len(reminders_grouped_by_proj))
    for project_id, reminders in reminders_grouped_by_proj.items():
        try:
            project = Project.get(dbm, project_id)
            if not project.has_deadline():
                continue
            #send reminders to next projects in the queue if their is any error while sending reminders to previous project
            _, total_sms_sent = send_reminders_on(project, reminders, on_date,
                                                  sms_client, from_number, dbm)

            increment_dict = {'sent_reminders_count': total_sms_sent}
            if charged_sms:
                increment_dict.update(
                    {'sent_reminders_charged_count': total_sms_sent})
            org.increment_message_count_for(**increment_dict)

        except Exception:
            logger.exception(
                "Exception while sending reminders for this project")
Example #21
0
def get_submission_breakup(request, project_id):
    dbm = get_database_manager(request.user)
    questionnaire = Project.get(dbm, project_id)
    submission_success, submission_errors = submission_stats(
        dbm, questionnaire.id)
    response = json.dumps([submission_success, submission_errors])
    return HttpResponse(response)
Example #22
0
def analysis_results(request, project_id=None, questionnaire_code=None):
    manager = get_database_manager(request.user)
    org_id = helper.get_org_id_by_user(request.user)

    if request.method == 'GET':
        questionnaire = Project.get(manager, project_id)
        dashboard_page = settings.HOME_PAGE + "?deleted=true"
        if questionnaire.is_void():
            return HttpResponseRedirect(dashboard_page)

        filterable_fields = get_filterable_fields(questionnaire.fields, [])
        first_filterable_fields = filterable_fields.pop(
            0) if filterable_fields else None

        result_dict = {
            "xform": questionnaire.xform,
            "user_email": request.user.email,
            "is_quota_reached": is_quota_reached(request, org_id=org_id),
            "first_filterable_field": first_filterable_fields,
            "filterable_fields": filterable_fields,
            'is_pro_sms': get_organization(request).is_pro_sms,
            "is_media_field_present":
            questionnaire.is_media_type_fields_present
            # first 3 columns are additional submission data fields (ds_is, ds_name and submission_status
        }
        result_dict.update(
            project_info(request, questionnaire, questionnaire_code))
        return render_to_response('project/analysis_results.html',
                                  result_dict,
                                  context_instance=RequestContext(request))
Example #23
0
    def test_get_correct_web_submission_link(self):
        request = Mock()
        request.user = Mock(spec=User)
        manager = Mock(spec=DatabaseManager)
        manager.database = dict()
        raw_project = dict(
            value=dict(_id="pid",
                       devices=["sms", "web"],
                       name="Project Name",
                       created="2012-05-23T02:57:09.788294+00:00"))

        project = Project(dbm=manager, name="Project Name")

        profile = Mock(spec=NGOUserProfile)

        questionnaire = Mock()
        questionnaire.form_code = "q01"

        with patch("datawinners.project.models.Project.get") as get_project:
            get_project.return_value = project
            with patch.object(DatabaseManager, "get") as db_manager:
                db_manager.return_value = questionnaire
                with patch("django.contrib.auth.models.User.get_profile"
                           ) as get_profile:
                    get_profile.return_value = profile
                    profile.reporter = False
                    project_info = get_project_info(manager, raw_project)
                    self.assertEqual(project_info["web_submission_link"],
                                     "/project/testquestionnaire/pid/")
Example #24
0
    def _get_cascade_questionnaire(self, cascades):
        fields = []
        for cascade in cascades:
            fields.append(
                SelectField(cascade,
                            cascade,
                            "Please select",
                            cascades[cascade],
                            is_cascade=True))

        doc = ProjectDocument()
        doc.xform = self._build_xform(fields=fields,
                                      field_type="cascade",
                                      cascades=cascades)
        questionnaire = Project.new_from_doc(DatabaseManagerStub(), doc)
        questionnaire.name = "q1"
        questionnaire.form_code = "007"
        questionnaire.fields.append(
            FieldSet(code="group_outer",
                     name="group_outer",
                     label="Enter the outer group details",
                     field_set=[
                         FieldSet(code="repeat_outer",
                                  name="repeat_outer",
                                  label="Enter the details you wanna repeat",
                                  field_set=fields)
                     ]))
        return questionnaire
Example #25
0
    def post(self, request):
        project_name = request.GET['pname'].strip()
        manager = get_database_manager(request.user)

        try:
            xls_parser_response = _try_parse_xls(manager, request,
                                                 project_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, project_name)
            questionnaire_code = generate_questionnaire_code(manager)
            excel_file = _temp_file(request)
            mangrove_service = MangroveService(
                request,
                questionnaire_code=questionnaire_code,
                project_name=project_name,
                xls_form=excel_file,
                xls_parser_response=xls_parser_response)
            questionnaire_id, form_code = mangrove_service.create_project()

            if not questionnaire_id:
                logger.info("User: %s. Upload Error: %s",
                            request.user.username,
                            "Questionnaire must be unique")

                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.")
                    }))

            questionnaire = Project.get(manager, questionnaire_id)
            _save_questionnaire_as_dict_for_builder(questionnaire,
                                                    excel_file=excel_file)
        except QuestionAlreadyExistsException as e:
            return HttpResponse(content_type='application/json',
                                content=json.dumps({
                                    'success': False,
                                    'error_msg': [_(e.message)]
                                }))
        return HttpResponse(json.dumps({
            "success": True,
            "project_name": project_name,
            "project_id": questionnaire_id,
            "form_code": form_code
        }),
                            content_type='application/json')
Example #26
0
def make_user_data_sender_with_project(manager, reporter_id, project_id):
    questionnaire = Project.get(manager, project_id)
    reporters_to_associate = [reporter_id]
    questionnaire.associate_data_sender_to_project(manager,
                                                   reporters_to_associate)
    for data_senders_code in reporters_to_associate:
        update_datasender_index_by_id(data_senders_code, manager)
Example #27
0
    def test_should_validate_xform_change(self):
        rule1 = Mock(Rule)
        rule2 = Mock(Rule)

        new_questionnaire = Project.new_from_doc(DatabaseManagerStub(), ProjectDocument())
        old_questionnaire = Project.new_from_doc(DatabaseManagerStub(), ProjectDocument())
        old_questionnaire.xform_model = Mock(Xform)
        new_questionnaire.xform_model = Mock(Xform)

        old_questionnaire.xform_model.equals.return_value = True
        activity_log_detail = {}
        self.assertTrue(Validator([rule1, rule2]).valid(new_questionnaire, old_questionnaire, activity_log_detail))
        rule1.update_xform.assert_called_once_with(old_questionnaire, new_questionnaire, activity_log_detail)

        old_questionnaire.xform_model.equals.return_value = False
        self.assertFalse(Validator([rule1, rule2]).valid(new_questionnaire, old_questionnaire, activity_log_detail))
Example #28
0
 def test_should_not_show_change_setting_option(self):
     self.registered_datasenders_page = self._create_project_and_go_to_registered_datasenders(
     )
     self.assertFalse(self.registered_datasenders_page.
                      is_change_setting_option_displayed())
     form_model = get_form_model_by_code(self.dbm, self.questionnaire_code)
     project = Project.from_form_model(form_model)
     self.assertFalse(project.is_open_survey)
Example #29
0
 def _get_projects(self, manager, request):
     project_ids = request.POST.get('project_id').split(';')
     questionnaires = []
     for project_id in project_ids:
         questionnaire = Project.get(manager, project_id)
         if questionnaire is not None:
             questionnaires.append(questionnaire)
     return questionnaires
Example #30
0
def get_projects_by_unique_id_type(dbm, unique_id_type):
    projects = []
    for row in dbm.load_all_rows_in_view('projects_by_subject_type',
                                         key=unique_id_type[0],
                                         include_docs=True):
        projects.append(
            Project.new_from_doc(dbm, ProjectDocument.wrap(row['doc'])))
    return projects