Allow partners to execute tasks assigned to them

This commit is contained in:
A R R R Associates
2026-09-22 19:10:30 +05:30
parent 581f5faf80
commit b176f60c11
3 changed files with 130 additions and 3 deletions
+80
View File
@@ -16,6 +16,7 @@ from app.modules.partner_dashboard.service import (
get_partner_review_workspace,
)
from app.modules.services.execution import apply_normal_task_review, apply_task_review
from app.modules.employees.service import build_employee_scope, save_employee_workflow_task
from app.modules.alerts.workflow_escalations import update_workflow_escalation
router = APIRouter(prefix="/partner", tags=["partner-dashboard-v2-ui"])
@@ -111,6 +112,85 @@ def partner_review_workspace(request: Request, subscription_id: int, task_id: in
db.close()
@router.post("/reviews/engagements/{subscription_id}/tasks/{task_id}/execute")
def partner_execute_assigned_task(
request: Request,
subscription_id: int,
task_id: int,
status: str = Form("in_progress"),
remarks: str = Form(""),
checklist_response: str = Form(""),
checklist_text_response: str = Form(""),
checklist_number_response: str = Form(""),
checklist_date_response: str = Form(""),
checklist_remarks: str = Form(""),
csrf_token: str = Form(...),
):
"""Execute a task from Partner Operations when the Partner is its actual assignee.
This deliberately reuses the existing employee task-save service so checklist
validation, evidence/approval gates, AQMM recalculation, review submission, locks
and audit timestamps remain identical to the existing execution workflow.
"""
validate_csrf(request, csrf_token)
db = CommonSessionLocal()
try:
current_user = get_current_user(request, db=db)
if not current_user:
return RedirectResponse(url="/login", status_code=303)
if not can_access_partner_dashboard(db, current_user):
return ui_access_denied()
workspace = get_partner_review_workspace(
db, request, current_user, subscription_id=subscription_id, active_task_id=task_id
)
if not workspace:
return RedirectResponse(url="/partner/dashboard?tab=review", status_code=303)
active = workspace.get("active_task") or {}
if int(active.get("id") or 0) != int(task_id) or not active.get("can_execute"):
return RedirectResponse(
url=f"/partner/reviews/engagements/{subscription_id}?task_id={task_id}&execution_error=not_assigned",
status_code=303,
)
if active.get("is_locked") or workspace.get("is_locked"):
return RedirectResponse(
url=f"/partner/reviews/engagements/{subscription_id}?task_id={task_id}&execution_error=locked",
status_code=303,
)
tenant_id = request.session.get("active_tenant_id") or current_user.tenant_id
branch_id = request.session.get("active_branch_id")
scope = build_employee_scope(db, current_user, tenant_id=tenant_id, branch_id=branch_id)
try:
saved_task, _next_task = save_employee_workflow_task(
db,
scope,
task_id,
status=status,
remarks=remarks,
checklist_response=checklist_response,
checklist_text_response=checklist_text_response,
checklist_number_response=checklist_number_response,
checklist_date_response=checklist_date_response,
checklist_remarks=checklist_remarks,
actor_user_id=current_user.id,
financial_year=None,
)
except ValueError as exc:
db.rollback()
return RedirectResponse(
url=f"/partner/reviews/engagements/{subscription_id}?task_id={task_id}&execution_error=validation",
status_code=303,
)
return RedirectResponse(
url=f"/partner/reviews/engagements/{subscription_id}?task_id={saved_task.id}&executed=1",
status_code=303,
)
finally:
db.close()
@router.post("/reviews/engagements/{subscription_id}/tasks/{task_id}")
def partner_review_task_submit(
request: Request,