예제 #1
0
    def get(self, request):
        # TODO: Add Overview data too
        overview_id = request.GET.get('overview_id', None)
        if not overview_id:
            return bad_request(
                'Could not complete request, \'overview_id\' is missing.')

        ov = Overview.objects.filter(id=overview_id).first()
        if not ov:
            return bad_request(
                'Could not find an Overview with the provided \'overview_id\'.'
            )

        # Check if the User has permissions to update
        if not request.user.is_superuser \
                and not request.user.has_perm('api.ifrc_admin') \
                and not request.user.has_perm('api.per_core_admin'):
            countries, regions = self.get_request_user_regions(request)

            if ov:
                # These need to be strings
                ov_country = f'{ov.country.id}' or ''
                ov_region = f'{ov.country.region.id}' if ov.country.region else ''

                if ov_country not in countries and ov_region not in regions:
                    return bad_request(
                        'You don\'t have permission to update these forms.')
            else:
                return bad_request(
                    'You don\'t have permission to update these forms.')

        response = HttpResponse(content_type='text/csv')
        writer = csv.writer(response)
        writer.writerow([
            'component number', 'question number', 'benchmark/epi?', 'answer',
            'notes'
        ])

        form_data = (FormData.objects.select_related(
            'form', 'form__overview', 'question', 'question__component',
            'selected_answer').filter(form__overview__id=ov.id).order_by(
                'question__component__component_num', 'question__question_num',
                'question__is_epi', 'question__is_benchmark'))
        for fd in form_data:
            bench_epi = ''
            if fd.question.is_benchmark:
                bench_epi = 'benchmark'
            if fd.question.is_epi:
                bench_epi = 'epi'
            writer.writerow([
                fd.question.component.component_num, fd.question.question_num,
                bench_epi,
                fd.selected_answer.text if fd.selected_answer else '', fd.notes
            ])

        response[
            'Content-Disposition'] = f'attachment; filename=assessment_{ov.id}.csv'

        return response
예제 #2
0
    def post(self, request):
        workplan_id = request.data.get('id', None)
        if workplan_id is None:
            return bad_request('Need to provide WorkPlan ID.')

        try:
            WorkPlan.objects.filter(id=workplan_id).delete()
        except Exception:
            return bad_request('Could not delete PER WorkPlan.')

        return JsonResponse({'status': 'ok'})
예제 #3
0
    def post(self, request):
        required_fields = ('country_id', 'user_id')
        missing_fields = [
            field for field in required_fields if field not in request.data
        ]
        if missing_fields:
            return bad_request('Could not complete request. Please submit %s' %
                               ', '.join(missing_fields))

        question_id = request.data.get('question_id', None)
        if ' ' in question_id:
            return bad_request('Question ID can not contain spaces.')

        prioritization = request.data.get('prioritization', None)
        components = request.data.get('components', None)
        benchmark = request.data.get('benchmark', None)
        actions = request.data.get('actions', None)
        comments = request.data.get('comments', None)
        timeline = request.data.get('timeline', get_now_str())
        status = request.data.get('status', None)
        support_required = request.data.get('support_required', None)
        focal_point = request.data.get('focal_point', None)
        country_id = request.data.get('country_id', None)
        code = request.data.get('code', None)
        user_id = request.data.get('user_id', None)

        try:
            WorkPlan.objects.create(prioritization=prioritization,
                                    components=components,
                                    benchmark=benchmark,
                                    actions=actions,
                                    comments=comments,
                                    timeline=timeline,
                                    status=status,
                                    support_required=support_required,
                                    focal_point=focal_point,
                                    country_id=country_id,
                                    code=code,
                                    question_id=question_id,
                                    user_id=user_id)
        except Exception:
            return bad_request('Could not insert PER WorkPlan.')

        return JsonResponse({'status': 'ok'})
