107 lines
7.4 KiB
Python
107 lines
7.4 KiB
Python
from __future__ import annotations
|
|
|
|
from fastapi import APIRouter, Request
|
|
from fastapi.responses import RedirectResponse
|
|
|
|
from app.core.db.common import CommonSessionLocal
|
|
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.core.rbac.permission_guard import require_permission
|
|
from app.modules.client_groups.service import GROUP_TYPES, create_group, get_group, list_group_clients, list_groups, update_group
|
|
from app.modules.clients.access import build_scope, enforce_partner_scope, is_partner_role
|
|
from app.modules.clients import repository
|
|
from app.modules.consultants.service import list_consultants
|
|
|
|
router = APIRouter(prefix="/client-groups", tags=["client-groups-ui"])
|
|
|
|
def _roles(db, user):
|
|
return {str(name).strip().lower() for name in get_user_roles(db, user.id)}
|
|
|
|
def _scope(request, user, db):
|
|
roles = _roles(db, user)
|
|
scope = build_scope(request, user, lambda code: code in set(get_user_permissions(db, user.id)))
|
|
return enforce_partner_scope(scope, user=user, role_names=roles), roles
|
|
|
|
|
|
def _ctx(request, user, db, **extra):
|
|
data={"request":request,"current_user":user,"current_user_roles":get_user_roles(db,user.id),"current_user_permissions":get_user_permissions(db,user.id),"csrf_token":get_or_create_csrf_token(request)}; data.update(extra); return data
|
|
|
|
|
|
def _payload(form):
|
|
def opt_int(name):
|
|
value=form.get(name); return int(value) if value not in (None,"","None") else None
|
|
return {"group_code":form.get("group_code"),"group_name":form.get("group_name"),"group_type":form.get("group_type") or "Family","primary_contact_name":form.get("primary_contact_name"),"primary_contact_mobile":form.get("primary_contact_mobile"),"primary_contact_email":form.get("primary_contact_email"),"assigned_partner_user_id":opt_int("assigned_partner_user_id"),"primary_consultant_id":opt_int("primary_consultant_id"),"notes":form.get("notes"),"is_active":form.get("is_active") in ("1","on","true","yes")}
|
|
|
|
@router.get("")
|
|
def groups_page(request: Request):
|
|
db=CommonSessionLocal()
|
|
try:
|
|
user=get_current_user(request,db=db)
|
|
if not user: return RedirectResponse('/login',303)
|
|
require_permission(db,user,'clients.view'); scope, roles=_scope(request,user,db)
|
|
return templates.TemplateResponse('modules/client_groups/templates/client_groups/list.html',_ctx(request,user,db,title='Client Groups',groups=list_groups(db,tenant_id=scope.tenant_id,include_inactive=True,viewer_partner_id=user.id if is_partner_role(roles) else None)))
|
|
finally: db.close()
|
|
|
|
@router.get("/new")
|
|
def group_new(request: Request):
|
|
db=CommonSessionLocal()
|
|
try:
|
|
user=get_current_user(request,db=db)
|
|
if not user: return RedirectResponse('/login',303)
|
|
require_permission(db,user,'clients.create'); scope, roles=_scope(request,user,db)
|
|
return templates.TemplateResponse('modules/client_groups/templates/client_groups/form.html',_ctx(request,user,db,title='Add Client Group',row=None,group_types=GROUP_TYPES,partners=([repository.get_partner(db,user.id)] if is_partner_role(roles) else repository.list_partners_for_scope(db,tenant_id=scope.tenant_id,branch_id=None)),consultants=list_consultants(db,tenant_id=scope.tenant_id,include_inactive=False),errors=[]))
|
|
finally: db.close()
|
|
|
|
@router.post("")
|
|
async def group_create(request: Request):
|
|
db=CommonSessionLocal()
|
|
try:
|
|
user=get_current_user(request,db=db); form=await request.form(); validate_csrf(request,form.get('csrf_token'))
|
|
if not user: return RedirectResponse('/login',303)
|
|
require_permission(db,user,'clients.create'); scope, roles=_scope(request,user,db)
|
|
try:
|
|
payload=_payload(form)
|
|
if is_partner_role(roles): payload["assigned_partner_user_id"] = user.id
|
|
row=create_group(db,tenant_id=scope.tenant_id,actor_user_id=user.id,payload=payload); return RedirectResponse(f'/client-groups/{row.id}',303)
|
|
except Exception as exc: return templates.TemplateResponse('modules/client_groups/templates/client_groups/form.html',_ctx(request,user,db,title='Add Client Group',row=_payload(form),group_types=GROUP_TYPES,partners=([repository.get_partner(db,user.id)] if is_partner_role(roles) else repository.list_partners_for_scope(db,tenant_id=scope.tenant_id,branch_id=None)),consultants=list_consultants(db,tenant_id=scope.tenant_id,include_inactive=False),errors=[str(exc)]),status_code=400)
|
|
finally: db.close()
|
|
|
|
@router.get("/{group_id}")
|
|
def group_detail(request: Request, group_id:int):
|
|
db=CommonSessionLocal()
|
|
try:
|
|
user=get_current_user(request,db=db)
|
|
if not user: return RedirectResponse('/login',303)
|
|
require_permission(db,user,'clients.view'); scope, roles=_scope(request,user,db); row=get_group(db,tenant_id=scope.tenant_id,group_id=group_id)
|
|
if not row: return RedirectResponse('/client-groups',303)
|
|
return templates.TemplateResponse('modules/client_groups/templates/client_groups/detail.html',_ctx(request,user,db,title=row.group_name,row=row,clients=list_group_clients(db,tenant_id=scope.tenant_id,group_id=row.id,viewer_partner_id=user.id if is_partner_role(roles) else None)))
|
|
finally: db.close()
|
|
|
|
@router.get("/{group_id}/edit")
|
|
def group_edit(request: Request, group_id:int):
|
|
db=CommonSessionLocal()
|
|
try:
|
|
user=get_current_user(request,db=db)
|
|
if not user: return RedirectResponse('/login',303)
|
|
require_permission(db,user,'clients.edit'); scope, roles=_scope(request,user,db); row=get_group(db,tenant_id=scope.tenant_id,group_id=group_id)
|
|
if not row: return RedirectResponse('/client-groups',303)
|
|
return templates.TemplateResponse('modules/client_groups/templates/client_groups/form.html',_ctx(request,user,db,title='Edit Client Group',row=row,group_types=GROUP_TYPES,partners=([repository.get_partner(db,user.id)] if is_partner_role(roles) else repository.list_partners_for_scope(db,tenant_id=scope.tenant_id,branch_id=None)),consultants=list_consultants(db,tenant_id=scope.tenant_id,include_inactive=False),errors=[]))
|
|
finally: db.close()
|
|
|
|
@router.post("/{group_id}/edit")
|
|
async def group_update(request: Request, group_id:int):
|
|
db=CommonSessionLocal()
|
|
try:
|
|
user=get_current_user(request,db=db); form=await request.form(); validate_csrf(request,form.get('csrf_token'))
|
|
if not user: return RedirectResponse('/login',303)
|
|
require_permission(db,user,'clients.edit'); scope, roles=_scope(request,user,db); row=get_group(db,tenant_id=scope.tenant_id,group_id=group_id)
|
|
if not row: return RedirectResponse('/client-groups',303)
|
|
try:
|
|
payload=_payload(form)
|
|
if is_partner_role(roles): payload["assigned_partner_user_id"] = user.id
|
|
update_group(db,row=row,actor_user_id=user.id,payload=payload); return RedirectResponse(f'/client-groups/{row.id}',303)
|
|
except Exception as exc: return templates.TemplateResponse('modules/client_groups/templates/client_groups/form.html',_ctx(request,user,db,title='Edit Client Group',row=row,group_types=GROUP_TYPES,partners=([repository.get_partner(db,user.id)] if is_partner_role(roles) else repository.list_partners_for_scope(db,tenant_id=scope.tenant_id,branch_id=None)),consultants=list_consultants(db,tenant_id=scope.tenant_id,include_inactive=False),errors=[str(exc)]),status_code=400)
|
|
finally: db.close()
|