Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 15 additions & 24 deletions partner_programs/services/assignment_analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand All @@ -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(),
)
)

Expand Down
2 changes: 1 addition & 1 deletion partner_programs/services/role_analytics.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down
2 changes: 1 addition & 1 deletion project_rates/expert_cabinet.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion project_rates/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
)
Expand Down
4 changes: 3 additions & 1 deletion project_rates/workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Loading