예제 #4
0
    def post(self, request):
        user = request.user
        overview_id = request.data.get('id', None)
        if overview_id is None:
            return bad_request('Need to provide Overview ID.')

        try:
            ov = Overview.objects.filter(id=overview_id,
                                         user=user,
                                         is_finalized=False).first()
            if ov:
                ov.delete()
            else:
                return bad_request(
                    f'Overview with the ID: {overview_id} is finalized or not created by your user.'
                )
        except Exception:
            return bad_request('Could not delete PER Overview.')

        return JsonResponse({'status': 'ok'})
예제 #5
0
    def handle_post(self, request, *args, **kwargs):
        body = json.loads(request.body.decode('utf-8'))

        required_fields = [
            'email',
            'username',
            'password',
            'country',
            'organizationType',
            'organization',
            'firstname',
            'lastname',
        ]

        missing_fields = [
            field for field in required_fields if field not in body
        ]
        if len(missing_fields):
            return bad_request('Could not complete request. Please submit %s' %
                               ', '.join(missing_fields))

        is_staff = is_valid_domain(body['email'])
        admins = True if is_staff else get_valid_admins(body['contact'])
        if not admins:
            return bad_request(
                'Non-IFRC users must submit two valid admin emails.')
        if User.objects.filter(email=body['email']).count() > 0:
            return bad_request(
                'A user with that email address already exists.')
        if User.objects.filter(username=body['username']).count() > 0:
            return bad_request(
                'That username is taken, please choose a different one.')

        try:
            user = create_active_user(body)
        except:
            return bad_request('Could not create user.')

        try:
            # Note, this also sets the user's active status to False
            set_user_profile_inactive(user, body)
        except:
            User.objects.filter(username=body['username']).delete()
            return bad_request('Could not create user profile.')

        pending = Pending.objects.create(user=user,
                                         token=get_random_string(length=32))
        if not is_staff:
            pending.admin_contact_1 = admins[0]
            pending.admin_contact_2 = admins[1]
            pending.admin_token_1 = get_random_string(length=32)
            pending.admin_token_2 = get_random_string(length=32)
            pending.admin_1_validated = False
            pending.admin_2_did_validation = False

        pending.save()

        email_context = {
            'confirmation_link':
            '%s/verify_email/?token=%s&user=%s' % (
                settings.BASE_URL,
                pending.token,
                body['username'],
            )
        }

        # if validated email accounts get a different message
        if is_staff:
            template = 'email/registration/verify-staff-email.html'
        else:
            template = 'email/registration/verify-outside-email.html'

        send_notification('Validate your account', [body['email']],
                          render_to_string(template, email_context))

        return JsonResponse({'status': 'ok'})
예제 #6
0
    def post(self, request):
        required_fields = (
            'email',
            # 'username',
            'password',
            'country',
            'organizationType',
            'organization',
            'firstname',
            'lastname',
        )

        missing_fields = [
            field for field in required_fields if field not in request.data
        ]
        if missing_fields:
            return bad_request('Could not complete request. Please submit %s' %
                               ', '.join(missing_fields))

        email = request.data.get('email', None)
        # Since username is a required field we still need to fill it in
        # but now only email is being used for new registrations
        username = request.data.get('email', None)
        password = request.data.get('password', None)
        firstname = request.data.get('firstname', None)
        lastname = request.data.get('lastname', None)
        country = request.data.get('country', None)
        city = request.data.get('city', None)
        organization_type = request.data.get('organizationType', None)
        organization = request.data.get('organization', None)
        department = request.data.get('department', None)
        position = request.data.get('position', None)
        phone_number = request.data.get('phoneNumber', None)
        justification = request.data.get('justification', None)

        is_staff = is_valid_domain(email)

        if User.objects.filter(email__iexact=email).exists():
            return bad_request(
                'A user with that email address already exists.')
        if User.objects.filter(username__iexact=username).exists():
            return bad_request(
                'That username is taken, please choose a different one.')
        if ' ' in username:
            return bad_request(
                'Username can not contain spaces, please choose a different one.'
            )

        # Create the User object
        try:
            user = create_inactive_user(username, firstname, lastname, email,
                                        password)
        except Exception:
            return bad_request('Could not create user.')

        # Set the User Profile properties
        try:
            set_user_profile(user, country, organization_type, organization,
                             city, department, position, phone_number)
        except Exception:
            User.objects.filter(username=username).delete()
            return bad_request('Could not create user profile.')

        pending = Pending.objects.create(user=user,
                                         justification=justification,
                                         token=get_random_string(length=32))
        if not is_staff:
            pending.admin_token_1 = get_random_string(length=32)

        pending.save()

        email_context = {
            'confirmation_link':
            'https://%s/verify_email/?token=%s&user=%s' % (
                settings.BASE_URL,  # on PROD it should point to goadmin...
                pending.token,
                username,
            )
        }

        # if validated email accounts get a different message
        if is_staff:
            template = 'email/registration/verify-staff-email.html'
        else:
            template = 'email/registration/verify-outside-email.html'

        send_notification('Validate your account', [email],
                          render_to_string(template, email_context),
                          'Validate account - ' + username)

        return JsonResponse({'status': 'ok'})
