Пример #1
0
def review_enrollment_type_for_user(request, user_id):
    user = get_object_or_404(users.models.User, id=user_id)
    entrance_step = get_object_or_404(
        models.SelectEnrollmentTypeEntranceStep,
        school=request.school,
    )
    selected_enrollment_type = get_object_or_404(
        models.SelectedEnrollmentType,
        user=user,
        step=entrance_step,
        enrollment_type__needs_moderation=True,
    )

    # TODO(artemtab): add locking
    # locked_by_me = True
    # with transaction.atomic():

    base_entrance_level = upgrades.get_base_entrance_level(
        request.school, user)
    level_upgrades = models.EntranceLevelUpgrade.objects.filter(
        upgraded_to__school=request.school, user=user)
    topics_entrance_level = upgrades.get_topics_entrance_level(
        request.school, user)

    if request.method == 'POST':
        pass
        # Handle review
    else:
        pass
        # Initialize review form

    add_checking_comment_form = forms.AddCheckingCommentForm()
    checking_comments = models.CheckingComment.objects.filter(
        school=request.school, user=user)

    # TODO(artemtab): better ordering, now it's not exactly chronological
    participations = (user.school_participations.order_by(
        '-school__year', '-school__name'))

    return render(
        request,
        'entrance/staff/enrollment_review_user.html',
        {
            'user_for_review': user,
            'participations': participations,
            'base_entrance_level': base_entrance_level,
            'level_upgrades': level_upgrades,
            'topics_entrance_level': topics_entrance_level,
            'selected_enrollment_type': selected_enrollment_type,
            'review_info': entrance_step.review_info,
            # 'locked_by_me': locked_by_me,
            'add_checking_comment_form': add_checking_comment_form,
            'checking_comments': checking_comments,
        })
