81 lines
2.7 KiB
Python
81 lines
2.7 KiB
Python
"""
|
|
Department contact resolution helpers.
|
|
|
|
Used by the "Send to Department" flow across modules to auto-target a
|
|
department's champion and manager (instead of asking the user to pick a
|
|
contact person). Each target is returned with the contact channels available.
|
|
"""
|
|
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _staff_contact(staff):
|
|
"""Return (email, phone) for a Staff instance, with user fallbacks."""
|
|
email = staff.email or ""
|
|
phone = staff.phone or ""
|
|
user_id = getattr(staff, "user_id", None)
|
|
if user_id:
|
|
user = getattr(staff, "user", None)
|
|
if user:
|
|
email = email or (user.email or "")
|
|
phone = phone or (getattr(user, "phone", "") or "")
|
|
return email, phone
|
|
|
|
|
|
def get_champion_and_manager(department):
|
|
"""Return a list of contact targets for a department's champion and manager.
|
|
|
|
Each item is a dict:
|
|
{
|
|
"label": "Champion" | "Manager",
|
|
"email": str, # may be ""
|
|
"phone": str, # may be ""
|
|
"staff": <Staff>|None, # present for the champion
|
|
"user": <User>|None, # present for the manager
|
|
}
|
|
|
|
Only targets that actually exist (the role FK is set) are included.
|
|
De-duplicates the case where the champion and manager are the same person.
|
|
"""
|
|
targets = []
|
|
seen_emails = set()
|
|
|
|
# Champion (a Staff)
|
|
champion = getattr(department, "champion", None)
|
|
if champion is not None:
|
|
email, phone = _staff_contact(champion)
|
|
email = email or (getattr(department, "champion_email", "") or "")
|
|
key = (email or "").lower()
|
|
if key not in seen_emails:
|
|
seen_emails.add(key)
|
|
targets.append(
|
|
{"label": "Champion", "email": email, "phone": phone, "staff": champion, "user": None}
|
|
)
|
|
|
|
# Manager (a User)
|
|
manager = getattr(department, "manager", None)
|
|
if manager is not None:
|
|
email = manager.email or ""
|
|
phone = getattr(manager, "phone", "") or ""
|
|
# If the manager also has a linked Staff profile, prefer its contact details.
|
|
staff_profile = getattr(manager, "staff_profile", None)
|
|
if staff_profile:
|
|
s_email, s_phone = _staff_contact(staff_profile)
|
|
email = email or s_email
|
|
phone = phone or s_phone
|
|
key = (email or "").lower()
|
|
if key and key not in seen_emails:
|
|
seen_emails.add(key)
|
|
targets.append(
|
|
{"label": "Manager", "email": email, "phone": phone, "staff": None, "user": manager}
|
|
)
|
|
|
|
return targets
|
|
|
|
|
|
def has_contact_target(department):
|
|
"""True if the department has at least a champion or a manager to notify."""
|
|
return bool(get_champion_and_manager(department))
|