Move AQMM controls to assurance engagement workflow
This commit is contained in:
@@ -26,6 +26,16 @@ from app.modules.services.client_services import (
|
||||
list_review_partners,
|
||||
parse_date,
|
||||
review_partner_required_for_engagement,
|
||||
ensure_engagement_quality_workflow,
|
||||
enforce_quality_gate_on_subscription,
|
||||
request_engagement_quality_declarations,
|
||||
list_engagement_quality_declarations,
|
||||
respond_engagement_quality_declaration,
|
||||
verify_engagement_kyc_from_permanent_documents,
|
||||
get_latest_engagement_kyc_verification,
|
||||
get_current_engagement_letter,
|
||||
mark_engagement_letter_completed,
|
||||
approve_engagement_quality_workflow,
|
||||
)
|
||||
from app.modules.core.rbac.deps import get_user_permissions, get_user_roles
|
||||
from app.modules.core.rbac.permission_guard import require_permission
|
||||
@@ -300,6 +310,8 @@ def subscription_create_submit(
|
||||
row.is_active = is_active is not None
|
||||
row.updated_by_user_id = user.id
|
||||
apply_due_date_rule_to_subscription(db, row)
|
||||
ensure_engagement_quality_workflow(db, subscription=row, actor_user_id=user.id, create_declarations=False)
|
||||
enforce_quality_gate_on_subscription(row)
|
||||
|
||||
db.commit()
|
||||
db.refresh(row)
|
||||
@@ -380,6 +392,13 @@ def subscription_detail(request: Request, subscription_id: int):
|
||||
if row.financial_year != active_fy:
|
||||
return RedirectResponse(url=f"/services/engagements?financial_year={active_fy}", status_code=303)
|
||||
|
||||
ensure_engagement_quality_workflow(db, subscription=row, actor_user_id=user.id, create_declarations=False)
|
||||
db.flush()
|
||||
declarations = list_engagement_quality_declarations(db, subscription_id=row.id)
|
||||
my_pending_declarations = [d for d in declarations if d.requested_user_id == user.id and d.status == "pending"]
|
||||
kyc_verification = get_latest_engagement_kyc_verification(db, subscription_id=row.id)
|
||||
engagement_letter = get_current_engagement_letter(db, subscription_id=row.id)
|
||||
|
||||
tasks = db.execute(
|
||||
select(ClientServiceTaskInstance)
|
||||
.where(ClientServiceTaskInstance.subscription_id == row.id)
|
||||
@@ -394,12 +413,168 @@ def subscription_detail(request: Request, subscription_id: int):
|
||||
title="Engagement Subscription",
|
||||
row=row,
|
||||
tasks=tasks,
|
||||
declarations=declarations,
|
||||
my_pending_declarations=my_pending_declarations,
|
||||
kyc_verification=kyc_verification,
|
||||
engagement_letter=engagement_letter,
|
||||
can_manage=_can_manage_client_services(db, user),
|
||||
)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.post("/{subscription_id}/aqmm/initiate")
|
||||
def subscription_aqmm_initiate(request: Request, subscription_id: int, csrf_token: str = Form(...)):
|
||||
validate_csrf(request, csrf_token)
|
||||
db = CommonSessionLocal()
|
||||
try:
|
||||
user = get_current_user(request, db=db)
|
||||
if not user:
|
||||
return RedirectResponse(url="/login", status_code=303)
|
||||
try:
|
||||
require_permission(db, user, "clients.edit")
|
||||
except Exception:
|
||||
return _redirect_denied()
|
||||
tenant_id = _active_tenant_id(request, user)
|
||||
row = get_subscription(db, subscription_id=subscription_id, tenant_id=tenant_id)
|
||||
if row:
|
||||
ensure_engagement_quality_workflow(db, subscription=row, actor_user_id=user.id, create_declarations=True)
|
||||
enforce_quality_gate_on_subscription(row)
|
||||
db.commit()
|
||||
return RedirectResponse(url=f"/services/engagements/{subscription_id}", status_code=303)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.post("/{subscription_id}/aqmm/request-declarations")
|
||||
def subscription_aqmm_request_declarations(request: Request, subscription_id: int, csrf_token: str = Form(...)):
|
||||
validate_csrf(request, csrf_token)
|
||||
db = CommonSessionLocal()
|
||||
try:
|
||||
user = get_current_user(request, db=db)
|
||||
if not user:
|
||||
return RedirectResponse(url="/login", status_code=303)
|
||||
try:
|
||||
require_permission(db, user, "clients.edit")
|
||||
except Exception:
|
||||
return _redirect_denied()
|
||||
tenant_id = _active_tenant_id(request, user)
|
||||
row = get_subscription(db, subscription_id=subscription_id, tenant_id=tenant_id)
|
||||
if row:
|
||||
request_engagement_quality_declarations(db, subscription=row, actor_user_id=user.id)
|
||||
enforce_quality_gate_on_subscription(row)
|
||||
db.commit()
|
||||
return RedirectResponse(url=f"/services/engagements/{subscription_id}", status_code=303)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.post("/{subscription_id}/aqmm/declarations/{declaration_id}/respond")
|
||||
def subscription_aqmm_declaration_respond(
|
||||
request: Request,
|
||||
subscription_id: int,
|
||||
declaration_id: int,
|
||||
status: str = Form(...),
|
||||
notes: str = Form(""),
|
||||
csrf_token: str = Form(...),
|
||||
):
|
||||
validate_csrf(request, csrf_token)
|
||||
db = CommonSessionLocal()
|
||||
try:
|
||||
user = get_current_user(request, db=db)
|
||||
if not user:
|
||||
return RedirectResponse(url="/login", status_code=303)
|
||||
respond_engagement_quality_declaration(
|
||||
db,
|
||||
declaration_id=declaration_id,
|
||||
current_user_id=user.id,
|
||||
status=status,
|
||||
notes=notes,
|
||||
request=request,
|
||||
)
|
||||
db.commit()
|
||||
return RedirectResponse(url=f"/services/engagements/{subscription_id}", status_code=303)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.post("/{subscription_id}/aqmm/kyc/verify")
|
||||
def subscription_aqmm_kyc_verify(request: Request, subscription_id: int, notes: str = Form(""), csrf_token: str = Form(...)):
|
||||
validate_csrf(request, csrf_token)
|
||||
db = CommonSessionLocal()
|
||||
try:
|
||||
user = get_current_user(request, db=db)
|
||||
if not user:
|
||||
return RedirectResponse(url="/login", status_code=303)
|
||||
try:
|
||||
require_permission(db, user, "clients.edit")
|
||||
except Exception:
|
||||
return _redirect_denied()
|
||||
tenant_id = _active_tenant_id(request, user)
|
||||
row = get_subscription(db, subscription_id=subscription_id, tenant_id=tenant_id)
|
||||
if row:
|
||||
verify_engagement_kyc_from_permanent_documents(db, subscription=row, actor_user_id=user.id, notes=notes)
|
||||
enforce_quality_gate_on_subscription(row)
|
||||
db.commit()
|
||||
return RedirectResponse(url=f"/services/engagements/{subscription_id}", status_code=303)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.post("/{subscription_id}/aqmm/engagement-letter/complete")
|
||||
def subscription_aqmm_engagement_letter_complete(
|
||||
request: Request,
|
||||
subscription_id: int,
|
||||
acceptance_mode: str = Form(...),
|
||||
notes: str = Form(""),
|
||||
csrf_token: str = Form(...),
|
||||
):
|
||||
validate_csrf(request, csrf_token)
|
||||
db = CommonSessionLocal()
|
||||
try:
|
||||
user = get_current_user(request, db=db)
|
||||
if not user:
|
||||
return RedirectResponse(url="/login", status_code=303)
|
||||
try:
|
||||
require_permission(db, user, "clients.edit")
|
||||
except Exception:
|
||||
return _redirect_denied()
|
||||
tenant_id = _active_tenant_id(request, user)
|
||||
row = get_subscription(db, subscription_id=subscription_id, tenant_id=tenant_id)
|
||||
if row:
|
||||
mark_engagement_letter_completed(db, subscription=row, actor_user_id=user.id, acceptance_mode=acceptance_mode, notes=notes, request=request)
|
||||
enforce_quality_gate_on_subscription(row)
|
||||
db.commit()
|
||||
return RedirectResponse(url=f"/services/engagements/{subscription_id}", status_code=303)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.post("/{subscription_id}/aqmm/approve")
|
||||
def subscription_aqmm_approve(request: Request, subscription_id: int, csrf_token: str = Form(...)):
|
||||
validate_csrf(request, csrf_token)
|
||||
db = CommonSessionLocal()
|
||||
try:
|
||||
user = get_current_user(request, db=db)
|
||||
if not user:
|
||||
return RedirectResponse(url="/login", status_code=303)
|
||||
try:
|
||||
require_permission(db, user, "clients.edit")
|
||||
except Exception:
|
||||
return _redirect_denied()
|
||||
tenant_id = _active_tenant_id(request, user)
|
||||
row = get_subscription(db, subscription_id=subscription_id, tenant_id=tenant_id)
|
||||
if row:
|
||||
try:
|
||||
approve_engagement_quality_workflow(db, subscription=row, actor_user_id=user.id)
|
||||
db.commit()
|
||||
except ValueError:
|
||||
db.rollback()
|
||||
return RedirectResponse(url=f"/services/engagements/{subscription_id}", status_code=303)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.get("/{subscription_id}/edit")
|
||||
def subscription_edit_page(request: Request, subscription_id: int):
|
||||
db = CommonSessionLocal()
|
||||
@@ -503,6 +678,8 @@ def subscription_edit_submit(
|
||||
row.is_active = is_active is not None
|
||||
row.updated_by_user_id = user.id
|
||||
apply_due_date_rule_to_subscription(db, row)
|
||||
ensure_engagement_quality_workflow(db, subscription=row, actor_user_id=user.id, create_declarations=False)
|
||||
enforce_quality_gate_on_subscription(row)
|
||||
db.commit()
|
||||
return RedirectResponse(url=f"/services/engagements/{row.id}", status_code=303)
|
||||
finally:
|
||||
|
||||
Reference in New Issue
Block a user