Пример #2
0
    def get_enrolling_columns(self, request, enrollees):
        columns = []

        columns.append(
            LinkExcelColumn(
                name='id',
                cell_width=5,
                data=[user.id for user in enrollees],
                data_urls=[
                    request.build_absolute_uri(
                        django.urls.reverse('school:entrance:enrolling_user',
                                            args=(request.school.short_name,
                                                  user.id)))
                    for user in enrollees
                ],
            ))

        columns.append(
            LinkExcelColumn(
                name='Фамилия',
                data=[user.profile.last_name for user in enrollees],
                data_urls=[
                    getattr(user.profile.poldnev_person, 'url', '')
                    for user in enrollees
                ],
            ))

        columns.append(
            PlainExcelColumn(
                name='Имя',
                data=[user.profile.first_name for user in enrollees],
            ))

        columns.append(
            PlainExcelColumn(
                name='Отчество',
                data=[user.profile.middle_name for user in enrollees],
            ))

        columns.append(
            PlainExcelColumn(
                name='Пол',
                data=[
                    'жм'[user.profile.sex == users.models.UserProfile.Sex.MALE]
                    for user in enrollees
                ],
            ))

        columns.append(
            PlainExcelColumn(
                name='Город',
                data=[user.profile.city for user in enrollees],
            ))

        columns.append(
            PlainExcelColumn(
                name='Класс',
                cell_width=7,
                data=[user.profile.get_class() for user in enrollees],
            ))

        columns.append(
            PlainExcelColumn(
                name='Школа',
                data=[user.profile.school_name for user in enrollees],
            ))

        enrollment_type_step = (
            models.SelectEnrollmentTypeEntranceStep.objects.filter(
                school=request.school).first())
        if enrollment_type_step is not None:
            columns.append(
                PlainExcelColumn(name='Основание для поступления',
                                 data=[
                                     self.get_enrollment_type_for_user(
                                         enrollment_type_step, user)
                                     for user in enrollees
                                 ]))
        elif self.question_exists(request.school, 'entrance_reason'):
            columns.append(
                PlainExcelColumn(
                    name='Основание для поступления',
                    data=self.get_choice_question_for_users(
                        request.school, enrollees, 'entrance_reason'),
                ))

        # TODO(artemtab): create ScoolParticipant entries for all the users
        #                 and use them instead
        if self.question_exists(request.school, 'previous_parallels'):
            columns.append(
                PlainExcelColumn(
                    name='История',
                    data=self.get_history_for_users(request.school, enrollees),
                ))

        columns.append(
            PlainExcelColumn(
                name='История (poldnev.ru)',
                data=self.get_poldnev_history_for_users(enrollees),
            ))

        previous_school = schools.models.School.objects.get(short_name='2017')
        columns.append(
            PlainExcelColumn(
                name='Параллель',
                data=self.get_real_parallel_for_users(enrollees,
                                                      previous_school),
            ))

        if self.question_exists(request.school, 'main_langauge'):
            columns.append(
                PlainExcelColumn(
                    name='Язык (основной)',
                    data=self.get_text_question_for_users(
                        request.school, enrollees, 'main_langauge'),
                ))

        if self.question_exists(request.school, 'travel_pasport'):
            columns.append(
                PlainExcelColumn(
                    name='Загран',
                    data=self.get_choice_question_for_users(
                        request.school, enrollees, 'travel_pasport'),
                ))

        if self.question_exists(request.school, 'visa'):
            columns.append(
                PlainExcelColumn(
                    name='Виза',
                    data=self.get_choice_question_for_users(
                        request.school, enrollees, 'visa'),
                ))

        if self.question_exists(request.school, 'visa_expiration'):
            columns.append(
                PlainExcelColumn(
                    name='Срок действия визы',
                    data=self.get_text_question_for_users(
                        request.school, enrollees, 'visa_expiration'),
                ))

        if self.question_exists(request.school, 'fingerprints'):
            columns.append(
                PlainExcelColumn(
                    name='Отпечатки',
                    data=self.get_choice_question_for_users(
                        request.school, enrollees, 'fingerprints'),
                ))

        if hasattr(request.school, 'entrance_exam'):
            columns.append(
                PlainExcelColumn(
                    name='Языки ОК\'ов',
                    data=self.get_ok_languages_for_users(
                        request.school, enrollees),
                ))

            columns.append(
                LinkExcelColumn(name='ТА',
                                data=[
                                    upgrades.get_base_entrance_level(
                                        request.school, user).name
                                    for user in enrollees
                                ],
                                data_urls=[
                                    request.build_absolute_uri(
                                        reverse('school:entrance:user_topics',
                                                kwargs={
                                                    'school_name':
                                                    request.school.short_name,
                                                    'user_id': user.id,
                                                })) for user in enrollees
                                ]))

            columns.append(
                PlainExcelColumn(
                    name='Уровень',
                    data=self.get_entrance_level_for_users(
                        request.school, enrollees),
                ))

            columns.append(
                PlainExcelColumn(
                    name='Апгрейд',
                    data=self.get_max_upgrade_for_users(
                        request.school, enrollees),
                ))

            columns.append(
                PlainExcelColumn(
                    name='Группы проверки',
                    data=self.get_checking_groups_for_users(
                        request.school, enrollees),
                ))

            file_tasks = (models.FileEntranceExamTask.objects.annotate(
                entrance_levels_count=Count('entrance_levels')).filter(
                    exam__school=request.school,
                    entrance_levels_count__gt=0).order_by('order'))
            if file_tasks.exists():
                subcolumns = [
                    PlainExcelColumn(
                        name='{}: {}'.format(task.id, task.title),
                        cell_width=5,
                        data=self.get_file_task_score_for_users(
                            task, enrollees),
                        comments=self.get_file_task_comments_for_users(
                            task, enrollees),
                    ) for task in file_tasks
                ]
                columns.append(
                    ExcelMultiColumn(name='Теория', subcolumns=subcolumns))

            program_tasks = (models.ProgramEntranceExamTask.objects.annotate(
                entrance_levels_count=Count('entrance_levels')).filter(
                    exam__school=request.school,
                    entrance_levels_count__gt=0).order_by('order'))
            if program_tasks.exists():
                subcolumns = [
                    PlainExcelColumn(
                        name='{}: {}'.format(task.id, task.title),
                        cell_width=5,
                        data=self.get_program_task_score_for_users(
                            task, enrollees)) for task in program_tasks
                ]
                columns.append(
                    ExcelMultiColumn(name='Практика', subcolumns=subcolumns))

            # TODO(artemtab): set of metrics to show shouldn't be hardcoded, but
            #     defined for each school/exam somewhere in the database.
            metrics = (models.EntranceUserMetric.objects.filter(
                exam__school=request.school,
                name__in=["C'", "C", "B'", "B", "A'", "A"]).order_by('name'))
            if metrics.exists():
                subcolumns = [
                    PlainExcelColumn(name=metric.name,
                                     cell_width=5,
                                     data=list(
                                         metric.values_for_users(enrollees)))
                    for metric in metrics
                ]
                columns.append(
                    ExcelMultiColumn(name='Баллы', subcolumns=subcolumns))

            auto_parallels = [
                self.get_auto_parallel_for_user(request.school, user)
                for user in enrollees
            ]
            columns.append(
                LinkExcelColumn(
                    name='Авто',
                    cell_width=5,
                    data=auto_parallels,
                    data_urls=[
                        request.build_absolute_uri(
                            reverse(
                                'school:entrance:enrollment_type_review_user',
                                kwargs={
                                    'school_name': request.school.short_name,
                                    'user_id': user.id,
                                })) if parallel else ''
                        for user, parallel in zip(enrollees, auto_parallels)
                    ]))

        # 2018
        if self.question_exists(request.school, 'want_to_session_2'):
            answers = self.get_choice_question_for_users(
                request.school, enrollees, 'want_to_session_2')
            answer_mapping = {
                "Хочу в августовскую, но могу и в июльскую": ("Август", "Да"),
                "Хочу в июльскую, но могу и в августовскую": ("Июль", "Да"),
                "Только в августовскую («Лаагна», Эстония, с 31 июля по 20 августа)":
                ("Август", "Нет"),
                "Только в июльскую («Берендеевы поляны», с 4 по 24 июля)":
                ("Июль", "Нет"),
                "": ("", ""),
            }
            columns.append(
                PlainExcelColumn(
                    name='Смена',
                    data=[answer_mapping[answer][0] for answer in answers],
                ))
            columns.append(
                PlainExcelColumn(
                    name='Другая смена',
                    data=[answer_mapping[answer][1] for answer in answers],
                ))

        # 2016 & 2017
        if self.question_exists(request.school, 'want_to_session'):
            columns.append(
                PlainExcelColumn(
                    name='Смена',
                    data=self.get_choice_question_for_users(
                        request.school, enrollees, 'want_to_session'),
                ))

        if self.question_exists(request.school, 'other_session'):
            columns.append(
                PlainExcelColumn(
                    name='Другая смена',
                    data=self.get_other_session_for_users(
                        request.school, enrollees),
                ))

        entrance_status_by_user_id = self.get_entrance_status_by_user_id(
            request.school, enrollees)
        status_repr = {
            models.EntranceStatus.Status.NOT_PARTICIPATED: '!',
            models.EntranceStatus.Status.AUTO_REJECTED: 'ТО',
            models.EntranceStatus.Status.NOT_ENROLLED: 'X',
            models.EntranceStatus.Status.ENROLLED: '+',
            models.EntranceStatus.Status.PARTICIPATING: '',
        }
        columns.append(
            ExcelMultiColumn(
                name='Итог',
                subcolumns=[
                    PlainExcelColumn(
                        name='Параллель',
                        cell_width=8,
                        data=[
                            getattr(
                                entrance_status_by_user_id[user.id].parallel,
                                'name', '') for user in enrollees
                        ],
                    ),
                    PlainExcelColumn(
                        name='Смена',
                        cell_width=7,
                        data=[
                            getattr(
                                entrance_status_by_user_id[user.id].session,
                                'name', '') for user in enrollees
                        ],
                    ),
                    PlainExcelColumn(
                        name='Статус',
                        cell_width=5,
                        data=[
                            status_repr.get(
                                entrance_status_by_user_id[user.id].status)
                            for user in enrollees
                        ],
                    ),
                    PlainExcelColumn(
                        name='Комментарий',
                        data=[
                            entrance_status_by_user_id[user.id].public_comment
                            for user in enrollees
                        ],
                    ),
                    PlainExcelColumn(
                        name='Приватный комментарий',
                        data=[
                            entrance_status_by_user_id[user.id].private_comment
                            for user in enrollees
                        ],
                    ),
                ],
            ))

        # TODO(artemtab): we need some way to define for each school the
        #     previous ones in the database.
        columns.append(
            ExcelMultiColumn(
                name='',
                subcolumns=[
                    PlainExcelColumn(
                        name='Оценки 2017.Зима',
                        cell_width=7,
                        data=self.get_marks_for_users('2017.winter',
                                                      enrollees),
                    ),
                    PlainExcelColumn(
                        name='Оценки 2017',
                        cell_width=7,
                        data=self.get_marks_for_users('2017', enrollees),
                    ),
                ],
            ))

        columns.append(
            PlainExcelColumn(name='Комментарии из системы',
                             data=self.get_checking_comments_for_users(
                                 request.school, enrollees)))

        columns.append(
            PlainExcelColumn(
                name='Комментарии 2017',
                cell_width=30,
                data=self.get_study_comments_for_users('2017', enrollees),
            ))

        if (self.question_exists(request.school, 'informatics_olympiads')
                and self.question_exists(request.school, 'math_olympiads')):
            columns.append(
                ExcelMultiColumn(
                    name='Олимпиады',
                    subcolumns=[
                        PlainExcelColumn(
                            name='Информатика',
                            cell_width=30,
                            data=self.get_text_question_for_users(
                                request.school, enrollees,
                                'informatics_olympiads'),
                        ),
                        PlainExcelColumn(
                            name='Математика',
                            cell_width=30,
                            data=self.get_text_question_for_users(
                                request.school, enrollees, 'math_olympiads'),
                        ),
                    ],
                ))

        return columns
