Coverage for apps/workflow/tasks_hub_api.py: 100%
24 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-04 17:24 +0000
« prev ^ index » next coverage.py v7.17.0, created at 2026-11-04 17:24 +0000
1"""Cross-loan Tasks Hub router: GET /api/tasks (mounted at "", not under /loans).
3The per-loan task endpoints in apps/workflow/api.py are unchanged; this is a sibling
4read-only view flattening tasks across every loan the principal can see.
5"""
7from __future__ import annotations
9from django.db.models import Prefetch
10from ninja import Router
12from apps.accounts.auth import requires, staff_loan_queryset
13from apps.application_1003.models import Borrower
14from apps.workflow.models import LoanTask
15from apps.workflow.schemas import TaskHubListOut
17router = Router(tags=["tasks-hub"])
20def _task_status(task: LoanTask) -> str:
21 """Done/InProgress/ToDo, derived from `completed` + `checklists` (design.md D1)."""
22 if task.completed:
23 return "Done"
24 if any(item.get("done") for item in task.checklists):
25 return "InProgress"
26 return "ToDo"
29def _task_row(task: LoanTask) -> dict:
30 loan = task.loan
31 primary = next(iter(getattr(loan, "_primary_borrowers", [])), None)
32 return {
33 "id": task.id,
34 "title": task.title,
35 "description": task.description,
36 "assignee_id": task.assignee_id,
37 "due_date": task.due_date,
38 "status": _task_status(task),
39 "checklists": task.checklists,
40 "loan_guid": str(loan.guid),
41 "loan_number": loan.arive_loan_no,
42 "borrower_name": f"{primary.first_name} {primary.last_name}" if primary else "—",
43 }
46@router.get("/tasks", response=TaskHubListOut, auth=requires("LOAN_VIEW"))
47def list_all_tasks(request):
48 qs = staff_loan_queryset(request.principal, "all")
49 tasks = LoanTask.objects.filter(loan__in=qs).select_related("loan").prefetch_related(
50 Prefetch(
51 "loan__borrowers",
52 queryset=Borrower.objects.filter(is_primary=True),
53 to_attr="_primary_borrowers",
54 )
55 )
56 rows = [_task_row(task) for task in tasks]
57 return {"count": len(rows), "rows": rows}