Add staff visibility workstation enrollment registration vault and category task views

This commit is contained in:
A R R R Associates
2026-09-02 14:05:20 +05:30
parent 1fe1597d6f
commit 97777e13a1
22 changed files with 538 additions and 103 deletions
+47 -6
View File
@@ -23,7 +23,7 @@ from app.modules.core.tenancy.settings_models import BranchSettings
from app.modules.employees.models import Employee, EmployeeAttendance, EmployeeRegistrationRequest, EmployeeLeaveType, EmployeeLeaveBalance, EmployeeLeaveRequest, EmployeeDocumentType, EmployeeDocument, EmployeeOnboardingChecklistItem, EmployeeOnboardingTask, EmployeeOffboardingRequest, EmployeeOffboardingTask, EmployeeSalaryStructure, EmployeePayrollRun, EmployeePayslip
from app.modules.clients.models import Client, ClientBusinessUnit, ClientBranch
from app.modules.documents.models import EngagementDocument
from app.modules.services.models import ClientServiceTaskInstance, ClientServiceSubscription, ServiceCatalogue, ServiceTaskComment, FirmTaskDocumentRequirement
from app.modules.services.models import ClientServiceTaskInstance, ClientServiceSubscription, ServiceCatalogue, ServiceTaskComment, FirmTaskDocumentRequirement, FirmServiceTaskTemplate, ServiceTaskCategory
from app.modules.registrations.models import ClientRegistration, RegistrationType
from app.modules.services.engagement_resources import build_engagement_resource_context
from app.modules.services.execution import (
@@ -152,11 +152,18 @@ def list_employees(
q: str = "",
include_inactive: bool = False,
link_status: str = "all",
status_filter: str | None = None,
) -> list[Employee]:
stmt = select(Employee).where(Employee.tenant_id == scope.tenant_id)
if scope.branch_id is not None:
stmt = stmt.where(Employee.branch_id == scope.branch_id)
if not include_inactive:
normalized_status = (status_filter or "").strip().lower()
if normalized_status in {"active", "inactive", "relieved"}:
stmt = stmt.where(Employee.status == normalized_status)
elif normalized_status == "all":
pass
elif not include_inactive:
stmt = stmt.where(Employee.is_active.is_(True))
link_status = (link_status or "all").lower()
@@ -3617,7 +3624,11 @@ def list_employee_engagement_documents(db: Session, scope: EmployeeScope, engage
def _employee_task_category(task: ClientServiceTaskInstance) -> str:
value = (getattr(task, "task_category", None) or "").strip()
value = (
getattr(task, "_resolved_task_category", None)
or getattr(task, "task_category", None)
or ""
).strip()
return value or "General Workflow"
@@ -4021,10 +4032,37 @@ def get_employee_engagement_work_board(
if int(row.id) in assigned_ids
or (getattr(row, "default_role_name", None) or "").strip().lower() in reviewer_roles
]
use_task_categories = any(
bool((getattr(row, "task_category", None) or "").strip())
# Resolve task categories from the current Task Category master/template when
# older generated task instances do not carry the category snapshot. This
# keeps historical engagements category-based without rewriting task history.
template_ids = {
int(row.firm_task_template_id)
for row in tasks
)
if getattr(row, "firm_task_template_id", None) is not None
}
resolved_categories: dict[int, tuple[str, int]] = {}
if template_ids:
category_rows = db.execute(
select(
FirmServiceTaskTemplate.id,
FirmServiceTaskTemplate.task_category,
ServiceTaskCategory.name,
ServiceTaskCategory.sort_order,
)
.outerjoin(ServiceTaskCategory, ServiceTaskCategory.id == FirmServiceTaskTemplate.task_category_id)
.where(FirmServiceTaskTemplate.id.in_(template_ids))
).all()
for template_id, legacy_name, master_name, sort_order in category_rows:
resolved_name = (master_name or legacy_name or "").strip()
if resolved_name:
resolved_categories[int(template_id)] = (resolved_name, int(sort_order or 100))
for row in tasks:
template_id = getattr(row, "firm_task_template_id", None)
resolved = resolved_categories.get(int(template_id)) if template_id is not None else None
row._resolved_task_category = resolved[0] if resolved else ((getattr(row, "task_category", None) or "").strip() or "General Workflow")
row._resolved_task_category_sort = resolved[1] if resolved else 100
use_task_categories = any(_employee_task_category(row) != "General Workflow" for row in tasks)
summary = {
"total": len(tasks),
@@ -4056,6 +4094,7 @@ def get_employee_engagement_work_board(
if category is None:
category = {
"name": category_name,
"sort_order": int(getattr(task, "_resolved_task_category_sort", 100) or 100),
"tasks": [],
"total": 0,
"completed": 0,
@@ -4075,6 +4114,8 @@ def get_employee_engagement_work_board(
elif status_code == "in_progress":
category["in_progress"] += 1
categories.sort(key=lambda item: (int(item.get("sort_order", 100)), item["name"].lower()))
for category in categories:
weighted_category = _weighted_progress(category["tasks"])
category.update(weighted_category)