Пример #3
0
 def get_entrance_level_for_users(self, school, enrollees):
     return [
         upgrades.get_base_entrance_level(school, user).name
         for user in enrollees
     ]
Пример #4
0
def check_users_task(request, task_id, user_id, group_name=None):
    _remove_old_checking_locks()

    if group_name is not None:
        checking_group = get_object_or_404(models.CheckingGroup,
                                           school=request.school,
                                           short_name=group_name)
    else:
        checking_group = None

    user = get_object_or_404(users.models.User, id=user_id)
    task = get_object_or_404(models.FileEntranceExamTask, id=task_id)
    task.mark_field_id = (
        forms.FileEntranceExamTasksMarkForm.FIELD_ID_TEMPLATE % task.id)
    task.comment_field_id = (
        forms.FileEntranceExamTasksMarkForm.COMMENT_ID_TEMPLATE % task.id)

    if checking_group is None:
        group_user_ids = list({
            user_id
            for g in request.school.entrance_checking_groups.all()
            for user_id in g.group.user_ids
        })
    else:
        # Select users from group
        group_user_ids = checking_group.group.user_ids

    task.total_solutions_count = users.models.User.objects.filter(
        id__in=nested_query_list(group_user_ids),
        entrance_exam_solutions__task=task).distinct().count()
    task.checked_solutions_count = users.models.User.objects.filter(
        id__in=nested_query_list(group_user_ids),
        entrance_exam_solutions__task=task,
        entrance_exam_solutions__checks__isnull=False).distinct().count()

    locked_by_me = True
    with transaction.atomic():
        lock = models.CheckingLock.objects.filter(
            user=user,
            task=task,
        ).first()
        if lock is None:
            lock = models.CheckingLock.objects.create(
                user_id=user_id,
                task_id=task_id,
                locked_by=request.user,
            )
        else:
            locked_by_me = lock.locked_by_id == request.user.id

    base_entrance_level = upgrades.get_base_entrance_level(
        request.school, user)
    level_upgrades = models.EntranceLevelUpgrade.objects.filter(
        upgraded_to__school=request.school, user=user)

    solutions = task.solutions.filter(user=user).order_by('-created_at')
    if not solutions.exists():
        lock.delete()
        messages.add_message(request, messages.INFO,
                             'Этот пользователь не решал выбранную задачу')
        if checking_group is None:
            return redirect('school:entrance:enrolling_user',
                            school_name=request.school.short_name,
                            user_id=user.id)
        return redirect('school:entrance:check_task',
                        school_name=request.school.short_name,
                        group_name=group_name,
                        task_id=task.id)

    solutions = list(solutions)
    last_solution = solutions[0]

    if request.method == 'POST':
        if 'refuse' in request.POST:
            lock.delete()
            return redirect(
                'school:entrance:check',
                school_name=request.school.short_name,
            )

        mark_form = forms.FileEntranceExamTasksMarkForm([task],
                                                        request.POST,
                                                        with_comment=True)
        if mark_form.is_valid():
            score = mark_form.cleaned_data[task.mark_field_id]
            comment = mark_form.cleaned_data[task.comment_field_id]
            models.CheckedSolution.objects.create(solution=last_solution,
                                                  checked_by=request.user,
                                                  score=score,
                                                  comment=comment)
            lock.delete()

            messages.add_message(
                request, messages.INFO,
                'Баллы пользователю %s успешно сохранены' %
                (user.get_full_name(), ))

            if checking_group is None:
                return redirect('school:entrance:enrolling_user',
                                school_name=request.school.short_name,
                                user_id=user.id)

            return redirect('school:entrance:check_task',
                            school_name=request.school.short_name,
                            group_name=group_name,
                            task_id=task.id)
    else:
        mark_form = forms.FileEntranceExamTasksMarkForm([task],
                                                        with_comment=True)

    checks = list(
        models.CheckedSolution.objects.filter(
            solution=last_solution).order_by('-created_at'))
    last_mark = None if len(checks) == 0 else checks[0].score
    if last_mark is not None:
        mark_form.set_initial_mark(task.id, last_mark)

    checking_comments = models.CheckingComment.objects.filter(
        school=request.school, user=user)

    add_checking_comment_form = forms.AddCheckingCommentForm()

    return render(
        request, 'entrance/staff/check_users_task.html', {
            'group': checking_group,
            'user_for_checking': user,
            'locked_by_me': locked_by_me,
            'task': task,
            'base_entrance_level': base_entrance_level,
            'level_upgrades': level_upgrades,
            'solutions': solutions,
            'last_solution': last_solution,
            'checks': checks,
            'last_mark': last_mark,
            'checking_comments': checking_comments,
            'add_checking_comment_form': add_checking_comment_form,
            'mark_form': mark_form
        })
