118 lines
5.4 KiB
Python
118 lines
5.4 KiB
Python
from django.db.models.signals import post_save
|
|
from django.dispatch import receiver
|
|
from channels.layers import get_channel_layer
|
|
from asgiref.sync import async_to_sync
|
|
from django.contrib.contenttypes.models import ContentType
|
|
|
|
from .models import Ticket, TicketComment
|
|
from notifications.models import Notification # Assuming notifications app is installed
|
|
|
|
@receiver(post_save, sender=Ticket)
|
|
def ticket_notification_handler(sender, instance, created, **kwargs):
|
|
channel_layer = get_channel_layer()
|
|
|
|
# Logic for Ticket assignment and status change
|
|
if not created: # Only on update
|
|
# Get old instance (this is tricky with post_save, usually requires pre_save)
|
|
# For simplicity, we'll assume the instance passed is the new state,
|
|
# and compare against previous state if we had it.
|
|
# For now, let's just trigger on any save after creation, and focus on assignee.
|
|
|
|
# Notify assignee if changed
|
|
if instance.assignee:
|
|
# Check if assignee actually changed (requires pre_save or a custom field for old value)
|
|
# For this iteration, let's just notify the assignee on any update to the ticket they are assigned to
|
|
# Or if it's a new assignment.
|
|
|
|
# Create Notification object for the assignee
|
|
Notification.objects.create(
|
|
recipient=instance.assignee,
|
|
actor=instance.creator, # The one who created the ticket (can be updated later)
|
|
verb=f"Ticket #{instance.id} '{instance.subject}' was updated.",
|
|
action_object=instance,
|
|
target=instance,
|
|
data={'ticket_id': instance.id, 'subject': instance.subject, 'status': instance.status}
|
|
)
|
|
|
|
# Send WebSocket message to assignee's personal channel
|
|
async_to_sync(channel_layer.group_send)(
|
|
f"user_{instance.assignee.id}",
|
|
{
|
|
"type": "notification_message",
|
|
"message": {
|
|
"type": "ticket_update",
|
|
"ticket_id": instance.id,
|
|
"subject": instance.subject,
|
|
"status": instance.status,
|
|
"assignee_id": str(instance.assignee.id),
|
|
"message": f"Ticket #{instance.id} '{instance.subject}' updated. Status: {instance.status}"
|
|
}
|
|
}
|
|
)
|
|
|
|
# General notification for tenant/platform admins (if needed)
|
|
# This might be too broad, usually target specific groups/users
|
|
pass
|
|
|
|
|
|
@receiver(post_save, sender=TicketComment)
|
|
def comment_notification_handler(sender, instance, created, **kwargs):
|
|
if created:
|
|
channel_layer = get_channel_layer()
|
|
ticket = instance.ticket
|
|
|
|
# Notify creator of the ticket (if not the commenter)
|
|
if ticket.creator and ticket.creator != instance.author:
|
|
# Create Notification object for the ticket creator
|
|
Notification.objects.create(
|
|
recipient=ticket.creator,
|
|
actor=instance.author,
|
|
verb=f"New comment on your ticket #{ticket.id} '{ticket.subject}'.",
|
|
action_object=instance,
|
|
target=ticket,
|
|
data={'ticket_id': ticket.id, 'subject': ticket.subject, 'comment_id': instance.id}
|
|
)
|
|
|
|
# Send WebSocket message to creator's personal channel
|
|
async_to_sync(channel_layer.group_send)(
|
|
f"user_{ticket.creator.id}",
|
|
{
|
|
"type": "notification_message",
|
|
"message": {
|
|
"type": "new_comment",
|
|
"ticket_id": ticket.id,
|
|
"subject": ticket.subject,
|
|
"comment_id": instance.id,
|
|
"author_name": instance.author.full_name,
|
|
"message": f"New comment on your ticket #{ticket.id} from {instance.author.full_name}."
|
|
}
|
|
}
|
|
)
|
|
|
|
# Notify assignee of the ticket (if not the commenter and not the creator)
|
|
if ticket.assignee and ticket.assignee != instance.author and ticket.assignee != ticket.creator:
|
|
# Create Notification object for the ticket assignee
|
|
Notification.objects.create(
|
|
recipient=ticket.assignee,
|
|
actor=instance.author,
|
|
verb=f"New comment on ticket #{ticket.id} '{ticket.subject}' you are assigned to.",
|
|
action_object=instance,
|
|
target=ticket,
|
|
data={'ticket_id': ticket.id, 'subject': ticket.subject, 'comment_id': instance.id}
|
|
)
|
|
# Send WebSocket message to assignee's personal channel
|
|
async_to_sync(channel_layer.group_send)(
|
|
f"user_{ticket.assignee.id}",
|
|
{
|
|
"type": "notification_message",
|
|
"message": {
|
|
"type": "new_comment",
|
|
"ticket_id": ticket.id,
|
|
"subject": ticket.subject,
|
|
"comment_id": instance.id,
|
|
"author_name": instance.author.full_name,
|
|
"message": f"New comment on ticket #{ticket.id} you are assigned to from {instance.author.full_name}."
|
|
}
|
|
}
|
|
)
|