예제 #7
0
    def post(self, request):
        # Get the PER Form by ID
        form_id = request.data.get('id', None)
        if form_id is None:
            return bad_request(
                'Could not complete request. Please include \'id\' in the request.'
            )
        form = Form.objects.filter(pk=form_id).first()
        if form is None:
            return bad_request('Could not find PER form record.')

        comment = request.data.get('comment', None)
        questions = request.data.get('questions', None)

        if questions is None:
            return bad_request('Questions are missing from the request.')

        # Check if the User has permissions to update
        if not request.user.is_superuser \
                and not request.user.has_perm('api.ifrc_admin') \
                and not request.user.has_perm('api.per_core_admin'):
            countries, regions = self.get_request_user_regions(request)
            # These need to be strings
            if form.overview:
                ov_country = f'{form.overview.country.id}' or ''
                ov_region = f'{form.overview.country.region.id}' if form.overview.country.region else ''

                if ov_country not in countries and ov_region not in regions:
                    return bad_request(
                        'You don\'t have permission to update these forms.')
            else:
                return bad_request(
                    'You don\'t have permission to update these forms.')

        # Update the Form
        try:
            form.comment = comment
            form.save()
        except Exception:
            logger.error('Could not change PER form record.', exc_info=True)
            return bad_request('Could not change PER form record.')

        # Update the FormData
        try:
            form_data_in_db = FormData.objects.filter(form_id=form_id)

            with transaction.atomic():
                for qid in questions:
                    form_data = form_data_in_db.filter(question_id=qid).first()
                    if not form_data:
                        # Probably newly added question
                        try:
                            # TODO: look up bulk_save, (validation)
                            form_data = FormData.objects.create(
                                form=form,
                                question_id=qid,
                                selected_answer_id=questions[qid]
                                ['selected_answer'],
                                notes=questions[qid]['notes']
                                # TODO: just as in the CreatePerForm
                            )
                        except Exception:
                            logger.error('Could not insert PER form record.',
                                         exc_info=True)
                            return bad_request(
                                'Could not insert PER form record.')
                    else:
                        if form_data.selected_answer_id != questions[qid]['selected_answer'] \
                                or form_data.notes != questions[qid]['notes']:
                            form_data.selected_answer_id = questions[qid][
                                'selected_answer'] or form_data.selected_answer_id
                            form_data.notes = questions[qid][
                                'notes'] or form_data.notes
                            form_data.save()
        except Exception:
            logger.error('Could not change PER formdata record.',
                         exc_info=True)
            return bad_request('Could not change PER formdata record.')

        return JsonResponse({'status': 'ok', 'overview_id': form.overview_id})
