Add phase 1 client consultant referral and linkage
This commit is contained in:
@@ -162,6 +162,19 @@ class ClientConsultantLink(CommonBase):
|
||||
can_view_services: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
||||
can_view_due_dates: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
||||
can_view_communications: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
||||
can_view_engagements: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
||||
can_view_task_status: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
||||
can_view_assignee: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
||||
can_view_document_requests: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
||||
can_upload_documents: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
||||
can_reply_to_clarifications: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
||||
can_view_filing_details: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
||||
can_view_final_documents: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
||||
can_view_permanent_documents: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
|
||||
can_receive_notifications: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
||||
can_act_for_client: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
|
||||
effective_from: Mapped[date | None] = mapped_column(Date, nullable=True)
|
||||
effective_to: Mapped[date | None] = mapped_column(Date, nullable=True)
|
||||
is_active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True, index=True)
|
||||
remarks: Mapped[str | None] = mapped_column(Text, nullable=True)
|
||||
|
||||
|
||||
@@ -1388,3 +1388,75 @@ def reject_managed_client_conversion(
|
||||
managed_client.conversion_firm_notes = normalise_text(firm_notes)
|
||||
managed_client.updated_by_user_id = user_id
|
||||
return managed_client
|
||||
|
||||
|
||||
def get_primary_client_consultant_link(db: Session, *, tenant_id: int, client_id: int) -> ClientConsultantLink | None:
|
||||
return db.execute(
|
||||
select(ClientConsultantLink)
|
||||
.where(
|
||||
ClientConsultantLink.tenant_id == tenant_id,
|
||||
ClientConsultantLink.client_id == client_id,
|
||||
ClientConsultantLink.is_primary.is_(True),
|
||||
ClientConsultantLink.is_active.is_(True),
|
||||
)
|
||||
.order_by(ClientConsultantLink.id.asc())
|
||||
).scalars().first()
|
||||
|
||||
|
||||
def sync_primary_client_consultant_link(
|
||||
db: Session, *, client: Client, consultant_id: int | None, actor_user_id: int
|
||||
) -> ClientConsultantLink | None:
|
||||
"""Synchronise the client's unrestricted primary consultant link without deleting history."""
|
||||
links = db.execute(
|
||||
select(ClientConsultantLink).where(
|
||||
ClientConsultantLink.tenant_id == client.tenant_id,
|
||||
ClientConsultantLink.client_id == client.id,
|
||||
)
|
||||
).scalars().all()
|
||||
selected = None
|
||||
for link in links:
|
||||
if consultant_id and int(link.consultant_id) == int(consultant_id) and link.service_catalogue_id is None:
|
||||
selected = link
|
||||
elif link.is_primary:
|
||||
link.is_primary = False
|
||||
link.updated_by_user_id = actor_user_id
|
||||
if consultant_id is None:
|
||||
db.flush()
|
||||
return None
|
||||
consultant = get_consultant(db, tenant_id=int(client.tenant_id), consultant_id=int(consultant_id))
|
||||
if not consultant or not consultant.is_active:
|
||||
raise ValueError("Selected primary consultant is not active in this firm.")
|
||||
if selected is None:
|
||||
selected = ClientConsultantLink(
|
||||
tenant_id=client.tenant_id, branch_id=client.branch_id, client_id=client.id,
|
||||
consultant_id=consultant.id, service_catalogue_id=None,
|
||||
relationship_type="accounts_consultant", is_primary=True, is_active=True,
|
||||
can_view_client=True, can_view_services=True, can_view_due_dates=True,
|
||||
can_view_communications=True, can_view_engagements=True, can_view_task_status=True,
|
||||
can_view_assignee=True, can_view_document_requests=True, can_upload_documents=True,
|
||||
can_reply_to_clarifications=True, can_view_filing_details=True,
|
||||
can_view_final_documents=True, can_view_permanent_documents=False,
|
||||
can_receive_notifications=True, can_act_for_client=True,
|
||||
effective_from=getattr(client, "referral_date", None) or date.today(),
|
||||
created_by_user_id=actor_user_id, updated_by_user_id=actor_user_id,
|
||||
)
|
||||
db.add(selected)
|
||||
else:
|
||||
selected.branch_id = client.branch_id
|
||||
selected.is_primary = True
|
||||
selected.is_active = True
|
||||
selected.updated_by_user_id = actor_user_id
|
||||
db.flush()
|
||||
return selected
|
||||
|
||||
|
||||
def get_client_consultant_summary(db: Session, *, tenant_id: int, client_id: int) -> dict:
|
||||
primary = get_primary_client_consultant_link(db, tenant_id=tenant_id, client_id=client_id)
|
||||
referred_id = db.execute(select(Client.referred_by_consultant_id).where(Client.id == client_id)).scalar_one_or_none()
|
||||
ids = {int(x) for x in (getattr(primary, "consultant_id", None), referred_id) if x}
|
||||
profiles = db.execute(select(ConsultantProfile).where(ConsultantProfile.id.in_(ids))).scalars().all() if ids else []
|
||||
by_id = {int(x.id): x for x in profiles}
|
||||
return {
|
||||
"primary": by_id.get(int(primary.consultant_id)) if primary else None,
|
||||
"referred_by": by_id.get(int(referred_id)) if referred_id else None,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user