131 lines
6.1 KiB
Python
131 lines
6.1 KiB
Python
"""Celery tasks for the appreciation module."""
|
|
import logging
|
|
|
|
from celery import shared_task
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@shared_task
|
|
def send_appreciation_notifications(
|
|
appreciation_id,
|
|
staff_id=None,
|
|
note="",
|
|
email_subject="",
|
|
email_body="",
|
|
host="",
|
|
):
|
|
"""Send email + SMS to champion, manager, and appreciated staff in the background.
|
|
|
|
Replaces the synchronous notification loop that used to block the
|
|
appreciation_send_to response.
|
|
"""
|
|
from apps.appreciation.models import Appreciation
|
|
from apps.notifications.services import NotificationService, get_email_header_html
|
|
from apps.organizations.department_contacts import get_champion_and_manager, _staff_contact
|
|
from apps.organizations.models import Staff
|
|
|
|
try:
|
|
appreciation = Appreciation.objects.select_related("department", "hospital").get(pk=appreciation_id)
|
|
except Appreciation.DoesNotExist:
|
|
logger.error(f"Appreciation {appreciation_id} not found for notification task")
|
|
return
|
|
|
|
department = appreciation.department
|
|
if not department:
|
|
logger.warning(f"Appreciation {appreciation_id} has no department, skipping notifications")
|
|
return
|
|
|
|
targets = get_champion_and_manager(department)
|
|
link = f"https://{host}/appreciation/detail/{appreciation.pk}/"
|
|
notified = []
|
|
|
|
# Notify champion + manager
|
|
for target in targets:
|
|
display_name = (
|
|
target["staff"].get_full_name() if target.get("staff")
|
|
else (target["user"].get_full_name() if target.get("user") else target["label"])
|
|
)
|
|
if target.get("email"):
|
|
try:
|
|
send_subject = email_subject or f"Appreciation Sent to Department - {appreciation.reference_number}"
|
|
send_body = email_body or (
|
|
f"Appreciation #{appreciation.reference_number} has been sent to your department ({department.name})."
|
|
)
|
|
NotificationService.send_email(
|
|
email=target["email"],
|
|
subject=send_subject,
|
|
message=send_body + f"\n\n{link}",
|
|
html_message=f"""
|
|
<div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
|
|
{get_email_header_html()}
|
|
<div style="padding: 20px;">
|
|
<h2 style="color: #005696; font-size: 18px; margin: 0 0 12px 0;">Appreciation Sent to Department</h2>
|
|
<p>Appreciation <strong>#{appreciation.reference_number}</strong> has been sent to your department <strong>({department.name})</strong>.</p>
|
|
<p><strong>Message:</strong> {appreciation.message_en or 'N/A'}</p>
|
|
{f'<p><strong>Note:</strong> {note}</p>' if note else ''}
|
|
<p><strong>Role:</strong> {target['label']}</p>
|
|
<p><a href="{link}">View Appreciation</a></p>
|
|
</div>
|
|
</div>
|
|
""",
|
|
related_object=appreciation,
|
|
)
|
|
except Exception:
|
|
logger.exception(f"Failed to send email to {target.get('email')}")
|
|
if target.get("phone"):
|
|
try:
|
|
NotificationService.send_sms(
|
|
target["phone"],
|
|
f"PX360: Appreciation #{appreciation.reference_number} sent to {department.name}. {link}",
|
|
related_object=appreciation,
|
|
)
|
|
except Exception:
|
|
pass
|
|
notified.append(f"{display_name} ({target['label']})")
|
|
|
|
# Notify the appreciated staff member
|
|
if staff_id:
|
|
try:
|
|
appreciated_staff = Staff.objects.get(id=staff_id)
|
|
except Staff.DoesNotExist:
|
|
appreciated_staff = None
|
|
|
|
if appreciated_staff:
|
|
s_email, s_phone = _staff_contact(appreciated_staff)
|
|
s_name = appreciated_staff.get_full_name()
|
|
if s_email:
|
|
try:
|
|
NotificationService.send_email(
|
|
email=s_email,
|
|
subject=f"An Appreciation Has Been Submitted About You - {appreciation.reference_number}",
|
|
message=f"An appreciation (#{appreciation.reference_number}) has been submitted about you.\n\nMessage: {appreciation.message_en or 'N/A'}\n\nView: {link}",
|
|
html_message=f"""
|
|
<div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
|
|
{get_email_header_html()}
|
|
<div style="padding: 20px;">
|
|
<h2 style="color: #005696; font-size: 18px; margin: 0 0 12px 0;">You've Been Appreciated!</h2>
|
|
<p>An appreciation <strong>#{appreciation.reference_number}</strong> has been submitted about you.</p>
|
|
<p><strong>Message:</strong> {appreciation.message_en or 'N/A'}</p>
|
|
{f'<p><strong>Note:</strong> {note}</p>' if note else ''}
|
|
<p><a href="{link}">View Appreciation</a></p>
|
|
</div>
|
|
</div>
|
|
""",
|
|
related_object=appreciation,
|
|
)
|
|
notified.append(f"{s_name} (Staff)")
|
|
except Exception:
|
|
logger.exception(f"Failed to send email to staff {s_email}")
|
|
if s_phone:
|
|
try:
|
|
NotificationService.send_sms(
|
|
s_phone,
|
|
f"PX360: An appreciation has been submitted about you. {link}",
|
|
related_object=appreciation,
|
|
)
|
|
except Exception:
|
|
pass
|
|
|
|
logger.info(f"Appreciation {appreciation_id} notifications sent to: {', '.join(notified)}")
|