diff --git a/uniticket/api_rest/urls.py b/uniticket/api_rest/urls.py index 1c379197..5ced9b1a 100644 --- a/uniticket/api_rest/urls.py +++ b/uniticket/api_rest/urls.py @@ -3,33 +3,30 @@ from rest_framework.renderers import JSONOpenAPIRenderer from rest_framework.schemas import get_schema_view -from api_rest.views import * +from api_rest.views import generic, manager, operator, user + # Routers provide an easy way of automatically determining the URL conf. router = routers.DefaultRouter() -router.register('users', UserViewSet) -router.register('groups', GroupViewSet) +router.register('users', generic.UserViewSet) +router.register('groups', generic.GroupViewSet) urlpatterns = [ - # path('api/', include(router.urls)), - # path('api-auth/', include(rest_framework.urls, 'rest_framework',)), - - re_path('^openapi$', get_schema_view(**{}), name='openapi-schema'), - re_path('^openapi.json$', get_schema_view(renderer_classes = [JSONOpenAPIRenderer], **{}), name='openapi-schema-json'), - path('api///ticket/new', TicketAPIView.as_view(), name='api-new-ticket'), - path('api/ticket/', TicketAPIDetail.as_view(), name='api-view-ticket'), - path('api/strutture/list', TicketAPIStruttureList.as_view(), name='api-strutture-list'), - path('api/ticket/category/list', TicketAPITicketCategoryList.as_view(),name='api-ticket-category-list'), - path('api/ticket/user/list', TicketAPIListCreated.as_view(), name='api-ticket-user-list'), - path('api/ticket/close/', TicketAPIClose.as_view(), name='api-ticket-close'), - - path('api/manager//tickets/unassigned/count/', TicketAPIManagerUnassignedCount.as_view(), name='api-manager-tickets-unassigned-count'), - path('api/manager//tickets/open/count/', TicketAPIManagerOpenCount.as_view(), name='api-manager-tickets-open-count'), - path('api/manager//tickets/my-open/count/', TicketAPIManagerMyOpenCount.as_view(), name='api-manager-tickets-my-open-count'), - - path('api/operator//tickets/unassigned/count/', TicketAPIOperatorUnassignedCount.as_view(), name='api-operator-tickets-unassigned-count'), - path('api/operator//tickets/open/count/', TicketAPIOperatorOpenCount.as_view(), name='api-operator-tickets-open-count'), - path('api/operator//tickets/my-open/count/', TicketAPIOperatorMyOpenCount.as_view(), name='api-operator-tickets-my-open-count'), - -] + # path('api/', include(router.urls)), + # path('api-auth/', include(rest_framework.urls, 'rest_framework',)), + + re_path('^openapi$', get_schema_view(**{}), name='openapi-schema'), + re_path('^openapi.json$', get_schema_view(renderer_classes = [JSONOpenAPIRenderer], **{}), name='openapi-schema-json'), + path('api///ticket/new', user.TicketAPIView.as_view(), name='api-new-ticket'), + path('api/ticket/', user.TicketAPIDetail.as_view(), name='api-view-ticket'), + path('api/strutture/list', generic.TicketAPIStruttureList.as_view(), name='api-strutture-list'), + path('api/ticket/category/list', generic.TicketAPITicketCategoryList.as_view(),name='api-ticket-category-list'), + path('api/ticket/user/list', user.TicketAPIListCreated.as_view(), name='api-ticket-user-list'), + path('api/ticket/close/', user.TicketAPIClose.as_view(), name='api-ticket-close'), + + # manager + path('api/manager//tickets/count/', manager.TicketAPICounter.as_view(), name='api-manager-tickets-count'), + + # operator + path('api/operator//tickets/count/', operator.TicketAPICounter.as_view(), name='api-operator-tickets-count'),] diff --git a/uniticket/api_rest/views/__init__.py b/uniticket/api_rest/views/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/uniticket/api_rest/views/generic.py b/uniticket/api_rest/views/generic.py new file mode 100644 index 00000000..3e454cd8 --- /dev/null +++ b/uniticket/api_rest/views/generic.py @@ -0,0 +1,97 @@ +from copy import deepcopy +import json +import logging + +from django.contrib import messages +from django.contrib.auth import get_user_model +from django.contrib.auth.models import Group +from django.core import serializers +from django.core.exceptions import BadRequest +from django.db.models import Q +from django.http import Http404 +from django.shortcuts import get_object_or_404 + +from rest_framework.authentication import SessionAuthentication +from rest_framework.exceptions import PermissionDenied +from rest_framework import generics +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import permissions, viewsets + +from uni_ticket.dynamic_form import serialize_form +from uni_ticket.models import Ticket, TicketAssignment, TicketCategory, TicketReply +from uni_ticket.views.user import TicketAddNew, TicketClose, TicketDetail +from uni_ticket.settings import TICKET_CREATE_BUTTON_NAME +from uni_ticket.utils import user_is_manager, user_is_operator, visible_tickets_to_user + +from organizational_area.models import OrganizationalStructure +from api_rest.authorizations import AuthorizationToken + + +from .. serializers import ( + GroupSerializer, + OrganizationalStructureSerializer, + TicketCategorySerializer, + TicketSerializer, + UserSerializer +) + +logger = logging.getLogger(__name__) + + +# ViewSets define the view behavior. +class UserViewSet(viewsets.ModelViewSet): + permission_classes = [permissions.IsAdminUser] + queryset = get_user_model().objects.all() + serializer_class = UserSerializer + + +class GroupViewSet(viewsets.ModelViewSet): + """ + API endpoint that allows groups to be viewed or edited. + """ + permission_classes = [permissions.IsAdminUser] + queryset = Group.objects.all() + serializer_class = GroupSerializer + + +class uniTicketROGenericList(generics.ListAPIView): + authentication_classes = [AuthorizationToken, SessionAuthentication] + permission_classes = [permissions.IsAuthenticated] + + +def message_level(level:int): + levels = {v:k for k,v in messages.DEFAULT_LEVELS.items()} + return levels.get(level, level) + + +class TicketAPIBaseView(APIView): + """ + base class to port in the API all the legacy code + """ + + # TODO: AgID MoDI also here? + authentication_classes = [ + AuthorizationToken, SessionAuthentication + ] + permission_classes = [permissions.IsAuthenticated] + + def get_messages(self): + return [ + { + message_level(i.level): i.message + for i in messages.get_messages(self.request) + } + ] + + +class TicketAPIStruttureList(uniTicketROGenericList): + queryset = OrganizationalStructure.objects.filter(is_active=True) + lookup_field = 'pk' + serializer_class = OrganizationalStructureSerializer + + +class TicketAPITicketCategoryList(uniTicketROGenericList): + queryset = TicketCategory.objects.filter(is_active=True) + lookup_field = 'pk' + serializer_class = TicketCategorySerializer diff --git a/uniticket/api_rest/views/manager.py b/uniticket/api_rest/views/manager.py new file mode 100644 index 00000000..2416a3da --- /dev/null +++ b/uniticket/api_rest/views/manager.py @@ -0,0 +1,56 @@ +import logging + +from django.contrib import messages +from django.core import serializers +from django.db.models import Q +from django.http import Http404 +from django.shortcuts import get_object_or_404 + +from rest_framework.authentication import SessionAuthentication +from rest_framework.exceptions import PermissionDenied +from rest_framework import generics +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import permissions, viewsets + +from uni_ticket.models import Ticket, TicketAssignment, TicketCategory, TicketReply +from uni_ticket.utils import user_is_manager, user_is_operator, visible_tickets_to_user + +from organizational_area.models import OrganizationalStructure +from api_rest.authorizations import AuthorizationToken + +from . generic import * + + +logger = logging.getLogger(__name__) + + +class TicketAPICounter(TicketAPIBaseView): + def get(self, request, structure_slug, *args, **kwargs): + structure = get_object_or_404(OrganizationalStructure, slug=structure_slug) + if not user_is_manager(request.user, structure): raise PermissionDenied + + unassigned_tickets = TicketAssignment.get_ticket_per_structure(structure=structure, + closed=False, + taken=False) + + open_tickets = TicketAssignment.get_ticket_per_structure(structure=structure, + closed=False, + taken=True) + + my_open_tickets = TicketAssignment.get_ticket_per_structure(structure=structure, + closed=False, + taken=True, + taken_by=request.user) + ticket_ids = TicketAssignment.objects.filter( + office__organizational_structure=structure, + office__is_active=True, + follow=True, + ticket__is_closed=False + ).values_list('ticket__pk', flat=True).distinct() + messages = TicketReply.get_unread_messages_count(ticket_ids=ticket_ids) + + return Response({'unassigned': len(unassigned_tickets), + 'open': len(open_tickets), + 'my_open': len(my_open_tickets), + 'new_messages': messages}) diff --git a/uniticket/api_rest/views/operator.py b/uniticket/api_rest/views/operator.py new file mode 100644 index 00000000..4fe68bbe --- /dev/null +++ b/uniticket/api_rest/views/operator.py @@ -0,0 +1,65 @@ +import logging + +from django.contrib import messages +from django.core import serializers +from django.db.models import Q +from django.http import Http404 +from django.shortcuts import get_object_or_404 + +from rest_framework.authentication import SessionAuthentication +from rest_framework.exceptions import PermissionDenied +from rest_framework import generics +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import permissions, viewsets + +from uni_ticket.models import Ticket, TicketAssignment, TicketCategory, TicketReply +from uni_ticket.utils import user_is_manager, user_is_operator, visible_tickets_to_user + +from organizational_area.models import OrganizationalStructure +from api_rest.authorizations import AuthorizationToken + +from . generic import * + + +logger = logging.getLogger(__name__) + + +class TicketAPICounter(TicketAPIBaseView): + def get(self, request, structure_slug, *args, **kwargs): + structure = get_object_or_404(OrganizationalStructure, slug=structure_slug) + oe = user_is_operator(request.user, structure) + if not oe: raise PermissionDenied + + unassigned_tickets = visible_tickets_to_user(user=request.user, + structure=structure, + office_employee=oe, + closed=False, + taken=False) + + open_tickets = visible_tickets_to_user(user=request.user, + structure=structure, + office_employee=oe, + closed=False, + taken=True) + + my_open_tickets = visible_tickets_to_user(user=request.user, + structure=structure, + office_employee=oe, + closed=False, + taken=True, + taken_by=request.user) + + ticket_ids = visible_tickets_to_user( + user=request.user, + structure=structure, + office_employee=oe, + closed=False + ) + + messages = TicketReply.get_unread_messages_count(ticket_ids=ticket_ids) + + return Response({'unassigned': len(unassigned_tickets), + 'open': len(open_tickets), + 'my_open': len(my_open_tickets), + 'new_messages': messages}) diff --git a/uniticket/api_rest/views.py b/uniticket/api_rest/views/user.py similarity index 58% rename from uniticket/api_rest/views.py rename to uniticket/api_rest/views/user.py index a1590e82..8f0d8288 100644 --- a/uniticket/api_rest/views.py +++ b/uniticket/api_rest/views/user.py @@ -27,8 +27,7 @@ from organizational_area.models import OrganizationalStructure from api_rest.authorizations import AuthorizationToken - -from . serializers import ( +from .. serializers import ( GroupSerializer, OrganizationalStructureSerializer, TicketCategorySerializer, @@ -36,53 +35,10 @@ UserSerializer ) -logger = logging.getLogger(__name__) - - -# ViewSets define the view behavior. -class UserViewSet(viewsets.ModelViewSet): - permission_classes = [permissions.IsAdminUser] - queryset = get_user_model().objects.all() - serializer_class = UserSerializer - - -class GroupViewSet(viewsets.ModelViewSet): - """ - API endpoint that allows groups to be viewed or edited. - """ - permission_classes = [permissions.IsAdminUser] - queryset = Group.objects.all() - serializer_class = GroupSerializer - - -class uniTicketROGenericList(generics.ListAPIView): - authentication_classes = [AuthorizationToken, SessionAuthentication] - permission_classes = [permissions.IsAuthenticated] - - -def message_level(level:int): - levels = {v:k for k,v in messages.DEFAULT_LEVELS.items()} - return levels.get(level, level) +from . generic import * -class TicketAPIBaseView(APIView): - """ - base class to port in the API all the legacy code - """ - - # TODO: AgID MoDI also here? - authentication_classes = [ - AuthorizationToken, SessionAuthentication - ] - permission_classes = [permissions.IsAuthenticated] - - def get_messages(self): - return [ - { - message_level(i.level): i.message - for i in messages.get_messages(self.request) - } - ] +logger = logging.getLogger(__name__) class TicketAPIView(TicketAPIBaseView): @@ -172,18 +128,6 @@ def post(self, request, structure_slug, category_slug): raise BadRequest() -class TicketAPIStruttureList(uniTicketROGenericList): - queryset = OrganizationalStructure.objects.filter(is_active=True) - lookup_field = 'pk' - serializer_class = OrganizationalStructureSerializer - - -class TicketAPITicketCategoryList(uniTicketROGenericList): - queryset = TicketCategory.objects.filter(is_active=True) - lookup_field = 'pk' - serializer_class = TicketCategorySerializer - - class TicketAPIDetail(TicketAPIBaseView): """ Shows the status of a Ticket @@ -283,74 +227,3 @@ def get(self, request, ticket_id, *args, **kwargs): def post(self, request, ticket_id, *args, **kwargs): return self.close(request, ticket_id, *args, **kwargs) - - -class TicketAPIManagerUnassignedCount(TicketAPIBaseView): - def get(self, request, structure_slug, *args, **kwargs): - structure = get_object_or_404(OrganizationalStructure, slug=structure_slug) - if not user_is_manager(request.user, structure): raise PermissionDenied - unassigned = len(TicketAssignment.get_ticket_per_structure(structure=structure, - closed=False, - taken=False)) - return Response({'count':unassigned}) - - -class TicketAPIManagerOpenCount(TicketAPIBaseView): - def get(self, request, structure_slug, *args, **kwargs): - structure = get_object_or_404(OrganizationalStructure, slug=structure_slug) - if not user_is_manager(request.user, structure): raise PermissionDenied - open_tickets = len(TicketAssignment.get_ticket_per_structure(structure=structure, - closed=False, - taken=True)) - return Response({'count':open_tickets}) - - -class TicketAPIManagerMyOpenCount(TicketAPIBaseView): - def get(self, request, structure_slug, *args, **kwargs): - structure = get_object_or_404(OrganizationalStructure, slug=structure_slug) - if not user_is_manager(request.user, structure): raise PermissionDenied - my_open = len(TicketAssignment.get_ticket_per_structure(structure=structure, - closed=False, - taken=True, - taken_by=request.user)) - return Response({'count':my_open}) - - -class TicketAPIOperatorUnassignedCount(TicketAPIBaseView): - def get(self, request, structure_slug, *args, **kwargs): - structure = get_object_or_404(OrganizationalStructure, slug=structure_slug) - oe = user_is_operator(request.user, structure) - if not oe: raise PermissionDenied - unassigned = len(visible_tickets_to_user(user=request.user, - structure=structure, - office_employee=oe, - closed=False, - taken=False)) - return Response({'count':unassigned}) - - -class TicketAPIOperatorOpenCount(TicketAPIBaseView): - def get(self, request, structure_slug, *args, **kwargs): - structure = get_object_or_404(OrganizationalStructure, slug=structure_slug) - oe = user_is_operator(request.user, structure) - if not oe: raise PermissionDenied - open_tickets = len(visible_tickets_to_user(user=request.user, - structure=structure, - office_employee=oe, - closed=False, - taken=True)) - return Response({'count':open_tickets}) - - -class TicketAPIOperatorMyOpenCount(TicketAPIBaseView): - def get(self, request, structure_slug, *args, **kwargs): - structure = get_object_or_404(OrganizationalStructure, slug=structure_slug) - oe = user_is_operator(request.user, structure) - if not oe: raise PermissionDenied - my_open = len(visible_tickets_to_user(user=request.user, - structure=structure, - office_employee=oe, - closed=False, - taken=True, - taken_by=request.user)) - return Response({'count':my_open}) diff --git a/uniticket/uni_ticket/views/management.py b/uniticket/uni_ticket/views/management.py index 802056f2..45908cae 100644 --- a/uniticket/uni_ticket/views/management.py +++ b/uniticket/uni_ticket/views/management.py @@ -446,61 +446,11 @@ def tickets(request, structure_slug, structure, office_employee=None): title = _("Gestione richieste") sub_title = _("Tutti gli stati") - ticket_list = [] - # if user is operator - if office_employee: - unassigned = len(visible_tickets_to_user(user=request.user, - structure=structure, - office_employee=office_employee, - closed=False, - taken=False)) - - opened = len(visible_tickets_to_user(user=request.user, - structure=structure, - office_employee=office_employee, - closed=False, - taken=True)) - - my_opened = len(visible_tickets_to_user(user=request.user, - structure=structure, - office_employee=office_employee, - closed=False, - taken=True, - taken_by=request.user)) - - ticket_ids = visible_tickets_to_user( - user=request.user, - structure=structure, - office_employee=office_employee, - closed=False - ) - # if user is manager - else: - unassigned = len(TicketAssignment.get_ticket_per_structure(structure=structure, - closed=False, - taken=False)) - opened = len(TicketAssignment.get_ticket_per_structure(structure=structure, - closed=False, - taken=True)) - my_opened = len(TicketAssignment.get_ticket_per_structure(structure=structure, - closed=False, - taken=True, - taken_by=request.user)) - ticket_ids = TicketAssignment.objects.filter( - office__organizational_structure=structure, - office__is_active=True, - follow=True, - ticket__is_closed=False - ).values_list('ticket__pk', flat=True).distinct() - - # unread messages - messages = TicketReply.get_unread_messages_count(ticket_ids=ticket_ids) - d = { - "ticket_aperti": opened, - "ticket_assegnati_a_me": my_opened, - "ticket_non_gestiti": unassigned, - "ticket_messages": messages, + # "ticket_aperti": opened, + # "ticket_assegnati_a_me": my_opened, + # "ticket_non_gestiti": unassigned, + # "ticket_messages": messages, "structure": structure, "sub_title": sub_title, "title": title, diff --git a/uniticket/uni_ticket/views/manager.py b/uniticket/uni_ticket/views/manager.py index 7b10c98f..aa76a77c 100644 --- a/uniticket/uni_ticket/views/manager.py +++ b/uniticket/uni_ticket/views/manager.py @@ -73,13 +73,7 @@ def dashboard(request, structure_slug, structure): .prefetch_related('ticketcategorytask_set')\ .prefetch_related('ticketcategorycondition_set') - ticket_ids = TicketAssignment.objects.filter( - office__organizational_structure=structure, - office__is_active=True, - follow=True, - ticket__is_closed=False - ).values_list('ticket__pk', flat=True).distinct() - messages = TicketReply.get_unread_messages_count(ticket_ids=ticket_ids) + d = { "categories": categories, @@ -88,7 +82,7 @@ def dashboard(request, structure_slug, structure): "sub_title": sub_title, # "ticket_aperti": opened, # "ticket_assegnati_a_me": my_opened, - "ticket_messages": messages, + # "ticket_messages": messages, # "ticket_non_gestiti": unassigned, "title": title, } diff --git a/uniticket/uni_ticket/views/operator.py b/uniticket/uni_ticket/views/operator.py index 941f41c9..64dc0504 100644 --- a/uniticket/uni_ticket/views/operator.py +++ b/uniticket/uni_ticket/views/operator.py @@ -32,19 +32,11 @@ def dashboard(request, structure_slug, structure, office_employee): template = "operator/dashboard.html" offices = user_offices_list(office_employee) - ticket_ids = visible_tickets_to_user( - user=request.user, - structure=structure, - office_employee=office_employee, - closed=False - ) - - messages = TicketReply.get_unread_messages_count(ticket_ids=ticket_ids) d = { "offices": offices, "structure": structure, "sub_title": sub_title, "title": title, - "ticket_messages": messages, + # "ticket_messages": messages, } return render(request, template, base_context(d)) diff --git a/uniticket/uni_ticket_bootstrap_italia_template/templates/manager/counters.html b/uniticket/uni_ticket_bootstrap_italia_template/templates/manager/counters.html index 9938d1be..e94a9f48 100644 --- a/uniticket/uni_ticket_bootstrap_italia_template/templates/manager/counters.html +++ b/uniticket/uni_ticket_bootstrap_italia_template/templates/manager/counters.html @@ -27,12 +27,14 @@ {% trans 'Chiuse' %} +
+ In elaborazione... +
+
- {% if ticket_messages %} - {% trans "Nuovi" %} - {% endif %} + {% trans "Nuovi" %} {% trans 'Messaggi' %}
@@ -71,13 +73,11 @@
  • - {% if ticket_messages %} -
    +
    {% trans "Nuovi" %}
    - {% endif %} @@ -96,47 +96,31 @@ unassigned: null, open: null, my_open: null, + new_messages: null } }, created(){ this.interval = setInterval(() =>{ - this.getUnassigned(); - this.getOpen(); - this.getMyOpen(); + this.getCounters(); }, 20000) }, destroyed(){ clearInterval(this.interval) }, mounted () { - this.getUnassigned() - this.getOpen() - this.getMyOpen() + this.getCounters() }, methods: { - getUnassigned() { - url = '{% url "api-manager-tickets-unassigned-count" structure_slug=structure.slug %}' - axios - .get(url) - .then(response => ( - this.unassigned = response.data.count - )) - }, - getOpen() { - url = '{% url "api-manager-tickets-open-count" structure_slug=structure.slug %}' - axios - .get(url) - .then(response => ( - this.open = response.data.count - )) - }, - getMyOpen() { - url = '{% url "api-manager-tickets-my-open-count" structure_slug=structure.slug %}' + getCounters() { + url = '{% url "api-manager-tickets-count" structure_slug=structure.slug %}' axios .get(url) - .then(response => ( - this.my_open = response.data.count - )) + .then(response => { + this.unassigned = response.data.unassigned + this.open = response.data.open + this.my_open = response.data.my_open + this.new_messages = response.data.new_messages + }) } } }).mount('#counters') diff --git a/uniticket/uni_ticket_bootstrap_italia_template/templates/operator/counters.html b/uniticket/uni_ticket_bootstrap_italia_template/templates/operator/counters.html index 90951dc2..ab753c97 100644 --- a/uniticket/uni_ticket_bootstrap_italia_template/templates/operator/counters.html +++ b/uniticket/uni_ticket_bootstrap_italia_template/templates/operator/counters.html @@ -28,12 +28,14 @@ {% trans 'Chiuse' %}
    +
    + In elaborazione... +
    +
    - {% if ticket_messages %} - {% trans "Nuovi" %} - {% endif %} + {% trans "Nuovi" %}{% trans "Nuovi" %} {% trans 'Messaggi' %}
    @@ -72,13 +74,11 @@
  • - {% if ticket_messages %} -
    +
    {% trans "Nuovi" %}
    - {% endif %} @@ -97,47 +97,30 @@ unassigned: null, open: null, my_open: null, + new_messages: false } }, created(){ this.interval = setInterval(() =>{ - this.getUnassigned(); - this.getOpen(); - this.getMyOpen(); + this.getCounters(); }, 20000) }, destroyed(){ clearInterval(this.interval) }, mounted () { - this.getUnassigned() - this.getOpen() - this.getMyOpen() + this.getCounters() }, methods: { - getUnassigned() { - url = '{% url "api-operator-tickets-unassigned-count" structure_slug=structure.slug %}' - axios - .get(url) - .then(response => ( - this.unassigned = response.data.count - )) - }, - getOpen() { - url = '{% url "api-operator-tickets-open-count" structure_slug=structure.slug %}' - axios - .get(url) - .then(response => ( - this.open = response.data.count - )) - }, - getMyOpen() { - url = '{% url "api-operator-tickets-my-open-count" structure_slug=structure.slug %}' + getCounters() { + url = '{% url "api-operator-tickets-count" structure_slug=structure.slug %}' axios .get(url) - .then(response => ( - this.my_open = response.data.count - )) + .then(response => { + this.unassigned = response.data.unassigned + this.open = response.data.open + this.my_open = response.data.my_open + }) } } }).mount('#counters')