You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
6.8 KiB
Python

from channels.generic.websocket import WebsocketConsumer
from django.shortcuts import get_object_or_404
from .models import *
import json
from django.template.loader import render_to_string
from asgiref.sync import async_to_sync
from channels.generic.websocket import WebsocketConsumer
from django.shortcuts import get_object_or_404
from customercore.models import *
import json
from django.template.loader import render_to_string
from asgiref.sync import async_to_sync
class TicketRoomConsumer(WebsocketConsumer):
def connect(self):
self.user = self.scope['user']
self.ticket_id = self.scope['url_route']['kwargs']['ticket_id']
self.ticket = get_object_or_404(Ticket, id=self.ticket_id)
self.ticket_number = self.ticket.ticket_number
existing_connection = TicketConnection.objects.filter(ticket=self.ticket, user=self.user, terminated=False).delete()
TicketConnection.objects.create(
ticket=self.ticket,
user=self.user,
date=datetime.now()
)
staff_profile = StaffProfile.objects.filter(user=self.user).first()
if staff_profile:
if not TicketStaff.objects.filter(staff=staff_profile, ticket=self.ticket).exists():
TicketStaff.objects.create(
staff=staff_profile,
ticket=self.ticket,
date_added=datetime.now()
)
async_to_sync(self.channel_layer.group_add)(
self.ticket_number, self.channel_name
)
self.accept()
self.modify_online_user()
def disconnect(self, close_code):
TicketConnection.objects.filter(
ticket=self.ticket,
user=self.user,
).update(terminated=True)
async_to_sync(self.channel_layer.group_discard)(
self.ticket_number, self.channel_name
)
self.modify_online_user()
def receive(self, text_data):
text_data_json = json.loads(text_data)
event_type = text_data_json.get('event_type')
if event_type == 'typing':
event = {
'type': 'typing_handler',
'user': self.scope['user']
}
async_to_sync(self.channel_layer.group_send)(
self.ticket_number, event
)
elif event_type == 'stop_typing':
event = {
'type': 'stop_typing_handler',
}
async_to_sync(self.channel_layer.group_send)(
self.ticket_number, event
)
elif event_type == 'update_reaction':
reaction = text_data_json['reaction']
update_id = text_data_json['update_id']
event = {
'type': 'reaction_handler',
'update_id': update_id,
'reaction': reaction,
'user': self.scope['user']
}
async_to_sync(self.channel_layer.group_send)(
self.ticket_number, event
)
else:
body = text_data_json['description']
file_paths = text_data_json['filePath']
ticketupdate = TicketUpdate.objects.create(
added_by=self.user,
description=body,
ticket=self.ticket,
date_added=datetime.now()
)
for file_path in file_paths:
ticket_attachment = TicketAttachment(
ticket_update=ticketupdate,
file_path=file_path
)
ticket_attachment.save()
event = {
'type': 'update_handler',
'update_id': ticketupdate.id
}
async_to_sync(self.channel_layer.group_send)(
self.ticket_number, event
)
def update_handler(self, event):
update_id = event['update_id']
update = TicketUpdate.objects.get(id=update_id)
context = {
'update': update,
'user': self.user
}
html = render_to_string("details_templates/partials/new-ticket-message.html", context=context)
self.send(text_data=json.dumps({
'event_type': 'update',
'html': html
}))
def typing_handler(self, event):
context = {
'user': event['user']
}
html = render_to_string("details_templates/partials/typing-message.html", context=context)
self.send(text_data=json.dumps({
'event_type': 'typing',
'html': html
}))
def stop_typing_handler(self, event):
self.send(text_data=json.dumps({
'event_type': 'stop_typing'
}))
def reaction_handler(self, event):
update_id = event['update_id']
reaction = event['reaction']
user = self.user
update = TicketUpdate.objects.get(id=update_id)
existing_reaction = TicketUpdateReaction.objects.filter(ticket_update=update, customer=user).first()
new_reaction = None
if existing_reaction:
# If the existing reaction type is equal to the new reaction, delete it
if existing_reaction.reaction == reaction:
existing_reaction.delete()
else:
# If not, delete all previous reactions and add a new one
TicketUpdateReaction.objects.filter(ticket_update=update, customer=user).delete()
new_reaction = TicketUpdateReaction.objects.create(
ticket_update=update,
reaction=reaction,
customer=user
)
else:
# If there's no existing reaction, simply add the new one
new_reaction = TicketUpdateReaction.objects.create(
ticket_update=update,
reaction=reaction,
customer=user
)
self.send(text_data=json.dumps({
'event_type': 'reaction',
'update_id': update_id,
'reaction': new_reaction.reaction if new_reaction else None
}))
def modify_online_user(self):
connections = TicketConnection.objects.filter(ticket=self.ticket, terminated=False)
event = {
'type': 'user_connection_handler',
'user': self.user,
'connections': connections,
}
async_to_sync(self.channel_layer.group_send)(
self.ticket_number, event
)
def user_connection_handler(self, event):
context = {
'connections': event['connections'],
'user': event['user']
}
html = render_to_string("details_templates/partials/ticket-online-users.html", context=context)
self.send(text_data=json.dumps({
'event_type': 'user_status',
'html': html
}))