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)