예제 #8
0
    def post(self, request):
        id = request.data.get('id', None)
        if id is None:
            return bad_request(
                'Could not complete request. Please submit include id')
        ov = Overview.objects.filter(pk=id).first()
        if ov is None:
            return bad_request('Could not find PER Overview form record.')
        required_fields = ('date_of_assessment', 'type_of_assessment',
                           'country_id', 'user_id')
        missing_fields = [
            field for field in required_fields
            if field not in request.data or not request.data[field]
        ]
        if missing_fields:
            return bad_request('Could not complete request. Please submit %s' %
                               ', '.join(missing_fields))

        # Fool-proofing so one couldn't change the Overview data even through
        # plain API requests, if it's finalized already
        if ov.is_finalized:
            return bad_request(
                'Form is already finalized. Can\'t save any changes to it.')

        assessment_number = request.data.get('assessment_number', None)
        branches_involved = request.data.get('branches_involved', None)
        country_id = request.data.get('country_id', None)
        date_of_assessment = request.data.get('date_of_assessment', None)
        date_of_mid_term_review = request.data.get('date_of_mid_term_review',
                                                   None)
        date_of_next_asmt = request.data.get('date_of_next_asmt', None)
        facilitator_name = request.data.get('facilitator_name', None)
        facilitator_email = request.data.get('facilitator_email', None)
        facilitator_phone = request.data.get('facilitator_phone', None)
        facilitator_contact = request.data.get('facilitator_contact', None)
        is_epi = request.data.get('is_epi', False)
        is_finalized = request.data.get('is_finalized', False)
        method_asmt_used = request.data.get('method_asmt_used', None)
        ns_focal_point_name = request.data.get('ns_focal_point_name', None)
        ns_focal_point_email = request.data.get('ns_focal_point_email', None)
        ns_focal_point_phone = request.data.get('ns_focal_point_phone', None)
        other_consideration = request.data.get('other_consideration', None)
        partner_focal_point_name = request.data.get('partner_focal_point_name',
                                                    None)
        partner_focal_point_email = request.data.get(
            'partner_focal_point_email', None)
        partner_focal_point_phone = request.data.get(
            'partner_focal_point_phone', None)
        partner_focal_point_organization = request.data.get(
            'partner_focal_point_organization', None)
        type_of_assessment_id = request.data.get('type_of_assessment', None)
        user_id = request.data.get('user_id', None)

        # Check if the User has permissions to update
        if not request.user.is_superuser \
                and not request.user.has_perm('api.ifrc_admin') \
                and not request.user.has_perm('api.per_core_admin'):
            countries, regions = self.get_request_user_regions(request)
            country = Country.objects.filter(
                id=country_id).first() if country_id else None
            if country:
                # These need to be strings
                country_id_string = f'{country.id}' or ''
                region_id_string = f'{country.region.id}' if country.region else ''

                if country_id_string not in countries and region_id_string not in regions:
                    return bad_request(
                        'You don\'t have permission to update the Overview for the selected Country.'
                    )
            else:
                return bad_request(
                    'You don\'t have permission to update the Overview for the selected Country.'
                )

        # prev_overview = None
        # if ov.country_id != country_id:
        #     prev_overview = Overview.objects.filter(country_id=country_id).order_by('-created_at').first()

        try:
            # if prev_overview:
            #     ov.assessment_number = prev_overview.assessment_number + 1
            ov.assessment_number = assessment_number
            ov.branches_involved = branches_involved
            ov.country_id = country_id
            ov.date_of_assessment = date_of_assessment
            ov.date_of_mid_term_review = date_of_mid_term_review
            ov.date_of_next_asmt = date_of_next_asmt
            ov.facilitator_name = facilitator_name
            ov.facilitator_email = facilitator_email
            ov.facilitator_phone = facilitator_phone
            ov.facilitator_contact = facilitator_contact
            ov.is_epi = is_epi
            ov.is_finalized = is_finalized
            ov.method_asmt_used = method_asmt_used
            ov.ns_focal_point_name = ns_focal_point_name
            ov.ns_focal_point_email = ns_focal_point_email
            ov.ns_focal_point_phone = ns_focal_point_phone
            ov.other_consideration = other_consideration
            ov.partner_focal_point_name = partner_focal_point_name
            ov.partner_focal_point_email = partner_focal_point_email
            ov.partner_focal_point_phone = partner_focal_point_phone
            ov.partner_focal_point_organization = partner_focal_point_organization
            ov.type_of_assessment_id = type_of_assessment_id
            ov.user_id = user_id
            ov.save()
        except Exception:
            logger.error('Could not change PER Overview form record.',
                         exc_info=True)
            return bad_request('Could not change PER Overview form record.')

        return JsonResponse({'status': 'ok', 'is_finalized': ov.is_finalized})
