Corp/backend/tasks/queries.py

153 lines
5.2 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 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",
"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