Add partner engagement review and release workspace phase 5B
This commit is contained in:
@@ -1,15 +1,21 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import APIRouter, Request
|
||||
from fastapi import APIRouter, Form, Request
|
||||
from fastapi.responses import RedirectResponse
|
||||
|
||||
from app.core.db.common import CommonSessionLocal
|
||||
from app.core.http_responses import ui_access_denied
|
||||
from app.core.security.csrf import get_or_create_csrf_token
|
||||
from app.core.security.csrf import get_or_create_csrf_token, validate_csrf
|
||||
from app.core.security.session_auth import get_current_user
|
||||
from app.core.templating import templates
|
||||
from app.modules.core.rbac.deps import get_user_permissions, get_user_roles
|
||||
from app.modules.partner_dashboard.service import build_partner_dashboard_payload, can_access_partner_dashboard
|
||||
from app.modules.partner_dashboard.service import (
|
||||
build_partner_dashboard_payload,
|
||||
can_access_partner_dashboard,
|
||||
get_next_partner_review_task_id,
|
||||
get_partner_review_workspace,
|
||||
)
|
||||
from app.modules.services.execution import apply_task_review
|
||||
|
||||
router = APIRouter(prefix="/partner", tags=["partner-dashboard-v2-ui"])
|
||||
|
||||
@@ -73,3 +79,92 @@ def dashboard_tab(request: Request, tab_name: str):
|
||||
)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.get("/reviews/engagements/{subscription_id}")
|
||||
def partner_review_workspace(request: Request, subscription_id: int, task_id: int | None = None):
|
||||
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)
|
||||
return templates.TemplateResponse(
|
||||
"modules/partner_dashboard/templates/partner_dashboard/partner_review_workspace.html",
|
||||
{
|
||||
"request": request,
|
||||
"current_user": current_user,
|
||||
"current_user_roles": get_user_roles(db, current_user.id),
|
||||
"current_user_permissions": get_user_permissions(db, current_user.id),
|
||||
"csrf_token": get_or_create_csrf_token(request),
|
||||
"title": "Partner Engagement Review & Release",
|
||||
"workspace": workspace,
|
||||
},
|
||||
)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.post("/reviews/engagements/{subscription_id}/tasks/{task_id}")
|
||||
def partner_review_task_submit(
|
||||
request: Request,
|
||||
subscription_id: int,
|
||||
task_id: int,
|
||||
decision: str = Form("reviewed"),
|
||||
review_note: str = Form(""),
|
||||
workflow_action: str = Form("save"),
|
||||
csrf_token: str = Form(...),
|
||||
):
|
||||
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):
|
||||
return RedirectResponse(url=f"/partner/reviews/engagements/{subscription_id}?review_error=task", 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}&review_error=locked", status_code=303)
|
||||
if not active.get("can_review") or active.get("review_level") not in {"partner", "review_partner"}:
|
||||
return RedirectResponse(url=f"/partner/reviews/engagements/{subscription_id}?task_id={task_id}&review_error=not_ready", status_code=303)
|
||||
|
||||
from sqlalchemy import select
|
||||
from app.modules.services.models import ClientServiceTaskInstance
|
||||
task = db.execute(select(ClientServiceTaskInstance).where(
|
||||
ClientServiceTaskInstance.id == int(task_id),
|
||||
ClientServiceTaskInstance.subscription_id == int(subscription_id),
|
||||
)).scalar_one_or_none()
|
||||
if not task:
|
||||
return RedirectResponse(url="/partner/dashboard?tab=review", status_code=303)
|
||||
try:
|
||||
apply_task_review(
|
||||
db,
|
||||
task=task,
|
||||
review_level=active["review_level"],
|
||||
decision=decision,
|
||||
note=review_note,
|
||||
user_id=current_user.id,
|
||||
)
|
||||
db.commit()
|
||||
except ValueError:
|
||||
db.rollback()
|
||||
return RedirectResponse(url=f"/partner/reviews/engagements/{subscription_id}?task_id={task_id}&review_error=validation", status_code=303)
|
||||
|
||||
if workflow_action == "save_next":
|
||||
refreshed = get_partner_review_workspace(db, request, current_user, subscription_id=subscription_id)
|
||||
next_id = get_next_partner_review_task_id(refreshed, task_id) if refreshed else None
|
||||
if next_id:
|
||||
return RedirectResponse(url=f"/partner/reviews/engagements/{subscription_id}?task_id={next_id}&reviewed=1", status_code=303)
|
||||
return RedirectResponse(url=f"/partner/reviews/engagements/{subscription_id}?task_id={task_id}&reviewed=1", status_code=303)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
Reference in New Issue
Block a user