Add Phase 3 client business intelligence profile

This commit is contained in:
A R R R Associates
2026-08-22 12:04:44 +05:30
parent f7bf1437ef
commit 397c887703
6 changed files with 467 additions and 0 deletions
+112
View File
@@ -55,6 +55,16 @@ from app.modules.core.rbac.deps import get_user_permissions, get_user_roles
from app.modules.core.rbac.permission_guard import require_permission
from app.modules.services.execution import list_client_visible_task_comments
from app.modules.clients.auditor_service import build_client_auditor_card
from app.modules.clients.business_profile_service import (
BUSINESS_MODEL_OPTIONS,
SOURCE_TYPE_OPTIONS,
add_source,
confirm_profile,
ensure_profile,
get_profile,
list_sources,
update_profile,
)
from app.modules.client_groups.service import get_group, list_groups
from app.modules.clients.portal_service import (
build_client_portal_summary,
@@ -2069,3 +2079,105 @@ async def client_portal_engagement_letter_upload_signed(request: Request, letter
return RedirectResponse(url="/client/engagement-letter", status_code=303)
finally:
db.close()
@router.get("/{client_id}/business-profile")
def client_business_profile_page(request: Request, client_id: int):
db = CommonSessionLocal()
try:
user = get_current_user(request, db=db)
if not user:
return RedirectResponse(url="/login", status_code=303)
has = _has_perm_factory(db, user)
if not has("clients.view"):
return _redirect_denied()
role_names = _role_names(db, user)
scope = _apply_role_scope(build_scope(request, user, has), user, role_names)
client = get_client_or_404(
db,
client_id=client_id,
tenant_id=scope.tenant_id,
branch_id=scope.branch_id,
allow_cross_branch=scope.allow_cross_branch,
allow_all_clients=scope.allow_all_clients,
viewer_partner_id=_viewer_partner_id(user, role_names),
)
profile = get_profile(db, client.id)
return _render(
request,
"modules/clients/templates/clients/business_profile.html",
db,
user,
title=f"Business Profile • {client.client_name}",
row=client,
profile=profile,
sources=list_sources(db, client.id),
business_model_options=BUSINESS_MODEL_OPTIONS,
source_type_options=SOURCE_TYPE_OPTIONS,
can_edit=has("clients.edit"),
)
finally:
db.close()
@router.post("/{client_id}/business-profile")
async def client_business_profile_update(request: Request, client_id: int):
db = CommonSessionLocal()
try:
user = get_current_user(request, db=db)
if not user:
return RedirectResponse(url="/login", status_code=303)
has = _has_perm_factory(db, user)
if not has("clients.edit"):
return _redirect_denied()
role_names = _role_names(db, user)
scope = _apply_role_scope(build_scope(request, user, has), user, role_names)
client = get_client_or_404(db, client_id=client_id, tenant_id=scope.tenant_id, branch_id=scope.branch_id, allow_cross_branch=scope.allow_cross_branch, allow_all_clients=scope.allow_all_clients, viewer_partner_id=_viewer_partner_id(user, role_names))
form = await request.form()
validate_csrf(request, form.get("csrf_token"))
update_profile(db, client=client, actor_user_id=user.id, form=form)
return RedirectResponse(url=f"/clients/{client.id}/business-profile", status_code=303)
finally:
db.close()
@router.post("/{client_id}/business-profile/confirm")
async def client_business_profile_confirm(request: Request, client_id: int):
db = CommonSessionLocal()
try:
user = get_current_user(request, db=db)
if not user:
return RedirectResponse(url="/login", status_code=303)
has = _has_perm_factory(db, user)
if not has("clients.edit"):
return _redirect_denied()
role_names = _role_names(db, user)
scope = _apply_role_scope(build_scope(request, user, has), user, role_names)
client = get_client_or_404(db, client_id=client_id, tenant_id=scope.tenant_id, branch_id=scope.branch_id, allow_cross_branch=scope.allow_cross_branch, allow_all_clients=scope.allow_all_clients, viewer_partner_id=_viewer_partner_id(user, role_names))
form = await request.form()
validate_csrf(request, form.get("csrf_token"))
confirm_profile(db, client=client, actor_user_id=user.id)
return RedirectResponse(url=f"/clients/{client.id}/business-profile", status_code=303)
finally:
db.close()
@router.post("/{client_id}/business-profile/sources")
async def client_business_profile_add_source(request: Request, client_id: int):
db = CommonSessionLocal()
try:
user = get_current_user(request, db=db)
if not user:
return RedirectResponse(url="/login", status_code=303)
has = _has_perm_factory(db, user)
if not has("clients.edit"):
return _redirect_denied()
role_names = _role_names(db, user)
scope = _apply_role_scope(build_scope(request, user, has), user, role_names)
client = get_client_or_404(db, client_id=client_id, tenant_id=scope.tenant_id, branch_id=scope.branch_id, allow_cross_branch=scope.allow_cross_branch, allow_all_clients=scope.allow_all_clients, viewer_partner_id=_viewer_partner_id(user, role_names))
form = await request.form()
validate_csrf(request, form.get("csrf_token"))
add_source(db, client=client, actor_user_id=user.id, form=form)
return RedirectResponse(url=f"/clients/{client.id}/business-profile", status_code=303)
finally:
db.close()