HH/apps/appreciation/tasks.py
2026-07-11 19:24:28 +03:00

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)}")