Пример #5
0
def check_user(request, user, group=None):
    entrance_exam = (models.EntranceExam.objects.filter(
        school=request.school).first())

    checking_comments = user.entrance_checking_comments.filter(
        school=request.school).order_by('created_at')

    add_checking_comment_form = forms.AddCheckingCommentForm()

    base_entrance_level = None
    level_upgrades = []
    test_tasks = []
    file_tasks = []
    program_tasks = []
    if entrance_exam is not None:
        base_entrance_level = upgrades.get_base_entrance_level(
            request.school, user)
        level_upgrades = models.EntranceLevelUpgrade.objects.filter(
            upgraded_to__school=request.school, user=user)
        tasks = upgrades.get_entrance_tasks(request.school, user,
                                            base_entrance_level)
        tasks_solutions = group_by(
            user.entrance_exam_solutions.filter(
                task__exam=entrance_exam).order_by('-created_at'),
            operator.attrgetter('task_id'))

        for task in tasks:
            task.user_solutions = tasks_solutions[task.id]
            task.is_solved = task.is_solved_by_user(user)
            if type(task) is models.TestEntranceExamTask:
                if len(task.user_solutions) > 0:
                    task.last_try = task.user_solutions[0].solution
                    task.is_last_correct = task.is_solution_correct(
                        task.last_try)
                else:
                    task.last_try = None
                    task.is_last_correct = None
            if type(task) is models.FileEntranceExamTask:
                if len(task.user_solutions) > 0:
                    task.last_solution = task.user_solutions[0]
                    task.checks = list(task.last_solution.checks.all())
                else:
                    task.last_solution = None
                    task.checks = []

        test_tasks = list(
            filter(lambda t: type(t) is models.TestEntranceExamTask, tasks))
        file_tasks = list(
            filter(lambda t: type(t) is models.FileEntranceExamTask, tasks))
        program_tasks = list(
            filter(lambda t: isinstance(t, models.EjudgeEntranceExamTask),
                   tasks))

    return render(
        request, 'entrance/staff/check_user.html', {
            'group': group,
            'user_for_checking': user,
            'base_entrance_level': base_entrance_level,
            'level_upgrades': level_upgrades,
            'test_tasks': test_tasks,
            'file_tasks': file_tasks,
            'program_tasks': program_tasks,
            'checking_comments': checking_comments,
            'add_checking_comment_form': add_checking_comment_form,
            'user_summary': UserSummary.summary_for_user(request.school, user),
            'clone_accounts': _find_clones(user)
        })