예제 #9
0
    def post(self, request):
        required_fields = ('date_of_assessment', 'type_of_assessment',
                           'country_id', 'user_id')
        missing_fields = [
            field for field in required_fields
            if field not in request.data or not request.data[field]
        ]
        if missing_fields:
            return bad_request('Could not complete request. Please submit %s' %
                               ', '.join(missing_fields))

        assessment_number = request.data.get('assessment_number', None)
        branches_involved = request.data.get('branches_involved', None)
        country_id = request.data.get('country_id', None)
        date_of_assessment = request.data.get('date_of_assessment', None)
        date_of_mid_term_review = request.data.get('date_of_mid_term_review',
                                                   None)
        date_of_next_asmt = request.data.get('date_of_next_asmt', None)
        facilitator_name = request.data.get('facilitator_name', None)
        facilitator_email = request.data.get('facilitator_email', None)
        facilitator_phone = request.data.get('facilitator_phone', None)
        facilitator_contact = request.data.get('facilitator_contact', None)
        is_epi = request.data.get('is_epi', False)
        method_asmt_used = request.data.get('method_asmt_used', None)
        ns_focal_point_name = request.data.get('ns_focal_point_name', None)
        ns_focal_point_email = request.data.get('ns_focal_point_email', None)
        ns_focal_point_phone = request.data.get('ns_focal_point_phone', None)
        other_consideration = request.data.get('other_consideration', None)
        partner_focal_point_name = request.data.get('partner_focal_point_name',
                                                    None)
        partner_focal_point_email = request.data.get(
            'partner_focal_point_email', None)
        partner_focal_point_phone = request.data.get(
            'partner_focal_point_phone', None)
        partner_focal_point_organization = request.data.get(
            'partner_focal_point_organization', None)
        type_of_assessment_id = request.data.get('type_of_assessment', None)
        user_id = request.data.get('user_id', None)

        # Check if the User has permissions to create
        if not request.user.is_superuser \
                and not request.user.has_perm('api.ifrc_admin') \
                and not request.user.has_perm('api.per_core_admin'):
            countries, regions = self.get_request_user_regions(request)
            country = Country.objects.filter(
                id=country_id).first() if country_id else None
            if country:
                # These need to be strings
                country_id_string = f'{country.id}' or ''
                region_id_string = f'{country.region.id}' if country.region else ''

                if country_id_string not in countries and region_id_string not in regions:
                    return bad_request(
                        'You don\'t have permission to create an Overview for the selected Country.'
                    )
            else:
                return bad_request(
                    'You don\'t have permission to create an Overview for the selected Country.'
                )

        # prev_overview = Overview.objects.filter(country_id=country_id).order_by('-created_at').first()

        try:
            overview = Overview.objects.create(
                # assessment_number=prev_overview.assessment_number + 1 if prev_overview else 1,
                assessment_number=assessment_number,
                branches_involved=branches_involved,
                country_id=country_id,
                date_of_assessment=date_of_assessment or None,
                date_of_mid_term_review=date_of_mid_term_review or None,
                date_of_next_asmt=date_of_next_asmt or None,
                facilitator_name=facilitator_name,
                facilitator_email=facilitator_email,
                facilitator_phone=facilitator_phone,
                facilitator_contact=facilitator_contact,
                is_epi=is_epi,
                is_finalized=
                False,  # We never want to finalize an Overview by start
                method_asmt_used=method_asmt_used,
                ns_focal_point_name=ns_focal_point_name,
                ns_focal_point_email=ns_focal_point_email,
                ns_focal_point_phone=ns_focal_point_phone,
                other_consideration=other_consideration,
                partner_focal_point_name=partner_focal_point_name,
                partner_focal_point_email=partner_focal_point_email,
                partner_focal_point_phone=partner_focal_point_phone,
                partner_focal_point_organization=
                partner_focal_point_organization,
                type_of_assessment_id=type_of_assessment_id,
                user_id=user_id)

            # For each Area create a Form record (Overview is the parent)
            areas = FormArea.objects.values_list('id', flat=True)
            form_data_to_create = []

            with transaction.atomic():
                for aid in areas:
                    form = Form.objects.create(area_id=aid,
                                               user_id=user_id,
                                               overview_id=overview.id)

                    # For each Question create a FormData record (Form is the parent)
                    questions = FormQuestion.objects.filter(
                        component__area_id=aid).values_list('id', flat=True)
                    for qid in questions:
                        form_data_to_create.append(
                            FormData(form=form, question_id=qid))
                FormData.objects.bulk_create(form_data_to_create)
        except Exception:
            return bad_request('Could not create PER Assessment.')

        return JsonResponse({'status': 'ok', 'overview_id': overview.id})
