""" Signals for QI Projects. - Sends a notification when a task is assigned. """ import logging from django.db.models.signals import post_save from django.dispatch import receiver logger = logging.getLogger(__name__) @receiver(post_save, sender="projects.QIProjectTask") def notify_task_assignment(sender, instance, created, **kwargs): """Notify the assignee when a QI task is assigned (email + in-app). Fires only on new task creation with an assignee. send_email also creates the matching in-app notification, so no separate call is needed. """ if not instance.assigned_to: return # Only notify on new assignments (creation with an assignee) if not created: return user = getattr(instance.assigned_to, "user", None) if not user or not getattr(user, "email", None): return try: from django.conf import settings from apps.notifications.services import NotificationService project_url = f"{getattr(settings, 'SITE_URL', 'http://localhost:8000').rstrip('/')}/projects/{instance.project.id}/" due = instance.due_date.strftime("%Y-%m-%d") if instance.due_date else None message = f"You have been assigned a task in project '{instance.project.name}'." if due: message += f"\nDue date: {due}" message += f"\n\nTask: {instance.title}\nOpen: {project_url}" html_message = f"""

New QI Task Assigned

You have been assigned a task in project {instance.project.name}.

Task: {instance.title}

{'

Due date: ' + due + '

' if due else ''}
Open Project
""" NotificationService.send_email( email=user.email, subject=f"New QI Task: {instance.title}", message=message, html_message=html_message, related_object=instance, metadata={ "notification_type": "qi_task_assigned", "task_id": str(instance.id), "project_id": str(instance.project.id), }, notification_type="qi_task_assigned", user=user, ) except Exception as e: logger.warning(f"Failed to send QI task notification: {e}")