Corp/backend/tasks/queries.py
2026-08-25 13:28:43 +03:00

155 lines
5.4 KiB
Python

"""Read model for the task REST collection and detail endpoints."""
from django.contrib.contenttypes.models import ContentType
from django.db.models import Count, IntegerField, OuterRef, Prefetch, Q, Subquery, Value
from django.db.models.functions import Coalesce
from communications.models import Message
from employees.services.skill_progress import skill_queryset_with_rarity
from tasks.access import task_board_access_q
from tasks.models import (
Task,
TaskAttachment,
TaskBoard,
TaskLinkedObjectKind,
)
def task_api_queryset(*, user, params):
task_content_type = ContentType.objects.get_for_model(Task)
comments_subquery = (
Message.objects.filter(
chat__type="comments",
chat__context_content_type=task_content_type,
chat__context_object_id=OuterRef("pk"),
is_deleted=False,
)
.values("chat")
.annotate(count=Count("id"))
.values("count")
)
queryset = (
Task.objects.filter(board__is_archived=False)
.filter(board__in=TaskBoard.objects.filter(task_board_access_q(user)))
.select_related(
"board",
"column",
"row",
"created_by",
"assignee",
"cover",
"cover__attachment",
"cover__attachment__uploaded_by",
"cover__comment",
"cover__comment__author",
"cover__external_link",
"cover__external_link__created_by",
"cover__linked_object",
"cover__linked_object__content_type",
)
.prefetch_related(
"labels",
Prefetch("skills", queryset=skill_queryset_with_rarity()),
"participants",
"checklist_items",
Prefetch(
"cover__comment__task_attachments",
queryset=TaskAttachment.objects.select_related("uploaded_by"),
),
)
.annotate(
linked_posts_count=Count(
"linked_objects",
filter=Q(linked_objects__kind=TaskLinkedObjectKind.POST),
distinct=True,
),
linked_messages_count=Count(
"linked_objects",
filter=Q(linked_objects__kind=TaskLinkedObjectKind.MESSAGE),
distinct=True,
),
linked_events_count=Count(
"linked_objects",
filter=Q(linked_objects__kind=TaskLinkedObjectKind.CALENDAR_EVENT),
distinct=True,
),
linked_documents_count=Count(
"linked_objects",
filter=Q(
linked_objects__kind=TaskLinkedObjectKind.DOCUMENT,
),
distinct=True,
),
linked_requests_count=Count(
"linked_objects",
filter=Q(
linked_objects__kind=TaskLinkedObjectKind.REQUEST,
),
distinct=True,
),
linked_procurement_requests_count=Count(
"linked_objects",
filter=Q(
linked_objects__kind=(TaskLinkedObjectKind.PROCUREMENT_REQUEST),
),
distinct=True,
),
linked_employees_count=Count(
"linked_objects",
filter=Q(
linked_objects__kind=TaskLinkedObjectKind.EMPLOYEE,
),
distinct=True,
),
linked_guests_count=Count(
"linked_objects",
filter=Q(
linked_objects__kind=TaskLinkedObjectKind.GUEST,
),
distinct=True,
),
linked_guest_visits_count=Count(
"linked_objects",
filter=Q(
linked_objects__kind=TaskLinkedObjectKind.GUEST_VISIT,
),
distinct=True,
),
linked_attendance_records_count=Count(
"linked_objects",
filter=Q(
linked_objects__kind=(TaskLinkedObjectKind.ATTENDANCE_RECORD),
),
distinct=True,
),
linked_objects_count=(
Count("linked_objects", distinct=True)
+ Count("external_links", distinct=True)
),
comments_count=Coalesce(
Subquery(comments_subquery, output_field=IntegerField()),
Value(0),
),
attachments_count=Count("attachments", distinct=True),
checklist_total=Count("checklist_items", distinct=True),
checklist_completed=Count(
"checklist_items",
filter=Q(checklist_items__is_completed=True),
distinct=True,
),
)
)
if board := params.get("board"):
queryset = queryset.filter(board_id=board)
if column := params.get("column"):
queryset = queryset.filter(column_id=column)
if row := params.get("row"):
queryset = queryset.filter(row_id=row)
if assignee := params.get("assignee"):
queryset = queryset.filter(assignee_id=assignee)
if priority := params.get("priority"):
queryset = queryset.filter(priority=priority)
if params.get("unassigned") == "true":
queryset = queryset.filter(assignee__isnull=True)
return queryset