Add compact searchable consultant client list
This commit is contained in:
@@ -326,6 +326,122 @@ def list_client_links_for_consultant(db: Session, *, consultant_id: int) -> list
|
||||
).scalars().all()
|
||||
|
||||
|
||||
def consultant_linked_clients_page(
|
||||
db: Session,
|
||||
*,
|
||||
consultant: ConsultantProfile,
|
||||
q: str = "",
|
||||
client_group_id: int | None = None,
|
||||
status: str = "active",
|
||||
page: int = 1,
|
||||
per_page: int = 25,
|
||||
sort_by: str = "client_name",
|
||||
sort_order: str = "asc",
|
||||
) -> dict:
|
||||
"""Return a compact, searchable and paginated list of linked firm clients.
|
||||
|
||||
Link permission columns remain unchanged and continue to govern the existing
|
||||
service, due-date, communication and document workflows. They are deliberately
|
||||
not exposed in the client-list UI.
|
||||
"""
|
||||
q = (q or "").strip()
|
||||
status = (status or "").strip().lower()
|
||||
per_page = min(max(int(per_page or 25), 1), 100)
|
||||
page = max(int(page or 1), 1)
|
||||
|
||||
stmt = (
|
||||
select(ClientConsultantLink, Client, ClientGroup)
|
||||
.join(Client, Client.id == ClientConsultantLink.client_id)
|
||||
.outerjoin(ClientGroup, ClientGroup.id == Client.client_group_id)
|
||||
.where(
|
||||
ClientConsultantLink.tenant_id == consultant.tenant_id,
|
||||
ClientConsultantLink.consultant_id == consultant.id,
|
||||
ClientConsultantLink.is_active.is_(True),
|
||||
Client.tenant_id == consultant.tenant_id,
|
||||
Client.is_archived.is_(False),
|
||||
)
|
||||
)
|
||||
if status:
|
||||
stmt = stmt.where(Client.status == status)
|
||||
if client_group_id:
|
||||
stmt = stmt.where(Client.client_group_id == int(client_group_id))
|
||||
if q:
|
||||
like = f"%{q}%"
|
||||
stmt = stmt.where(
|
||||
or_(
|
||||
Client.client_code.ilike(like),
|
||||
Client.client_name.ilike(like),
|
||||
Client.trade_name.ilike(like),
|
||||
Client.pan.ilike(like),
|
||||
Client.gstin.ilike(like),
|
||||
ClientGroup.group_name.ilike(like),
|
||||
ClientGroup.group_code.ilike(like),
|
||||
)
|
||||
)
|
||||
|
||||
total = int(db.execute(select(func.count()).select_from(stmt.subquery())).scalar_one() or 0)
|
||||
pages = max(ceil(total / per_page), 1)
|
||||
page = min(page, pages)
|
||||
|
||||
sort_columns = {
|
||||
"client_code": Client.client_code,
|
||||
"client_name": Client.client_name,
|
||||
"pan": Client.pan,
|
||||
"client_group": ClientGroup.group_name,
|
||||
"status": Client.status,
|
||||
}
|
||||
sort_column = sort_columns.get(sort_by, Client.client_name)
|
||||
ordering = sort_column.desc() if (sort_order or "asc").lower() == "desc" else sort_column.asc()
|
||||
|
||||
rows = []
|
||||
result = db.execute(
|
||||
stmt.order_by(ordering, Client.id.asc())
|
||||
.offset((page - 1) * per_page)
|
||||
.limit(per_page)
|
||||
).all()
|
||||
for link, client, group in result:
|
||||
rows.append({
|
||||
"link": link,
|
||||
"client": client,
|
||||
"client_group_id": getattr(group, "id", None),
|
||||
"client_group_code": getattr(group, "group_code", None),
|
||||
"client_group_name": getattr(group, "group_name", None),
|
||||
"relationship_label": (link.relationship_type or "accounts_consultant").replace("_", " ").title(),
|
||||
})
|
||||
|
||||
groups_stmt = (
|
||||
select(ClientGroup.id, ClientGroup.group_code, ClientGroup.group_name)
|
||||
.join(Client, Client.client_group_id == ClientGroup.id)
|
||||
.join(ClientConsultantLink, ClientConsultantLink.client_id == Client.id)
|
||||
.where(
|
||||
ClientConsultantLink.tenant_id == consultant.tenant_id,
|
||||
ClientConsultantLink.consultant_id == consultant.id,
|
||||
ClientConsultantLink.is_active.is_(True),
|
||||
Client.tenant_id == consultant.tenant_id,
|
||||
Client.is_archived.is_(False),
|
||||
ClientGroup.is_active.is_(True),
|
||||
)
|
||||
.distinct()
|
||||
.order_by(ClientGroup.group_name.asc())
|
||||
)
|
||||
groups = [
|
||||
{"id": int(group_id), "code": code, "name": name}
|
||||
for group_id, code, name in db.execute(groups_stmt).all()
|
||||
]
|
||||
return {
|
||||
"rows": rows,
|
||||
"groups": groups,
|
||||
"meta": {"total": total, "page": page, "per_page": per_page, "pages": pages},
|
||||
"filters": {
|
||||
"q": q,
|
||||
"client_group_id": client_group_id,
|
||||
"status": status,
|
||||
"sort_by": sort_by if sort_by in sort_columns else "client_name",
|
||||
"sort_order": "desc" if (sort_order or "asc").lower() == "desc" else "asc",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def link_client_to_consultant(
|
||||
db: Session,
|
||||
*,
|
||||
|
||||
Reference in New Issue
Block a user