예제 #10
0
    def post(self, request):
        forms = request.data.get('forms', None)
        forms_data = request.data.get('forms_data', None)

        if not forms or not forms_data:
            return bad_request(
                'Could not complete request. \'forms\' or \'forms_data\' are missing.'
            )

        # Check if the User has permissions to update
        if not request.user.is_superuser \
                and not request.user.has_perm('api.ifrc_admin') \
                and not request.user.has_perm('api.per_core_admin'):
            countries, regions = self.get_request_user_regions(request)
            overview_id = forms[list(forms.keys())[0]]['overview']['id']
            ov = Overview.objects.filter(id=overview_id).first()

            if ov:
                # These need to be strings
                ov_country = f'{ov.country.id}' or ''
                ov_region = f'{ov.country.region.id}' if ov.country.region else ''

                if ov_country not in countries and ov_region not in regions:
                    return bad_request(
                        'You don\'t have permission to update these forms.')
            else:
                return bad_request(
                    'You don\'t have permission to update these forms.')

        # Update the Forms
        try:
            with transaction.atomic():
                for form_id in forms:
                    form = Form.objects.filter(
                        pk=forms[form_id].get('id')).first()
                    if form:
                        form.comment = forms[form_id].get('comment')
                        form.save()
        except Exception:
            logger.error('Could not update PER Forms.', exc_info=True)
            return bad_request('Could not update PER Forms.')

        # Update the FormsData
        try:
            with transaction.atomic():
                for fid in forms_data:
                    # All FormData related to the Form
                    db_form_data = FormData.objects.filter(form_id=fid)
                    form_data_to_update = []
                    for qid in forms_data[fid]:
                        db_fd = db_form_data.filter(question_id=qid).first()
                        selected_answer = forms_data[fid][qid].get(
                            'selected_answer', None)
                        notes = forms_data[fid][qid].get('notes', None)

                        if selected_answer:
                            selected_answer = int(selected_answer)

                        if not db_fd:
                            # Missing question
                            FormData.objects.create(
                                form_id=fid,
                                question_id=qid,
                                selected_answer_id=selected_answer,
                                notes=notes)
                        else:
                            if db_fd.selected_answer_id == selected_answer \
                                    and db_fd.notes == notes:
                                continue
                            db_fd.selected_answer_id = selected_answer
                            db_fd.notes = notes
                            form_data_to_update.append(db_fd)
                    FormData.objects.bulk_update(
                        form_data_to_update, ['selected_answer_id', 'notes'])
        except Exception:
            logger.error('Could not update PER FormsData.', exc_info=True)
            return bad_request('Could not update PER FormsData.')

        return JsonResponse({'status': 'ok'})