@ -43,6 +43,7 @@ from core.viewsets import (
|
||||
ticket_category,
|
||||
ticket_comment,
|
||||
ticket_linked_item,
|
||||
related_ticket,
|
||||
|
||||
)
|
||||
|
||||
@ -119,6 +120,8 @@ router.register('config_management/group/(?P<group_id>[0-9]+)/software', config_
|
||||
|
||||
router.register('core/(?P<model_class>.+)/(?P<model_id>[0-9]+)/history', history_v2.ViewSet, basename='_api_v2_model_history')
|
||||
router.register('core/ticket/(?P<ticket_id>[0-9]+)/linked_item', ticket_linked_item.ViewSet, basename='_api_v2_ticket_linked_item')
|
||||
router.register('core/ticket/(?P<ticket_id>[0-9]+)/related_ticket', related_ticket.ViewSet, basename='_api_v2_ticket_related')
|
||||
|
||||
|
||||
router.register('itam', itam_index_v2.Index, basename='_api_v2_itam_home')
|
||||
router.register('itam/device', device_v2.ViewSet, basename='_api_v2_device')
|
||||
|
@ -225,6 +225,19 @@ class ModelViewSet(
|
||||
|
||||
|
||||
|
||||
class ModelListRetrieveDeleteViewSet(
|
||||
viewsets.mixins.ListModelMixin,
|
||||
viewsets.mixins.RetrieveModelMixin,
|
||||
viewsets.mixins.DestroyModelMixin,
|
||||
viewsets.GenericViewSet,
|
||||
ModelViewSetBase
|
||||
):
|
||||
""" Use for models that you wish to delete and view ONLY!"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class ModelRetrieveUpdateViewSet(
|
||||
viewsets.mixins.RetrieveModelMixin,
|
||||
viewsets.mixins.UpdateModelMixin,
|
||||
|
@ -3,6 +3,8 @@ from django.db import models
|
||||
from django.db.models import Q, signals, Sum
|
||||
from django.forms import ValidationError
|
||||
|
||||
from rest_framework.reverse import reverse
|
||||
|
||||
from .ticket_enum_values import TicketValues
|
||||
|
||||
from access.fields import AutoCreatedField, AutoLastModifiedField
|
||||
@ -1103,6 +1105,11 @@ class RelatedTickets(TenancyObject):
|
||||
'id'
|
||||
]
|
||||
|
||||
verbose_name = 'Related Ticket'
|
||||
|
||||
verbose_name_plural = 'Related Tickets'
|
||||
|
||||
|
||||
class Related(models.IntegerChoices):
|
||||
RELATED = '1', 'Related'
|
||||
|
||||
@ -1159,9 +1166,32 @@ class RelatedTickets(TenancyObject):
|
||||
]
|
||||
|
||||
|
||||
# def __str__(self):
|
||||
def get_url( self, ticket_id, request = None ) -> str:
|
||||
|
||||
if not ticket_id:
|
||||
|
||||
return ''
|
||||
|
||||
if request:
|
||||
|
||||
return reverse(
|
||||
"v2:_api_v2_ticket_related-detail",
|
||||
request = request,
|
||||
kwargs={
|
||||
'ticket_id': ticket_id,
|
||||
'pk': self.id
|
||||
}
|
||||
)
|
||||
|
||||
return reverse("v2:_api_v2_ticket_related-detail", kwargs={'pk': self.id})
|
||||
|
||||
|
||||
def __str__(self):
|
||||
|
||||
# return '#' + str( self.id )
|
||||
|
||||
return '#'
|
||||
|
||||
# return ''
|
||||
|
||||
@property
|
||||
def parent_object(self):
|
||||
|
@ -75,6 +75,7 @@ class TicketModelSerializer(TicketBaseSerializer):
|
||||
),
|
||||
'comments': reverse('v2:_api_v2_ticket_' + str(item.get_ticket_type_display()).lower() + '_comments-list', request=context['view'].request, kwargs={'ticket_id': item.pk}),
|
||||
'linked_items': reverse("v2:_api_v2_ticket_linked_item-list", request=context['view'].request, kwargs={'ticket_id': item.pk}),
|
||||
'related_tickets': reverse("v2:_api_v2_ticket_related-list", request=context['view'].request, kwargs={'ticket_id': item.pk}),
|
||||
}
|
||||
|
||||
|
||||
|
119
app/core/serializers/ticket_related.py
Normal file
119
app/core/serializers/ticket_related.py
Normal file
@ -0,0 +1,119 @@
|
||||
from rest_framework.fields import empty
|
||||
from rest_framework.reverse import reverse
|
||||
from rest_framework import serializers
|
||||
|
||||
from access.serializers.organization import OrganizationBaseSerializer
|
||||
|
||||
from core.serializers.ticket import TicketBaseSerializer
|
||||
|
||||
from core.models.ticket.ticket import RelatedTickets
|
||||
|
||||
|
||||
|
||||
class RelatedTicketBaseSerializer(serializers.ModelSerializer):
|
||||
|
||||
display_name = serializers.SerializerMethodField('get_display_name')
|
||||
|
||||
def get_display_name(self, item):
|
||||
|
||||
return str( item )
|
||||
|
||||
url = serializers.SerializerMethodField('get_url')
|
||||
|
||||
def get_url(self, item) -> str:
|
||||
|
||||
request = None
|
||||
|
||||
ticket_id: int = None
|
||||
|
||||
if 'view' in self._context:
|
||||
|
||||
if hasattr(self._context['view'], 'request'):
|
||||
|
||||
request = self._context['view'].request
|
||||
|
||||
if 'ticket_id' in self._kwargs['context']['view'].kwargs:
|
||||
|
||||
ticket_id = int(self._kwargs['context']['view'].kwargs['ticket_id'])
|
||||
|
||||
return item.get_url( ticket_id = ticket_id,request = request )
|
||||
|
||||
|
||||
class Meta:
|
||||
|
||||
model = RelatedTickets
|
||||
|
||||
fields = [
|
||||
'id',
|
||||
'display_name',
|
||||
'title',
|
||||
'url',
|
||||
]
|
||||
|
||||
read_only_fields = [
|
||||
'id',
|
||||
'display_name',
|
||||
'title',
|
||||
'url',
|
||||
]
|
||||
|
||||
|
||||
class RelatedTicketModelSerializer(RelatedTicketBaseSerializer):
|
||||
|
||||
|
||||
_urls = serializers.SerializerMethodField('get_url')
|
||||
|
||||
def get_url(self, item):
|
||||
|
||||
request = None
|
||||
|
||||
ticket_id: int = None
|
||||
|
||||
if 'view' in self._context:
|
||||
|
||||
if hasattr(self._context['view'], 'request'):
|
||||
|
||||
request = self._context['view'].request
|
||||
|
||||
if 'ticket_id' in self._kwargs['context']['view'].kwargs:
|
||||
|
||||
ticket_id = int(self._kwargs['context']['view'].kwargs['ticket_id'])
|
||||
|
||||
return {
|
||||
'_self': item.get_url( ticket_id = ticket_id, request = request ),
|
||||
}
|
||||
|
||||
|
||||
class Meta:
|
||||
|
||||
model = RelatedTickets
|
||||
|
||||
fields = [
|
||||
'id',
|
||||
'display_name',
|
||||
'to_ticket_id',
|
||||
'from_ticket_id',
|
||||
'how_related',
|
||||
'organization',
|
||||
'_urls',
|
||||
]
|
||||
|
||||
read_only_fields = [
|
||||
'id',
|
||||
'display_name',
|
||||
'to_ticket_id',
|
||||
'from_ticket_id',
|
||||
'how_related',
|
||||
'organization',
|
||||
'_urls',
|
||||
]
|
||||
|
||||
|
||||
|
||||
class RelatedTicketViewSerializer(RelatedTicketModelSerializer):
|
||||
|
||||
from_ticket_id = TicketBaseSerializer()
|
||||
|
||||
organization = OrganizationBaseSerializer(many=False, read_only=True)
|
||||
|
||||
to_ticket_id = TicketBaseSerializer()
|
78
app/core/viewsets/related_ticket.py
Normal file
78
app/core/viewsets/related_ticket.py
Normal file
@ -0,0 +1,78 @@
|
||||
from django.db.models import Q
|
||||
|
||||
from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiResponse
|
||||
|
||||
from access.mixin import OrganizationMixin
|
||||
|
||||
from api.viewsets.common import ModelListRetrieveDeleteViewSet
|
||||
|
||||
from core.serializers.ticket_related import (
|
||||
RelatedTickets,
|
||||
RelatedTicketModelSerializer,
|
||||
RelatedTicketViewSerializer,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@extend_schema_view(
|
||||
destroy = extend_schema(
|
||||
summary = 'Delete a related ticket',
|
||||
description = '',
|
||||
responses = {
|
||||
204: OpenApiResponse(description=''),
|
||||
403: OpenApiResponse(description='User is missing delete permissions'),
|
||||
}
|
||||
),
|
||||
list = extend_schema(
|
||||
summary = 'Fetch all related tickets',
|
||||
description='',
|
||||
responses = {
|
||||
200: OpenApiResponse(description='', response=RelatedTicketViewSerializer),
|
||||
403: OpenApiResponse(description='User is missing view permissions'),
|
||||
}
|
||||
),
|
||||
retrieve = extend_schema(
|
||||
summary = 'Fetch a related ticket',
|
||||
description='',
|
||||
responses = {
|
||||
200: OpenApiResponse(description='', response=RelatedTicketViewSerializer),
|
||||
403: OpenApiResponse(description='User is missing view permissions'),
|
||||
}
|
||||
),
|
||||
)
|
||||
class ViewSet(ModelListRetrieveDeleteViewSet):
|
||||
|
||||
|
||||
filterset_fields = [
|
||||
'organization',
|
||||
]
|
||||
|
||||
search_fields = [
|
||||
'name',
|
||||
]
|
||||
|
||||
model = RelatedTickets
|
||||
|
||||
|
||||
def get_serializer_class(self):
|
||||
|
||||
if (
|
||||
self.action == 'list'
|
||||
or self.action == 'retrieve'
|
||||
):
|
||||
|
||||
return globals()[str( self.model._meta.verbose_name).replace(' ', '') + 'ViewSerializer']
|
||||
|
||||
|
||||
return globals()[str( self.model._meta.verbose_name).replace(' ', '') + 'ModelSerializer']
|
||||
|
||||
|
||||
def get_queryset(self):
|
||||
|
||||
self.queryset = RelatedTickets.objects.filter(
|
||||
Q(from_ticket_id_id=self.kwargs['ticket_id'])
|
||||
|
|
||||
Q(to_ticket_id_id=self.kwargs['ticket_id'])
|
||||
)
|
||||
|
||||
return self.queryset.filter().order_by('id')
|
Reference in New Issue
Block a user