Allow partners to add staff or branch managers

This commit is contained in:
A R R R Associates
2026-08-04 22:59:18 +05:30
parent da8f49fe0a
commit 9abe68d695
3 changed files with 47 additions and 14 deletions
+29 -7
View File
@@ -292,12 +292,16 @@ def create_employee(db: Session, actor: User, scope: EmployeeScope, data: dict[s
cleaned = _clean_payload(data)
partner_staff_mode = bool(scope.is_partner and not scope.is_system_admin and not scope.is_firm_admin)
# Partners can create staff only in their own tenant and branch. Never trust
# tenant, branch or role values posted by the browser for this workflow.
# Partners can create Staff or Branch Manager users only in their own
# tenant and branch. Never trust tenant or branch values posted by the
# browser for this workflow, and validate the requested role server-side.
if partner_staff_mode:
cleaned["tenant_id"] = scope.tenant_id
cleaned["branch_id"] = scope.branch_id or actor.branch_id
cleaned["employee_role"] = "Staff"
requested_role = (cleaned.get("employee_role") or "Staff").strip()
if requested_role not in {"Staff", "Branch Manager"}:
raise HTTPException(status_code=403, detail="Partners can create only Staff or Branch Manager users.")
cleaned["employee_role"] = requested_role
tenant_id = int(cleaned.get("tenant_id") or scope.tenant_id)
branch_id = int(cleaned.get("branch_id") or actor.branch_id)
@@ -322,9 +326,10 @@ def create_employee(db: Session, actor: User, scope: EmployeeScope, data: dict[s
raise HTTPException(status_code=400, detail="Selected user must belong to the employee tenant and branch.")
if partner_staff_mode:
linked_roles = _role_set(db, linked_user)
elevated_roles = {"System Admin", "Firm Admin", "Partner", "Branch Manager"}
if "Staff" not in linked_roles or linked_roles.intersection(elevated_roles):
raise HTTPException(status_code=403, detail="Partners can link only a Staff login user.")
allowed_roles = {"Staff", "Branch Manager"}
prohibited_roles = {"System Admin", "Firm Admin", "Partner"}
if not linked_roles.intersection(allowed_roles) or linked_roles.intersection(prohibited_roles):
raise HTTPException(status_code=403, detail="Partners can link only a Staff or Branch Manager login user.")
user_id = linked_user.id
elif cleaned.get("create_login_user"):
login_user = create_login_user_for_employee(
@@ -505,7 +510,24 @@ def link_employee_to_user(db: Session, actor: User, emp: Employee, user_id: int
def list_reporting_managers(db: Session, scope: EmployeeScope) -> list[User]:
stmt = select(User).where(User.tenant_id == scope.tenant_id, User.deleted_at.is_(None), User.is_active.is_(True))
"""Return only active Partner and Branch Manager users in scope.
Client and other non-employee login roles must never appear in the
Reporting Manager dropdown.
"""
stmt = (
select(User)
.join(UserRole, UserRole.user_id == User.id)
.join(Role, Role.id == UserRole.role_id)
.where(
User.tenant_id == scope.tenant_id,
User.deleted_at.is_(None),
User.is_active.is_(True),
Role.is_active.is_(True),
Role.name.in_(("Partner", "Branch Manager")),
)
.distinct()
)
if scope.branch_id is not None:
stmt = stmt.where(User.branch_id == scope.branch_id)
return db.execute(stmt.order_by(User.full_name, User.email)).scalars().all()