Files
Rasadyar_Marzaki/ticket/views.py
2026-01-18 11:45:53 +03:30

512 lines
23 KiB
Python

import datetime
import random
import string
import requests
from django.db.models import Q, Count
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from oauth2_provider.contrib.rest_framework import TokenHasReadWriteScope
from rest_framework import status
from rest_framework import viewsets
from rest_framework.decorators import api_view, permission_classes
from rest_framework.pagination import PageNumberPagination
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from authentication.models import SystemUserProfile, Group
from authentication.sms_management import ticket_answered
from helper_eata import token, chat_id
from panel.filterset import TicketsFilterSet
from panel.helper import build_query
from ticket.models import TicketSupport, MessageSupport, TicketPermission, TicketClosePermission
from ticket.serializers import TicketSupportSerializer, MessageSupportSerializer, TicketPermissionSerializer, \
SystemUserProfileForTicketPermissionSerializer, MessageSupportWithoutReadBySerializer, \
TicketClosePermissionSerializer
from .bucket import upload_to_liara
from .helper import send_image_to_server
class CustomPagination(PageNumberPagination):
page_size = 10
def update_unread_ticket(tickets, user):
user_roles = list(user.role.all())
unread_ticket_ids = MessageSupport.objects.filter(
Q(ticket__user=user) |
Q(ticket__to_user=user) |
Q(ticket__to_role__in=user_roles) |
Q(ticket__referred_by=user) |
Q(ticket__referred_to=user.id),
~Q(created_by=user),
~Q(read_by=user.id),
ticket__in=tickets
).values_list('ticket_id', flat=True).distinct()
unread_set = set(unread_ticket_ids)
for ticket in tickets:
ticket.unread_message = ticket.id in unread_set
TicketSupport.objects.bulk_update(tickets, ['unread_message'])
class TicketSupportViewSet(viewsets.ModelViewSet):
queryset = TicketSupport.objects.filter(trash=False).select_related(
'user', 'referred_by'
).prefetch_related(
'to_role', 'referred_to', 'to_user').order_by('-unread_message', '-create_date')
serializer_class = TicketSupportSerializer
permission_classes = [TokenHasReadWriteScope]
pagination_class = CustomPagination
filterset_class = TicketsFilterSet
def list(self, request, *args, **kwargs):
user = SystemUserProfile.objects.get(user=request.user)
role_list = list(user.role.values_list('id', flat=True).distinct())
role_check = any(role in ['AdminX', 'SuperAdmin'] for role in user.role.values_list('name', flat=True))
type_param = request.GET.get('type', None)
status = request.GET.get('status', 'open')
base_filter = Q(user=user) | Q(to_user=user.id) | Q(to_role__in=role_list) | Q(referred_to=user.id) | Q(
referred_by=user)
if role_check:
if type_param:
query = self.queryset.filter(type_ticket=type_param,
status=status).distinct() if type_param else self.queryset
else:
query = self.queryset.filter(status=status).distinct()
else:
if type_param:
query = self.queryset.filter(base_filter, type_ticket=type_param, status=status).distinct()
else:
query = self.queryset.filter(base_filter, status=status)
value = request.GET.get('value')
search = request.GET.get('search')
if value and search == 'filter':
if value != 'undefined' and value.strip():
query = query.filter(
build_query(self.filterset_class, value)
)
update_unread_ticket(query, user)
query = query.order_by('-unread_message', '-create_date')
page_size = request.query_params.get('page_size', None)
if page_size:
self.pagination_class.page_size = int(page_size)
page = self.paginate_queryset(query)
if page is not None:
serializer = self.serializer_class(page, many=True)
return self.get_paginated_response(serializer.data)
ser_data = self.serializer_class(query, many=True)
return Response(ser_data.data, status=status.HTTP_200_OK)
def create(self, request, *args, **kwargs):
user = SystemUserProfile.objects.get(user=request.user)
type_ticket = request.data.get('type_ticket')
read_only = request.data.get('read_only')
to_user_data = request.data.get('to_user')
if request.data.get('image') is not None:
image = send_image_to_server(request.data['image'])
else:
image = None
if request.FILES.get('file'):
file_obj = request.FILES.get('file')
file_url = upload_to_liara(file_obj, file_obj.name)
else:
file_url = None
if to_user_data:
to_users = SystemUserProfile.objects.filter(key__in=request.data['to_user'])
ticket = TicketSupport(
user=user,
title=request.data['title'],
status='open',
read_only=read_only,
type_ticket=type_ticket,
role=request.data.get('role'),
)
ticket.save()
ticket.to_user.set(to_users)
else:
to_role = Group.objects.filter(name__in=request.data.get('to_role'))
if ((SystemUserProfile.objects.filter(trash=False, role__in=to_role).count() < 2)):
return Response({'result': 'برای نقش انتخابی، لطفاً تیکت شخصی ثبت کنید!'},
status=status.HTTP_403_FORBIDDEN)
ticket = TicketSupport(
user=user,
title=request.data['title'],
status='open',
read_only=read_only,
type_ticket=type_ticket,
role=request.data.get('role'),
)
ticket.save()
ticket.to_role.set(to_role)
msg = MessageSupport(
ticket=ticket,
message=request.data['message'],
created_by=user,
sender=request.data.get('sender'),
picture=image,
file=file_url)
msg.save()
return Response({'msg': 'با موفقیت انجام شد.'}, status=status.HTTP_201_CREATED)
def update(self, request, *args, **kwargs):
ticket_id = request.data.get('ticket')
ticket = self.queryset.filter(ticket_id=int(ticket_id)).first()
if ticket:
if 'referred_to' in request.data:
referred_to = SystemUserProfile.objects.filter(key__in=request.data['referred_to'])
ticket.referred_by = SystemUserProfile.objects.get(user=request.user)
ticket.status = 'open'
ticket.is_referred = True
ticket.save()
referrer_name = []
for user in referred_to:
if not ticket.referred_to.filter(id=user.id).exists():
ticket.referred_to.add(user)
referrer_name.append(user.fullname)
if len(referrer_name) > 1:
names = ' و '.join(referrer_name)
else:
names = referrer_name[0] if referrer_name else ''
if referrer_name:
MessageSupport.objects.create(
ticket=ticket,
message=f"تیکت شماره {ticket.ticket_id} به ({names}) ارجاع داده شد.",
created_by=SystemUserProfile.objects.get(user=request.user),
sender='Admin'
)
return Response({'message': 'تیکت با موفقیت ارجاع داده شد.'}, status=200)
else:
ticket.status = 'closed'
ticket.save()
return Response({'result': 'تیکت با موفقیت پایان یافت.'}, status=status.HTTP_200_OK)
return Response({'result': 'تیکت وجود ندارد!'}, status=status.HTTP_400_BAD_REQUEST)
class MessageSupportViewSet(viewsets.ModelViewSet):
queryset = MessageSupport.objects.all().select_related('ticket').order_by('created_at')
serializer_class = MessageSupportSerializer
permission_classes = [TokenHasReadWriteScope]
def list(self, request, *args, **kwargs):
user = SystemUserProfile.objects.get(user=request.user)
ticket_id = request.GET.get('ticket')
role_list = list(user.role.values_list('id', flat=True).distinct())
role_check = any(
role in ['AdminX', 'SuperAdmin', 'ProvinceOperator'] for role in user.role.values_list('name', flat=True))
query = self.queryset.filter(ticket__ticket_id=int(ticket_id)).order_by('-created_at')
if query.filter(Q(ticket__user=user) | Q(ticket__to_user=user.id) | Q(ticket__to_role__in=role_list) | Q(
ticket__referred_by=user) | Q(ticket__referred_to=user.id)).exists():
unseen_messages = query.filter(~Q(created_by=user), last_seen__isnull=True)
unseen_messages.update(last_seen=datetime.datetime.now())
for message in query.filter(~Q(created_by=user)):
if not message.read_by.filter(id=user.id).exists():
message.read_by.add(user)
query = query.defer('message')
if role_check:
srz_data = self.serializer_class(query, many=True).data
else:
srz_data = MessageSupportWithoutReadBySerializer(query, many=True).data
return Response(srz_data)
def create(self, request, *args, **kwargs):
user = SystemUserProfile.objects.select_related('user').filter(user=request.user).first()
ticket_id = request.data.get('ticket')
ticket = TicketSupport.objects.get(ticket_id=int(ticket_id))
if ticket.status == 'closed':
return Response({'result': 'این تیکت بسته شده است!'}, status=status.HTTP_403_FORBIDDEN)
if ticket.read_only == False and ticket.type_ticket == 'public' and ticket.parent is None \
and ticket.user != user:
new_ticket = TicketSupport(
user=user,
title=ticket.title,
status='open',
read_only=False,
type_ticket='single',
parent=ticket,
last_message=request.data.get('sender'),
role=request.data.get('role'),
)
new_ticket.save()
new_ticket.to_user.add(ticket.user)
msg = MessageSupport(
ticket=new_ticket,
message=request.data.get('message'),
created_by=user,
sender=request.data.get('sender')
)
else:
msg = MessageSupport(
ticket=ticket,
message=request.data.get('message'),
created_by=user,
sender=request.data.get('sender')
)
ticket.last_message = request.data.get('sender')
ticket.save()
if request.data['send_message'] == True:
ticket_answered(ticket.user.mobile)
msg.send_message = True
if request.data.get('image') is not None:
# ran = ''.join(random.choices(string.ascii_uppercase + string.digits, k=15))
# upload_object_resize(image_data=request.data['image'], bucket_name="profileimagedefault",
# object_name="{0}.jpg".format(str(ran)))
msg.picture = send_image_to_server(request.data['image'])
if request.FILES.get('file'):
file_obj = request.FILES.get('file')
file_url = upload_to_liara(file_obj, file_obj.name)
msg.file = file_url
msg.save()
ser_data = self.serializer_class(msg)
return Response(ser_data.data, status=status.HTTP_201_CREATED)
def update(self, request, *args, **kwargs):
msg_id = request.data.get('message_id')
instance = self.get_queryset().get(id=msg_id)
request.data.pop('message_id')
serializer = self.get_serializer(instance, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response({'result': "با موفقیت انجام شد."}, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class MessageForRoleViewSet(viewsets.ModelViewSet):
queryset = MessageSupport.objects.all()
serializer_class = MessageSupportSerializer
permission_classes = [TokenHasReadWriteScope]
def create(self, request, *args, **kwargs):
user_sender = SystemUserProfile.objects.get(user=request.user)
if 'role' in request.data.keys():
to_user = SystemUserProfile.objects.filter(trash=False, role__name__in=request.data['role'])
relations = [
TicketSupport(
user=user_sender,
title=request.data['title'],
status='open',
to_user=user
)
for user in to_user
]
TicketSupport.objects.bulk_create(relations)
return Response({'msg': 'با موفقیت ارسال شد'}, status=status.HTTP_201_CREATED)
class TicketPermissionViewSet(viewsets.ModelViewSet):
queryset = TicketPermission.objects.all()
serializer_class = TicketPermissionSerializer
permission_classes = [AllowAny]
def create(self, request, *args, **kwargs):
role = request.data['role']
group = request.data['roles']
roles = Group.objects.filter(name__in=group)
ticket = TicketPermission.objects.get(role=role)
ticket.roles.set(roles)
ser_data = self.serializer_class(ticket)
return Response(ser_data.data, status=status.HTTP_201_CREATED)
def list(self, request, *args, **kwargs):
if 'role' in request.GET:
role = request.GET['role']
query = self.queryset.get(role=role)
ser_data = self.serializer_class(query).data
return Response(ser_data, status=status.HTTP_200_OK)
else:
query = self.queryset
ser_data = self.serializer_class(query, many=True).data
return Response(ser_data, status=status.HTTP_200_OK)
class GetUserFromRoleViewSet(viewsets.ModelViewSet):
queryset = SystemUserProfile.objects.all()
serializer_class = SystemUserProfileForTicketPermissionSerializer
permission_classes = [TokenHasReadWriteScope]
def list(self, request, *args, **kwargs):
role = request.GET['role']
user = SystemUserProfile.objects.filter(~Q(user=request.user), trash=False, role__name=role, )
ser_data = self.serializer_class(user, many=True)
return Response(ser_data.data, status=status.HTTP_200_OK)
class TicketClosePermissionViewSet(viewsets.ModelViewSet):
queryset = TicketClosePermission.objects.all().first()
serializer_class = TicketClosePermissionSerializer
permission_classes = [TokenHasReadWriteScope]
@api_view(["GET"])
@csrf_exempt
@permission_classes([TokenHasReadWriteScope])
def get_num_message(request):
user = SystemUserProfile.objects.get(user=request.user)
message = MessageSupport.objects.filter(
Q(ticket__user=user) | Q(ticket__to_user=user) | Q(ticket__to_role__in=user.role.all()) | Q(
ticket__referred_by=user) | Q(ticket__referred_to=user.id)
, ~Q(created_by=user)).exclude(read_by=user.id).values('ticket').annotate(
ticket_count=Count('ticket', distinct=True)
).distinct()
state = True if message.count() > 0 else False
return Response({
'state': state,
'num': message.count(),
})
# @api_view(["PUT"])
# @csrf_exempt
# @permission_classes([AllowAny])
# def FileUploadView(request):
# # queryset = TicketSupport.objects.all()
# # permission_classes = [AllowAny]
# # serializer_class = TicketSupportSerializer
# #
# # def create(self, request, *args, **kwargs):
# file_obj = request.FILES.get('file')
# if not file_obj:
# return Response({"error": "فایلی ارسال نشده است"}, status=status.HTTP_400_BAD_REQUEST)
#
# try:
# file_url = upload_to_liara(file_obj, file_obj.name)
# return Response({"file_url": file_url}, status=status.HTTP_201_CREATED)
# except Exception as e:
# return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
def bot_eitaa_for_bar():
url = f'https://eitaayar.ir/api/{token}/sendMessage'
data = {
"cookie": "ASP.NET_SessionId=w1jadrzcqgznxugnjee1xrkj; .ASPXAUTH=4CC27FD1BAB0CA729584056577AA51209F731F22CDF4B95F9FEE33AD12F1DFFF960C77B0A237D5733E336195A2CA6DB1C1F2CA2EDCD079EC0B3C3092A2BF1BA8811D7C44263B1E5EB84430C0906024A55D51AF1FE5852F406C358A051715BB9270475D58228F44380D12FA075A4DF0E029220F0C809AEDDDF58FFE9568064DD9D397B038D19DC1757232A92EA63571EA7B47E1706F677528E539301417093B523B6C2BFD340AA33DC32D50E7853E3D14D93924313B9B1EB36320C90A2303BB852841EE0DE1D844B281B4CD6D7E95D593CF2E2F0C3816687C529B7702863F75CD6549F49D346C7C88F22F033C75C357BE9E91AD170A2502731BC03AE2DF09F594417646FE332B8BAB70673E584A23AD45CADC285C554B66FD29DD989F85962891A11C06FC84832DD8FB03933CF26E190601D493B0430A742544B8BC0A8639E4E5788432AA401FAFFD3A1C6793FB24909A992405D07E53B81DF546AB07ED90314735518C37E9291F10E2B723B795B8BB838C2810CE103A4EF893211BFDBB605ADBE0E3B9B35438A5FE3506937D020EC2EF061B6D1E3AAFB3A9A138CC219A4A556CEB6A2E44C18D53C85666A5C0C9663F8314EFD97FFF5C1844C0FEB4362A781E2138785D832EEFD1AEDAD1271C2513A6F4EC1174EF107AC2E9FEFF8A9A111CC6D6189CCC66E93224EE4D30813AAD9DCDE1CFC530B08CB67827C351DCE4C2AFD4E3FB12E85EA0CD6E2D3D4CC8753D74E863A37C5675D82C9977518A942786EF055F0DBFC809B9F9B6A45B269526FC9D8B5E888B1C6E40C6ACE8EB37ED7E1F9F266A018936F3228A3C8E20C1BD869CC657D1CE19FFEA8C8B979DE5077E17AE5FA1F085B3A424C91DA19D3743871A2A9440937B2C4E076EC99AE4DEE1A7AF601448F2F763FC2DF85ED8902287DDD0ED5B9E649A4490900B4BF64F639CDD761326AC08D1B540CBD853B42F556FFB8FD5BC33A54E68125CD20278B191A1896BF955FFA1B4CC5308E12A84003B64B0EE532079563DC334FB9AEB9B742803EBE35C82CA14E5D0D84CA736AB9A2E07EECFF98657561C029ECE3C1249DA843B4236E41BD745E54B1A86ED2CE4EA0FDDBB3B4B2B97A87548B23298283F6D09094F7BC709FAABE59CC84138F83B083EAB15BE0B032481; leggedOut=-"
}
r = requests.post(url='https://pay.rasadyar.net/transporting-chickens/', data=data)
data = {
'chat_id': chat_id,
'text': r.status_code,
}
response = requests.post(url, data=data, verify=False)
return HttpResponse(response.status_code)
# def close_ticket_cron_job():
# ticket=TicketSupport.objects.filter(Q(unread_message=False,read_only=True)|Q(unread_message=True,read_only=False),trash=False,status='open')
# for t in ticket:
# two_day_ago =datetime.datetime.now().date() - datetime.timedelta(days=2)
# if (t.create_date.date() - datetime.datetime.now().date()).days > 2:
# t.status='closed'
# t.to_role=None
# t.title=None
# t.trash=False
# t.create_date=datetime.datetime.now()
# t.save()
# else:
# continue
@api_view(["GET"])
@csrf_exempt
@permission_classes([AllowAny])
def closed_unread_ticket(request):
user = SystemUserProfile.objects.filter(trash=False, role__name='AdminX').first()
two_day_ago = datetime.datetime.now() - datetime.timedelta(days=2)
ten_day_ago = datetime.datetime.now() - datetime.timedelta(days=10)
tickets = TicketSupport.objects.filter(
trash=False,
status='open',
type_ticket='single'
)
text_two_day_ago_message = 'به دلیل عدم دریافت پیام جدید در مدت 48 ساعت، این تیکت توسط سامانه به صورت خودکار بسته شد.'
text_ten_day_ago_message = 'به دلیل خوانده نشدن پیام در مدت 10 روز، این تیکت توسط سامانه به صورت خودکار بسته شد.'
for ticket in tickets:
message = MessageSupport.objects.filter(ticket=ticket).last()
if not message:
continue
if message.read_by.exists() and message.last_seen.date() <= two_day_ago.date():
msg = MessageSupport(
ticket=ticket,
message=text_two_day_ago_message,
created_by=user)
msg.save()
ticket.status = 'closed'
ticket.save()
if not message.read_by.exists() and message.created_at.date() <= ten_day_ago.date():
msg = MessageSupport(
ticket=ticket,
message=text_ten_day_ago_message,
created_by=user)
msg.save()
ticket.status = 'closed'
ticket.save()
return HttpResponse('ok')
def closed_unread_ticket_cron():
user = SystemUserProfile.objects.filter(trash=False, role__name='AdminX').first()
two_day_ago = datetime.datetime.now() - datetime.timedelta(days=2)
ten_day_ago = datetime.datetime.now() - datetime.timedelta(days=10)
tickets = TicketSupport.objects.filter(
trash=False,
status='open',
type_ticket='single'
)
text_two_day_ago_message = 'به دلیل عدم دریافت پیام جدید در مدت 48 ساعت، این تیکت توسط سامانه به صورت خودکار بسته شد.'
# text_ten_day_ago_message = 'به دلیل خوانده نشدن پیام در مدت 10 روز، این تیکت توسط سامانه به صورت خودکار بسته شد.'
for ticket in tickets:
message = MessageSupport.objects.filter(ticket=ticket).last()
if not message:
continue
if message.read_by.exists() and message.last_seen.date() <= two_day_ago.date():
msg = MessageSupport(
ticket=ticket,
message=text_two_day_ago_message,
created_by=user)
msg.save()
ticket.status = 'closed'
ticket.save()
# if not message.read_by.exists() and message.created_at.date() <= ten_day_ago.date():
# msg = MessageSupport(
# ticket=ticket,
# message=text_ten_day_ago_message,
# created_by=user)
# msg.save()
# ticket.status = 'closed'
# ticket.save()
@api_view(["GET"])
@csrf_exempt
@permission_classes([TokenHasReadWriteScope])
def get_unread_ticket_for_dashboard(request):
user = SystemUserProfile.objects.get(user=request.user)
role_list = list(user.role.values_list('id', flat=True).distinct())
base_filter = Q(user=user) | Q(to_user=user.id) | Q(to_role__in=role_list) | Q(referred_to=user.id) | Q(
referred_by=user)
query = TicketSupport.objects.filter(base_filter, status='open',trash=False).select_related(
'user', 'referred_by'
).prefetch_related(
'to_role', 'referred_to', 'to_user').order_by('-create_date')
update_unread_ticket(query, user)
query1 = query.filter(unread_message=True)
ser_data = TicketSupportSerializer(query1, many=True)
return Response(ser_data.data, status=status.HTTP_200_OK)