Пример #1
0
def comment_report(monitoring):
    """
    Вернет словарь с основной статистикой по комментариям.

    expired - list: просроченные комментарии без ответа
    expiring - list: комментарии без ответа, срок ответа которых истечет в течении суток
    pending - list: остальные комментарии без ответа
    num_answered - количество комментариев с ответом (включая просроченные)
    num_answered_late - количество комментариев с просроченным ответом
    num_org_comments - количество комментариев представителей организаций
    num_expert_comments - количество комментариев экспертов
    active_experts - list: активные эксперты (с доп. атрибутом num_comments)
    active_orgs - list: активные организации (dict c ключами 'name', 'expert' и 'num_comments')
    num_orgs_with_user - количество организаций, имеющих хотя бы одного представителя

    """
    org_users = User.objects.filter(userprofile__organization__monitoring=monitoring)
    org_users = set(org_users.distinct().values_list('pk', flat=True))

    scores = Score.objects.filter(task__organization__monitoring=monitoring, task__status=Task.TASK_APPROVED)

    _scores = scores.values_list('pk', 'task__organization_id', 'task__organization__name', 'task__user__username')
    score_org_expert = dict((str(pk), (org_pk, org_name, expert)) for pk, org_pk, org_name, expert in _scores)

    # Dict by pk. Later this will become a list of active_experts and active_orgs.
    dict_active_experts, dict_active_orgs = {}, {}
    non_urgent, urgent, expired = [], [], []
    num_org_comments = num_answered = num_answered_late = 0

    for comment in CommentExmo.objects.filter(object_pk__in=scores).prefetch_related('user'):
        if comment.user.pk in org_users:
            org_pk, org_name, expert = score_org_expert[comment.object_pk]
            dict_active_orgs.setdefault(org_pk, {'num_comments': 0, 'name': org_name, 'expert': expert})
            dict_active_orgs[org_pk]['num_comments'] += 1

            num_org_comments += 1
            if comment.status == CommentExmo.ANSWERED:
                num_answered += 1
                if workday_count(comment.submit_date, comment.answered_date) > monitoring.time_to_answer:
                    num_answered_late += 1
            elif comment.status == CommentExmo.OPEN:
                days_passed = workday_count(comment.submit_date, datetime.today())
                if days_passed == monitoring.time_to_answer:
                    urgent.append(comment)
                elif days_passed > monitoring.time_to_answer:
                    expired.append(comment)
                else:
                    non_urgent.append(comment)
        else:
            # Comment by expert.
            if comment.user.pk in dict_active_experts:
                dict_active_experts[comment.user.pk].num_comments += 1
            else:
                comment.user.num_comments = 1
                dict_active_experts[comment.user.pk] = comment.user

    active_orgs = dict_active_orgs.values()
    active_experts = dict_active_experts.values()
    num_expert_comments = sum(e.num_comments for e in active_experts)
    num_orgs_with_user = monitoring.organization_set.filter(
        userprofile__isnull=False, orguser__seen=True).distinct().count()

    # Clean unneeded intermediate local variables before returning the rest as result dictionary.
    del scores, _scores, dict_active_experts, dict_active_orgs, org_users
    return locals()
Пример #2
0
 def test_workday_count(self, start, end, expected_result):
     fmt = '%Y.%m.%d %H:%M'
     result = workday_count(datetime.strptime(start, fmt), datetime.strptime(end, fmt))
     self.assertEqual(result, expected_result)
Пример #3
0
def comment_report(monitoring):
    """
    Вернет словарь с основной статистикой по комментариям.

    """
    from custom_comments.models import CommentExmo

    result = {}
    comments_without_reply = []
    fail_comments_without_reply = []
    fail_soon_comments_without_reply = []
    fail_comments_with_reply = []
    active_organization_stats = []
    total_org = Organization.objects.filter(monitoring=monitoring)
    reg_org = total_org.filter(userprofile__isnull=False)
    start_date = monitoring.interact_date
    end_date = datetime.today()
    time_to_answer = monitoring.time_to_answer

    scores = Score.objects.filter(
        task__organization__monitoring=monitoring)

    iifd_all_comments = CommentExmo.objects.filter(
        content_type__model='score',
        object_pk__in=scores,
        user__in=User.objects.exclude(
            groups__name='organizations')).order_by('submit_date')

    org_all_comments = CommentExmo.objects.filter(
        content_type__model='score',
        object_pk__in=scores,
        user__in=User.objects.filter(
            groups__name='organizations')).order_by('submit_date')

    org_comments = org_all_comments.filter(
        status=CommentExmo.OPEN
    )

    comments_with_reply = org_all_comments.filter(
        status=CommentExmo.ANSWERED
    )

    active_organizations = set([Score.objects.get(
        pk=oco.object_pk).task.organization for oco in org_all_comments])
    for active_organization in active_organizations:
        active_org_comments_count = org_all_comments.filter(
            object_pk__in=scores.filter(
                task__organization=active_organization)).count()
        try:
            task = Task.approved_tasks.get(organization=active_organization)
        except Task.DoesNotExist:
            task = None
        active_organization_stats.append(
            {'org': active_organization,
             'comments_count': active_org_comments_count,
             'task': task})

    active_iifd_person_stats = User.objects.filter(
        comment_comments__pk__in=iifd_all_comments).annotate(
            comments_count=Count('comment_comments'))

    for org_comment in org_comments:
        from core.utils import workday_count
        delta = timedelta(days=1)
        #check time_to_answer
        if workday_count(org_comment.submit_date.date() + delta,
                         end_date) == time_to_answer:
            fail_soon_comments_without_reply.append(org_comment)
        elif workday_count(org_comment.submit_date.date() + delta,
                           end_date) > time_to_answer:
            fail_comments_without_reply.append(org_comment)
        else:
            comments_without_reply.append(org_comment)

    #комментарии без ответа
    result['comments_without_reply'] = comments_without_reply
    #просроченные комментарии без ответа
    result['fail_comments_without_reply'] = fail_comments_without_reply
    #комментарии с ответом
    result['comments_with_reply'] = comments_with_reply
    #комментарии без ответа; срок ответа истечет в течении суток
    result['fail_soon_comments_without_reply'] = fail_soon_comments_without_reply
    #комментарии с ответом, но ответ был позже срока
    result['fail_comments_with_reply'] = fail_comments_with_reply
    #неотвеченные комментарии представителей
    result['org_comments'] = org_comments
    #все комментарии экспертов
    result['org_all_comments'] = org_all_comments
    #статистика активных (оставивших хоть один комментарий) организаций
    #лист словарей: [{'org': org1, 'comments_count': 1}, ...]
    result['active_organization_stats'] = active_organization_stats
    #статистика ответов по экспертам
    result['active_iifd_person_stats'] = active_iifd_person_stats
    #комментарии экспертов
    result['iifd_all_comments'] = iifd_all_comments
    #всего огранизаций
    result['total_org'] = total_org
    #зарегистрированных организаций
    result['reg_org'] = reg_org
    #дата начала взаимодействия
    result['start_date'] = start_date
    #дата окончания отчетного периода
    result['end_date'] = end_date
    #срок ответа на комментарии (в днях)
    result['time_to_answer'] = time_to_answer

    return result