Add client groups and family tracking
This commit is contained in:
@@ -11,6 +11,7 @@ from sqlalchemy import select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.modules.client_identity.service import ensure_identity, normalize_pan, placeholder_email
|
||||
from app.modules.client_groups.service import get_group_by_code, resolve_or_create_group
|
||||
from app.modules.clients import repository
|
||||
from app.modules.clients.models import Client
|
||||
from app.modules.clients.schemas import ClientCreate
|
||||
@@ -31,6 +32,11 @@ TEMPLATE_COLUMNS = [
|
||||
"referral_status",
|
||||
"communication_routing_mode",
|
||||
"branch_id",
|
||||
"client_group_code",
|
||||
"client_group_name",
|
||||
"group_type",
|
||||
"group_relationship",
|
||||
"is_group_head",
|
||||
"client_code",
|
||||
"client_name",
|
||||
"client_type",
|
||||
@@ -75,6 +81,7 @@ TEMPLATE_COLUMNS = [
|
||||
]
|
||||
|
||||
BOOL_FIELDS = {
|
||||
"is_group_head",
|
||||
"gst_applicable",
|
||||
"income_tax_applicable",
|
||||
"tds_applicable",
|
||||
@@ -239,6 +246,11 @@ def build_client_import_template_bytes(*, current_user, tenant_id: int, partner_
|
||||
"partner_user_id": "Must be an active Partner user in the same firm.",
|
||||
"referred_by_consultant_id": "Optional active consultant profile id who introduced the client.",
|
||||
"primary_consultant_id": "Optional active consultant profile id for the operational client link.",
|
||||
"client_group_code": "Optional tenant-unique group code. Existing group is matched by this code.",
|
||||
"client_group_name": "Required only when creating a new group during import.",
|
||||
"group_type": "Family, Business Group, Promoter Group, Trust Group, Common Management, or Other.",
|
||||
"group_relationship": "Optional relationship such as Spouse, HUF, Company, Trust, or Related Concern.",
|
||||
"is_group_head": "yes/no. Only one group head is recommended per group.",
|
||||
"referral_date": "Optional referral date supported by the existing client schema.",
|
||||
"referral_reference": "Optional referral or source reference.",
|
||||
"referral_status": "active, inactive, ended, or pending.",
|
||||
@@ -407,6 +419,9 @@ def build_preview(
|
||||
"tenant_id": firm_tenant_id,
|
||||
"branch_id": branch_id,
|
||||
"partner_id": partner_user_id or None,
|
||||
"client_group_id": None,
|
||||
"group_relationship": cleaned.get("group_relationship"),
|
||||
"is_group_head": bool(cleaned.get("is_group_head")),
|
||||
"referred_by_consultant_id": referred_id,
|
||||
"primary_consultant_id": primary_id,
|
||||
"referral_date": cleaned.get("referral_date"),
|
||||
@@ -470,6 +485,9 @@ def build_preview(
|
||||
"tenant_id": firm_tenant_id,
|
||||
"branch_id": branch_id,
|
||||
"partner_id": partner_user_id,
|
||||
"client_group_code": cleaned.get("client_group_code"),
|
||||
"client_group_name": cleaned.get("client_group_name"),
|
||||
"group_type": cleaned.get("group_type") or "Family",
|
||||
"client_payload": payload,
|
||||
"portal_password": password,
|
||||
"portal_password_confirm": password_confirm,
|
||||
@@ -530,6 +548,16 @@ def commit_import(
|
||||
if existing_user:
|
||||
raise ValueError("Email is already used by another ERP login.")
|
||||
|
||||
group = resolve_or_create_group(
|
||||
db, tenant_id=int(payload["tenant_id"]), actor_user_id=current_user.id,
|
||||
group_code=item.get("client_group_code"), group_name=item.get("client_group_name"), group_type=item.get("group_type"),
|
||||
)
|
||||
payload["client_group_id"] = group.id if group else None
|
||||
if group and payload.get("is_group_head"):
|
||||
existing_head = db.execute(select(Client).where(Client.tenant_id == int(payload["tenant_id"]), Client.client_group_id == group.id, Client.is_group_head.is_(True))).scalar_one_or_none()
|
||||
if existing_head:
|
||||
raise ValueError(f"Group {group.group_code} already has group head {existing_head.client_code} - {existing_head.client_name}.")
|
||||
|
||||
data = ClientCreate(**payload)
|
||||
row = create_client_service(
|
||||
db,
|
||||
|
||||
Reference in New Issue
Block a user