Add consultant onboarding for firm administrators
This commit is contained in:
@@ -18,6 +18,7 @@ from app.modules.core.rbac.models import Role, UserRole
|
||||
from app.modules.core.tenancy.models import Branch, FinancialYear, Tenant
|
||||
from app.modules.clients.models import Client
|
||||
from app.modules.employees.models import Employee
|
||||
from app.modules.consultants.models import ConsultantProfile
|
||||
from app.modules.services.models import (
|
||||
FirmServiceSelection,
|
||||
FirmServiceTaskTemplate,
|
||||
@@ -268,6 +269,7 @@ ONBOARDING_ROLE_CONFIG: dict[str, dict[str, str]] = {
|
||||
"default_designation": "Partner",
|
||||
"default_department": "Management",
|
||||
"default_employment_type": "full_time",
|
||||
"requires_employee": True,
|
||||
},
|
||||
"manager": {
|
||||
"role_name": "Branch Manager",
|
||||
@@ -275,6 +277,7 @@ ONBOARDING_ROLE_CONFIG: dict[str, dict[str, str]] = {
|
||||
"default_designation": "Branch Manager",
|
||||
"default_department": "Operations",
|
||||
"default_employment_type": "full_time",
|
||||
"requires_employee": True,
|
||||
},
|
||||
"staff": {
|
||||
"role_name": "Staff",
|
||||
@@ -282,6 +285,15 @@ ONBOARDING_ROLE_CONFIG: dict[str, dict[str, str]] = {
|
||||
"default_designation": "Staff",
|
||||
"default_department": "Operations",
|
||||
"default_employment_type": "full_time",
|
||||
"requires_employee": True,
|
||||
},
|
||||
"consultant": {
|
||||
"role_name": "Consultant",
|
||||
"label": "Consultant",
|
||||
"default_designation": "Consultant",
|
||||
"default_department": "Consulting",
|
||||
"default_employment_type": "consultant",
|
||||
"requires_employee": False,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -447,6 +459,13 @@ def create_firm_internal_user(
|
||||
designation: str | None = None,
|
||||
date_of_joining: str | None = None,
|
||||
employment_type: str | None = None,
|
||||
consultant_type: str | None = None,
|
||||
firm_name: str | None = None,
|
||||
specialisation: str | None = None,
|
||||
gstin: str | None = None,
|
||||
pan: str | None = None,
|
||||
address: str | None = None,
|
||||
remarks: str | None = None,
|
||||
) -> dict[str, Any]:
|
||||
actor_roles = set(get_user_role_names(db, actor.id))
|
||||
if not actor_roles.intersection(FIRM_ADMIN_ROLES):
|
||||
@@ -501,17 +520,60 @@ def create_firm_internal_user(
|
||||
db.flush()
|
||||
db.add(UserRole(user_id=user.id, role_id=role.id))
|
||||
|
||||
employee_link_result = _ensure_employee_for_onboarded_user(
|
||||
db,
|
||||
actor=actor,
|
||||
user_obj=user,
|
||||
employee_code=employee_code,
|
||||
mobile=mobile,
|
||||
department=(department or config.get("default_department") or ""),
|
||||
designation=(designation or config.get("default_designation") or ""),
|
||||
date_of_joining=date_of_joining,
|
||||
employment_type=(employment_type or config.get("default_employment_type") or "full_time"),
|
||||
)
|
||||
consultant_profile = None
|
||||
if role_key == "consultant":
|
||||
duplicate_profile = db.execute(
|
||||
select(ConsultantProfile).where(
|
||||
ConsultantProfile.tenant_id == int(tenant_id),
|
||||
ConsultantProfile.email == email_clean,
|
||||
)
|
||||
).scalar_one_or_none()
|
||||
if duplicate_profile:
|
||||
raise ValueError("A consultant profile with this email already exists in this firm.")
|
||||
|
||||
consultant_profile = ConsultantProfile(
|
||||
tenant_id=int(tenant_id),
|
||||
branch_id=int(branch.id),
|
||||
user_id=int(user.id),
|
||||
consultant_type=(consultant_type or "external_consultant").strip() or "external_consultant",
|
||||
firm_name=(firm_name or "").strip() or None,
|
||||
contact_person=name_clean,
|
||||
email=email_clean,
|
||||
mobile=(mobile or "").strip() or None,
|
||||
specialisation=(specialisation or "").strip() or None,
|
||||
gstin=(gstin or "").strip().upper() or None,
|
||||
pan=(pan or "").strip().upper() or None,
|
||||
address=(address or "").strip() or None,
|
||||
status="active",
|
||||
onboarding_status="invited",
|
||||
is_platform_partner=False,
|
||||
is_franchise_partner=False,
|
||||
is_saas_customer=False,
|
||||
is_active=True,
|
||||
remarks=(remarks or "").strip() or None,
|
||||
created_by_user_id=actor.id,
|
||||
updated_by_user_id=actor.id,
|
||||
)
|
||||
db.add(consultant_profile)
|
||||
db.flush()
|
||||
employee_link_result = {
|
||||
"required": False,
|
||||
"created": False,
|
||||
"linked_existing": False,
|
||||
"employee_id": None,
|
||||
}
|
||||
else:
|
||||
employee_link_result = _ensure_employee_for_onboarded_user(
|
||||
db,
|
||||
actor=actor,
|
||||
user_obj=user,
|
||||
employee_code=employee_code,
|
||||
mobile=mobile,
|
||||
department=(department or config.get("default_department") or ""),
|
||||
designation=(designation or config.get("default_designation") or ""),
|
||||
date_of_joining=date_of_joining,
|
||||
employment_type=(employment_type or config.get("default_employment_type") or "full_time"),
|
||||
)
|
||||
|
||||
try:
|
||||
db.commit()
|
||||
@@ -540,6 +602,7 @@ def create_firm_internal_user(
|
||||
"role_label": config["label"],
|
||||
"branch": branch,
|
||||
"employee_link_result": employee_link_result,
|
||||
"consultant_profile": consultant_profile,
|
||||
"invite_url": invite_url,
|
||||
"email_status": email_status,
|
||||
"email_error": email_error,
|
||||
|
||||
Reference in New Issue
Block a user