From 5206a04ed82fcac63035689f96d44c75dc8e0675 Mon Sep 17 00:00:00 2001 From: DarKylX Date: Fri, 13 Nov 2026 17:03:27 +0300 Subject: [PATCH] Preserve DEV organizer evaluation metrics --- .../services/assignment_analytics.py | 39 +++++++------------ partner_programs/services/role_analytics.py | 2 +- project_rates/expert_cabinet.py | 2 +- project_rates/services.py | 2 +- project_rates/workspace.py | 4 +- 5 files changed, 21 insertions(+), 28 deletions(-) diff --git a/partner_programs/services/assignment_analytics.py b/partner_programs/services/assignment_analytics.py index 45c2e73b..507a8400 100644 --- a/partner_programs/services/assignment_analytics.py +++ b/partner_programs/services/assignment_analytics.py @@ -20,13 +20,8 @@ from project_rates.models import Criteria, ProjectExpertAssignment, ProjectScore -def annotated_assignment_queryset(program_id=None): - """Общая SQL-проверка завершённости реального назначения в программе. - - Завершенное назначение требует сданного проекта и оценок по обязательным - критериям программы. Если есть только комментарии, нужна сохраненная оценка. - Аннотации пригодны и для списка назначений, и для агрегации работ без N+1. - """ +def annotated_assignment_queryset(program_id=None, *, expert_completion=False): + """Кабинет эксперта учитывает обязательные критерии; отчеты — все критерии.""" scope = program_id if program_id is not None else OuterRef("partner_program_id") criteria = ( Criteria.objects.filter(partner_program_id=scope) @@ -53,7 +48,7 @@ def annotated_assignment_queryset(program_id=None): link = PartnerProgramProject.objects.filter( partner_program_id=scope, project_id=OuterRef("project_id") ).order_by("pk") - return ( + assignments = ( ( ProjectExpertAssignment.objects.filter(partner_program_id=program_id) if program_id is not None @@ -71,22 +66,18 @@ def annotated_assignment_queryset(program_id=None): ), project_submitted_at=Subquery(link.values("datetime_submitted")[:1]), ) - .annotate( - is_completed=Case( - When( - Q(project_submitted=True) - & ( - Q( - required_criteria__gt=0, - required_scored__gte=F("required_criteria"), - ) - | Q(required_criteria=0, criteria_scored__gt=0) - ), - then=Value(True), - ), - default=Value(False), - output_field=BooleanField(), - ) + ) + if expert_completion: + complete = Q( + required_criteria__gt=0, required_scored__gte=F("required_criteria") + ) | Q(required_criteria=0, criteria_scored__gt=0) + else: + complete = Q(criteria_total__gt=0, criteria_scored__gte=F("criteria_total")) + return assignments.annotate( + is_completed=Case( + When(Q(project_submitted=True) & complete, then=Value(True)), + default=Value(False), + output_field=BooleanField(), ) ) diff --git a/partner_programs/services/role_analytics.py b/partner_programs/services/role_analytics.py index d37c43e7..45ede253 100644 --- a/partner_programs/services/role_analytics.py +++ b/partner_programs/services/role_analytics.py @@ -46,7 +46,7 @@ def expert_widget_metrics(program, user): if mode == "open" or not program.is_competitive: return {"mode": mode, "assigned": None, "remaining": None} counts = ( - annotated_assignment_queryset(program.pk) + annotated_assignment_queryset(program.pk, expert_completion=True) .filter(expert__user_id=user.pk) .aggregate( assigned=Count("pk"), diff --git a/project_rates/expert_cabinet.py b/project_rates/expert_cabinet.py index 4ef64bcb..32860ba6 100644 --- a/project_rates/expert_cabinet.py +++ b/project_rates/expert_cabinet.py @@ -23,7 +23,7 @@ def cabinet_projects( project_filters: Q | None = None, ): own = ( - annotated_assignment_queryset() + annotated_assignment_queryset(expert_completion=True) .filter( expert__user=user, partner_program_id__in=program_ids, diff --git a/project_rates/services.py b/project_rates/services.py index 25db11ab..6a7ce900 100644 --- a/project_rates/services.py +++ b/project_rates/services.py @@ -94,7 +94,7 @@ def get_projects_for_rate_queryset( completed = Q(_own_score_count__gt=0) if assigned_only: completed = Exists( - annotated_assignment_queryset(program.pk).filter( + annotated_assignment_queryset(program.pk, expert_completion=True).filter( expert__user=user, project_id=OuterRef("pk"), is_completed=True ) ) diff --git a/project_rates/workspace.py b/project_rates/workspace.py index 63191dfb..89968a73 100644 --- a/project_rates/workspace.py +++ b/project_rates/workspace.py @@ -700,7 +700,9 @@ def my_programs(user): done = sum(row["is_completed"] for row in assignments) else: assignments = list( - annotated_assignment_queryset(program.pk).filter(expert__user=user) + annotated_assignment_queryset(program.pk, expert_completion=True).filter( + expert__user=user + ) ) done = sum(a.is_completed for a in assignments) rows.append(