chore(core): Remove no longer used Django UI

ref: #788 #757
This commit is contained in:
2025-06-05 14:10:23 +09:30
parent 97b07e1663
commit 25d510f086
73 changed files with 0 additions and 7973 deletions

View File

@ -1,15 +0,0 @@
from django.conf import settings
from core.forms.common import CommonModelForm
from core.models.notes import Notes
class AddNoteForm(CommonModelForm):
prefix = 'note'
class Meta:
model = Notes
fields = [
'note'
]

View File

@ -1,104 +0,0 @@
from django import forms
from django.db.models import Q
from access.models.tenant import Tenant as Organization
from access.models.team_user import TeamUsers
class CommonModelForm(forms.ModelForm):
""" Abstract Form class for form inclusion
This class exists so that common functions can be conducted against forms as they are loaded.
"""
organization_field: str = 'organization'
""" Organization Field
Name of the field that contains Organizations.
This field will be filtered to those that the user is part of.
"""
def __init__(self, *args, **kwargs):
"""Form initialization.
Initialize the form using the super classes first then continue to initialize the form using logic
contained within this method.
## Tenancy Objects
Fields that contain an attribute called `organization` will have the objects filtered to
the organizations the user is part of. If the object has `is_global=True`, that object will not be
filtered out.
!!! danger "Requirement"
This method may be overridden however must still be called from the overriding function. i.e. `super().__init__(*args, **kwargs)`
"""
user = kwargs.pop('user', None)
user_organizations: list([str]) = []
user_organizations_id: list(int()) = []
for team_user in TeamUsers.objects.filter(user=user):
if team_user.team.organization.name not in user_organizations:
user_organizations += [ team_user.team.organization.name ]
user_organizations_id += [ team_user.team.organization.id ]
new_kwargs: dict = {}
for key, value in kwargs.items():
if key != 'user':
new_kwargs.update({key: value})
super().__init__(*args, **new_kwargs)
if len(user_organizations_id) > 0:
for field_name in self.fields:
field = self.fields[field_name]
if hasattr(field, 'queryset'):
if hasattr(field.queryset.model, 'organization'):
if hasattr(field.queryset.model, 'is_global'):
if field.queryset.model.is_global is not None:
self.fields[field_name].queryset = field.queryset.filter(
Q(organization__in=user_organizations_id)
|
Q(is_global = True)
)
else:
self.fields[field_name].queryset = field.queryset.filter(
Q(organization__in=user_organizations_id)
)
if self.Meta.fields:
if self.organization_field in self.Meta.fields:
self.fields[self.organization_field].queryset = self.fields[self.organization_field].queryset.filter(
Q(id__in=user_organizations_id)
|
Q(manager=user)
)
if hasattr(self, 'instance'):
self.model_name_plural = self.instance._meta.verbose_name_plural

View File

@ -1,90 +0,0 @@
from django import forms
from django.urls import reverse
from django.conf import settings
from core.forms.common import CommonModelForm
from core.models.manufacturer import Manufacturer
from settings.forms.admin_settings_global import AdminGlobalModels
class ManufacturerForm(
AdminGlobalModels,
CommonModelForm
):
class Meta:
fields = [
'name',
'slug',
'id',
'organization',
'is_global',
'model_notes',
]
model = Manufacturer
class DetailForm(ManufacturerForm):
tabs: dict = {
"details": {
"name": "Details",
"slug": "details",
"sections": [
{
"layout": "double",
"left": [
'name',
'slug',
'organization',
'is_global',
'c_created',
'c_modified',
],
"right": [
'model_notes',
]
}
]
},
# "notes": {
# "name": "Notes",
# "slug": "notes",
# "sections": []
# }
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['c_created'] = forms.DateTimeField(
label = 'Created',
input_formats=settings.DATETIME_FORMAT,
disabled = True,
initial = self.instance.created,
)
self.fields['c_modified'] = forms.DateTimeField(
label = 'Modified',
input_formats=settings.DATETIME_FORMAT,
disabled = True,
initial = self.instance.modified,
)
self.tabs['details'].update({
"edit_url": reverse('Settings:_manufacturer_change', args=(self.instance.pk,))
})
self.url_index_view = reverse('Settings:_manufacturers')

View File

@ -1,55 +0,0 @@
from django import forms
from django.db.models import Q
from django.forms import ValidationError
from django.conf import settings
from core.forms.common import CommonModelForm
from core.models.ticket.ticket import RelatedTickets
class RelatedTicketForm(CommonModelForm):
prefix = 'ticket'
class Meta:
model = RelatedTickets
fields = '__all__'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['from_ticket_id'].widget = self.fields['from_ticket_id'].hidden_widget()
def clean(self):
cleaned_data = super().clean()
return cleaned_data
def is_valid(self) -> bool:
is_valid = super().is_valid()
check_db = self.Meta.model.objects.filter(
to_ticket_id = self.cleaned_data['to_ticket_id'].id,
from_ticket_id = self.cleaned_data['from_ticket_id'].id,
)
check_db_inverse = self.Meta.model.objects.filter(
to_ticket_id = self.cleaned_data['from_ticket_id'].id,
from_ticket_id = self.cleaned_data['to_ticket_id'].id,
)
if check_db.count() > 0 or check_db_inverse.count() > 0:
raise ValidationError(f"Ticket is already related to #{self.cleaned_data['to_ticket_id'].id}")
is_valid = False
return is_valid

View File

@ -1,249 +0,0 @@
from django import forms
from django.db.models import Q
from django.forms import ValidationError
from django.conf import settings
from core.forms.common import CommonModelForm
from core.forms.validate_ticket import TicketValidation
from core.models.ticket.ticket import Ticket, RelatedTickets
class TicketForm(
CommonModelForm,
TicketValidation,
):
class Meta:
model = Ticket
fields = '__all__'
def __init__(self, request, *args, **kwargs):
self.request = request
super().__init__(*args, **kwargs)
self.fields['planned_start_date'].widget = forms.widgets.DateTimeInput(attrs={'type': 'datetime-local', 'format': "%Y-%m-%dT%H:%M"})
self.fields['planned_start_date'].input_formats = settings.DATETIME_FORMAT
self.fields['planned_start_date'].format="%Y-%m-%dT%H:%M"
self.fields['planned_finish_date'].widget = forms.widgets.DateTimeInput(attrs={'type': 'datetime-local'})
self.fields['planned_finish_date'].input_formats = settings.DATETIME_FORMAT
self.fields['planned_finish_date'].format="%Y-%m-%dT%H:%M"
self.fields['real_start_date'].widget = forms.widgets.DateTimeInput(attrs={'type': 'datetime-local'})
self.fields['real_start_date'].input_formats = settings.DATETIME_FORMAT
self.fields['real_start_date'].format="%Y-%m-%dT%H:%M"
self.fields['real_finish_date'].widget = forms.widgets.DateTimeInput(attrs={'type': 'datetime-local'})
self.fields['real_finish_date'].input_formats = settings.DATETIME_FORMAT
self.fields['real_finish_date'].format="%Y-%m-%dT%H:%M"
self.fields['description'].widget.attrs = {'style': "height: 800px; width: 900px"}
self.fields['opened_by'].initial = kwargs['user'].pk
self.fields['opened_by'].widget = self.fields['opened_by'].hidden_widget()
self.fields['ticket_type'].widget = self.fields['ticket_type'].hidden_widget()
self.fields['organization'].initial = self.initial['organization']
if self.instance.pk is not None:
del self.fields['organization']
if self.instance.project is not None:
self.fields['milestone'].queryset = self.fields['milestone'].queryset.filter(
project=self.instance.project
)
else:
self.fields['milestone'].queryset = self.fields['milestone'].queryset.filter(
id=0
)
original_fields = self.fields.copy()
ticket_type = []
if kwargs['initial']['type_ticket'] == 'request':
ticket_type = self.Meta.model.fields_itsm_request
self.fields['status'].choices = self.Meta.model.TicketStatus.Request
self.fields['ticket_type'].initial = '1'
self.fields['category'].queryset = self.fields['category'].queryset.filter(
request=True
)
elif kwargs['initial']['type_ticket'] == 'incident':
ticket_type = self.Meta.model.fields_itsm_incident
self.fields['status'].choices = self.Meta.model.TicketStatus.Incident
self.fields['ticket_type'].initial = self.Meta.model.TicketType.INCIDENT.value
self.fields['category'].queryset = self.fields['category'].queryset.filter(
incident=True
)
elif kwargs['initial']['type_ticket'] == 'problem':
ticket_type = self.Meta.model.fields_itsm_problem
self.fields['status'].choices = self.Meta.model.TicketStatus.Problem
self.fields['ticket_type'].initial = self.Meta.model.TicketType.PROBLEM.value
self.fields['category'].queryset = self.fields['category'].queryset.filter(
problem=True
)
elif kwargs['initial']['type_ticket'] == 'change':
ticket_type = self.Meta.model.fields_itsm_change
self.fields['status'].choices = self.Meta.model.TicketStatus.Change
self.fields['ticket_type'].initial = self.Meta.model.TicketType.CHANGE.value
self.fields['category'].queryset = self.fields['category'].queryset.filter(
change=True
)
elif kwargs['initial']['type_ticket'] == 'issue':
ticket_type = self.Meta.model.fields_git_issue
self.fields['status'].choices = self.Meta.model.TicketStatus.Git
self.fields['ticket_type'].initial = self.Meta.model.TicketType.ISSUE.value
elif kwargs['initial']['type_ticket'] == 'merge':
ticket_type = self.Meta.model.fields_git_merge
self.fields['status'].choices = self.Meta.model.TicketStatus.Git
self.fields['ticket_type'].initial = self.Meta.model.TicketType.MERGE_REQUEST.value
elif kwargs['initial']['type_ticket'] == 'project_task':
ticket_type = self.Meta.model.fields_project_task
self.fields['status'].choices = self.Meta.model.TicketStatus.ProjectTask
self._project: int = kwargs['initial']['project']
self.fields['project'].initial = self._project
self.fields['project'].widget = self.fields['project'].hidden_widget()
self.fields['ticket_type'].initial = self.Meta.model.TicketType.PROJECT_TASK.value
self.fields['category'].queryset = self.fields['category'].queryset.filter(
project_task=True
)
if kwargs['user'].is_superuser:
ticket_type += self.Meta.model.tech_fields
self.ticket_type_fields = ticket_type
fields_allowed_by_permission = self.get_fields_allowed_by_permission
allowed_ticket_fields: list = []
for field in fields_allowed_by_permission: # Remove fields not intended for the ticket type
if field in ticket_type:
allowed_ticket_fields = allowed_ticket_fields + [ field ]
for field in original_fields: # Remove fields user cant edit unless field is hidden
if (
(
field not in allowed_ticket_fields and not self.fields[field].widget.is_hidden
)
or
field not in ticket_type
):
# self.fields[field].widget = self.fields[field].hidden_widget()
del self.fields[field]
def clean(self):
cleaned_data = super().clean()
return cleaned_data
def is_valid(self) -> bool:
is_valid = super().is_valid()
self.validate_ticket()
if self._ticket_type == 'change':
self.validate_change_ticket()
elif self._ticket_type == 'incident':
self.validate_incident_ticket()
elif self._ticket_type == 'issue':
# self.validate_issue_ticket()
raise ValidationError(
'This Ticket type is not yet available'
)
elif self._ticket_type == 'merge_request':
# self.validate_merge_request_ticket()
raise ValidationError(
'This Ticket type is not yet available'
)
elif self._ticket_type == 'problem':
self.validate_problem_ticket()
elif self._ticket_type == 'project_task':
self.validate_project_task_ticket()
elif self._ticket_type == 'request':
self.validate_request_ticket()
else:
raise ValidationError('Ticket Type must be set')
return is_valid
class DetailForm(CommonModelForm):
prefix = 'ticket'
class Meta:
model = Ticket
fields = '__all__'

View File

@ -1,120 +0,0 @@
from django import forms
from django.forms import ValidationError
from django.urls import reverse
from django.conf import settings
from core.forms.common import CommonModelForm
from core.models.ticket.ticket_category import TicketCategory
class TicketCategoryForm(CommonModelForm):
class Meta:
fields = '__all__'
model = TicketCategory
prefix = 'ticket_category'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['parent'].queryset = self.fields['parent'].queryset.exclude(
id=self.instance.pk
)
def clean(self):
cleaned_data = super().clean()
pk = self.instance.id
parent = cleaned_data.get("parent")
if pk:
if parent == pk:
raise ValidationError("Category can't have itself as its parent category")
return cleaned_data
class DetailForm(TicketCategoryForm):
tabs: dict = {
"details": {
"name": "Details",
"slug": "details",
"sections": [
{
"layout": "double",
"left": [
'parent',
'name',
'runbook',
'organization',
'c_created',
'c_modified'
],
"right": [
'model_notes',
]
},
{
"layout": "double",
"name": "Ticket Types",
"left": [
'change',
'problem',
'request'
],
"right": [
'incident',
'project_task'
]
},
]
},
"notes": {
"name": "Notes",
"slug": "notes",
"sections": []
}
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['c_created'] = forms.DateTimeField(
label = 'Created',
input_formats=settings.DATETIME_FORMAT,
disabled = True,
initial = self.instance.created,
)
self.fields['c_modified'] = forms.DateTimeField(
label = 'Modified',
input_formats=settings.DATETIME_FORMAT,
disabled = True,
initial = self.instance.modified,
)
self.tabs['details'].update({
"edit_url": reverse('Settings:_ticket_category_change', kwargs={'pk': self.instance.pk})
})
self.url_index_view = reverse('Settings:_ticket_categories')

View File

@ -1,163 +0,0 @@
from django import forms
from django.db.models import Q
from django.conf import settings
from core.forms.common import CommonModelForm
from core.forms.validate_ticket_comment import TicketCommentValidation
from core.models.ticket.ticket_comment import TicketComment
class CommentForm(
CommonModelForm,
TicketCommentValidation
):
prefix = 'ticket'
class Meta:
model = TicketComment
fields = '__all__'
def __init__(self, request, *args, **kwargs):
self.request = request
super().__init__(*args, **kwargs)
self._ticket_organization = self.fields['ticket'].queryset.model.objects.get(pk=int(self.initial['ticket'])).organization
self._ticket_type = kwargs['initial']['type_ticket']
if 'qs_comment_type' in kwargs['initial']:
self._comment_type = kwargs['initial']['qs_comment_type']
else:
self._comment_type = str(self.instance.get_comment_type_display()).lower()
self.ticket_comment_permissions
self.fields['planned_start_date'].widget = forms.widgets.DateTimeInput(attrs={'type': 'datetime-local', 'format': "%Y-%m-%dT%H:%M"})
self.fields['planned_start_date'].input_formats = settings.DATETIME_FORMAT
self.fields['planned_start_date'].format="%Y-%m-%dT%H:%M"
self.fields['planned_finish_date'].widget = forms.widgets.DateTimeInput(attrs={'type': 'datetime-local'})
self.fields['planned_finish_date'].input_formats = settings.DATETIME_FORMAT
self.fields['planned_finish_date'].format="%Y-%m-%dT%H:%M"
self.fields['real_start_date'].widget = forms.widgets.DateTimeInput(attrs={'type': 'datetime-local'})
self.fields['real_start_date'].input_formats = settings.DATETIME_FORMAT
self.fields['real_start_date'].format="%Y-%m-%dT%H:%M"
self.fields['real_finish_date'].widget = forms.widgets.DateTimeInput(attrs={'type': 'datetime-local'})
self.fields['real_finish_date'].input_formats = settings.DATETIME_FORMAT
self.fields['real_finish_date'].format="%Y-%m-%dT%H:%M"
self.fields['body'].widget.attrs = {'style': "height: 800px; width: 900px"}
self.fields['duration'].widget = self.fields['duration'].hidden_widget()
self.fields['user'].initial = kwargs['user'].pk
self.fields['user'].widget = self.fields['user'].hidden_widget()
self.fields['ticket'].widget = self.fields['ticket'].hidden_widget()
self.fields['parent'].widget = self.fields['parent'].hidden_widget()
self.fields['comment_type'].widget = self.fields['comment_type'].hidden_widget()
if not( self._has_import_permission or self._has_triage_permission or request.user.is_superuser ):
self.fields['source'].initial = TicketComment.CommentSource.HELPDESK
self.fields['source'].widget = self.fields['source'].hidden_widget()
else:
self.fields['source'].initial = TicketComment.CommentSource.DIRECT
if self._comment_type == 'task':
self.fields['comment_type'].initial = self.Meta.model.CommentType.TASK
self.fields['category'].queryset = self.fields['category'].queryset.filter(
task = True
)
elif self._comment_type == 'comment':
self.fields['comment_type'].initial = self.Meta.model.CommentType.COMMENT
self.fields['category'].queryset = self.fields['category'].queryset.filter(
comment = True
)
elif self._comment_type == 'solution':
self.fields['comment_type'].initial = self.Meta.model.CommentType.SOLUTION
self.fields['category'].queryset = self.fields['category'].queryset.filter(
solution = True
)
elif self._comment_type == 'notification':
self.fields['comment_type'].initial = self.Meta.model.CommentType.NOTIFICATION
self.fields['category'].queryset = self.fields['category'].queryset.filter(
notification = True
)
allowed_fields = self.fields_allowed
original_fields = self.fields.copy()
for field in original_fields:
if field not in allowed_fields and not self.fields[field].widget.is_hidden:
del self.fields[field]
def clean(self):
cleaned_data = super().clean()
return cleaned_data
def is_valid(self) -> bool:
is_valid = super().is_valid()
validate_ticket_comment: bool = self.validate_ticket_comment()
if not validate_ticket_comment:
is_valid = validate_ticket_comment
return is_valid
class DetailForm(CommentForm):
prefix = 'ticket'
class Meta:
model = TicketComment
fields = '__all__'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

View File

@ -1,119 +0,0 @@
from django import forms
from django.forms import ValidationError
from django.urls import reverse
from django.conf import settings
from core.forms.common import CommonModelForm
from core.models.ticket.ticket_comment_category import TicketCommentCategory
class TicketCommentCategoryForm(CommonModelForm):
class Meta:
fields = '__all__'
model = TicketCommentCategory
prefix = 'ticket_comment_category'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['parent'].queryset = self.fields['parent'].queryset.exclude(
id=self.instance.pk
)
def clean(self):
cleaned_data = super().clean()
pk = self.instance.id
parent = cleaned_data.get("parent")
if pk:
if parent == pk:
raise ValidationError("Category can't have itself as its parent category")
return cleaned_data
class DetailForm(TicketCommentCategoryForm):
tabs: dict = {
"details": {
"name": "Details",
"slug": "details",
"sections": [
{
"layout": "double",
"left": [
'parent',
'name',
'runbook',
'organization',
'c_created',
'c_modified'
],
"right": [
'model_notes',
]
},
{
"layout": "double",
"name": "Comment Types",
"left": [
'comment',
'solution'
],
"right": [
'notification',
'task'
]
},
]
},
"notes": {
"name": "Notes",
"slug": "notes",
"sections": []
}
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['c_created'] = forms.DateTimeField(
label = 'Created',
input_formats=settings.DATETIME_FORMAT,
disabled = True,
initial = self.instance.created,
)
self.fields['c_modified'] = forms.DateTimeField(
label = 'Modified',
input_formats=settings.DATETIME_FORMAT,
disabled = True,
initial = self.instance.modified,
)
self.tabs['details'].update({
"edit_url": reverse('Settings:_ticket_comment_category_change', kwargs={'pk': self.instance.pk})
})
self.url_index_view = reverse('Settings:_ticket_comment_categories')

View File

@ -1,26 +0,0 @@
from django import forms
from django.db.models import Q
from django.forms import ValidationError
from django.conf import settings
from core.forms.common import CommonModelForm
from core.models.ticket.ticket_linked_items import TicketLinkedItem
class TicketLinkedItemForm(CommonModelForm):
prefix = 'ticket_linked_item'
class Meta:
model = TicketLinkedItem
fields = '__all__'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['organization'].widget = self.fields['organization'].hidden_widget()
self.fields['ticket'].widget = self.fields['ticket'].hidden_widget()

View File

@ -1,681 +0,0 @@
from django.core.exceptions import PermissionDenied, ValidationError
from rest_framework import serializers
from access.mixin import OrganizationMixin
class TicketValidation(
OrganizationMixin,
):
"""Ticket Form/Serializer Validation
Validate a ticket form or api viewset
## Class requirements
- attribute `ticket_type_fields` is set to a list of fields for the ticket type
- attribute `ticket_type` is set to a string value (lowercase) of the ticket type
Raises:
PermissionDenied: User has no allowable fields to edit
PermissionDenied: User is lacking permission to edit a field
serializers.ValidationError: Status field has a value set that does not meet the ticket type
ValidationError: Status field has a value set that does not meet the ticket type
"""
original_object = None
add_fields: list = [
'title',
'description',
'urgency',
'organization'
]
change_fields: list = []
delete_fields: list = [
'is_deleted',
]
import_fields: list = [
'assigned_users',
'assigned_teams',
'category',
'created',
'date_closed',
'estimate',
'external_ref',
'external_system',
'status',
'impact',
'opened_by',
'planned_start_date',
'planned_finish_date',
'priority',
'project',
'milestone',
'real_start_date',
'real_finish_date',
'subscribed_users',
'subscribed_teams',
'ticket_type',
]
triage_fields: list = [
'category',
'assigned_users',
'assigned_teams',
'estimate',
'status',
'impact',
'opened_by',
'planned_start_date',
'planned_finish_date',
'priority',
'project',
'milestone',
'real_start_date',
'real_finish_date',
'subscribed_users',
'subscribed_teams',
]
def combined_validation_error(self, message:str, code:str = None) -> None:
if 'serializers' in self.Meta.__module__:
raise serializers.ValidationError(
detail = message,
code = code
)
else:
raise ValidationError(
message = message,
code = code
)
@property
def get_fields_allowed_by_permission(self) -> list(str()):
"""Obtain Fields that the user can edit
First obtain the users organization. As this can be found in multiple
locations, first check and fetch from the existing ticket. If this is
a new ticket, the organization should have been supplied, so use that.
Check the permission after building the required permission using the
ticket type.
Returns:
list(str()): Fields the user can edit.
"""
if hasattr(self, '_fields_allowed_by_permission'):
return self._fields_allowed_by_permission
if not hasattr(self, '_ticket_type'):
self._ticket_type = self.initial['type_ticket']
fields_allowed: list = []
ticket_organization = None
if self.instance is not None:
if self.instance.pk:
ticket_organization = self.instance.organization
if ticket_organization is None:
ticket_organization = self.initial['organization']
if ticket_organization is None:
if 'organization' in self.data:
ticket_organization = self.fields['organization'].queryset.model.objects.get(pk=self.data['organization'])
if self.has_organization_permission(
organization=ticket_organization.id,
permissions_required = [ 'core.add_ticket_'+ self._ticket_type ],
) and not self.request.user.is_superuser:
fields_allowed = self.add_fields
if self.has_organization_permission(
organization=ticket_organization.id,
permissions_required = [ 'core.change_ticket_'+ self._ticket_type ],
) and not self.request.user.is_superuser:
if len(fields_allowed) == 0:
fields_allowed = self.add_fields + self.change_fields
else:
fields_allowed = fields_allowed + self.change_fields
if self.has_organization_permission(
organization=ticket_organization.id,
permissions_required = [ 'core.delete_ticket_'+ self._ticket_type ],
) and not self.request.user.is_superuser:
fields_allowed = fields_allowed + self.delete_fields
if self.has_organization_permission(
organization=ticket_organization.id,
permissions_required = [ 'core.import_ticket_'+ self._ticket_type ],
) and not self.request.user.is_superuser:
if hasattr(self, 'serializer_choice_field'):
fields_allowed = fields_allowed + self.import_fields
if self.has_organization_permission(
organization=ticket_organization.id,
permissions_required = [ 'core.triage_ticket_'+ self._ticket_type ],
) and not self.request.user.is_superuser:
fields_allowed = fields_allowed + self.triage_fields
if self.request.user.is_superuser:
all_fields: list = self.add_fields
all_fields = all_fields + self.change_fields
all_fields = all_fields + self.delete_fields
all_fields = all_fields + self.import_fields
all_fields = all_fields + self.triage_fields
fields_allowed = fields_allowed + all_fields
self._fields_allowed_by_permission = fields_allowed
return fields_allowed
@property
def get_user_changed_data(self) -> dict:
"""Create an object with the user 'changed' data.
Due to forms having fields deleted, this function is required
as attribute `cleaned_data` no longer functions per normal.
Returns:
_user_changed_data (dict): Changed data.
"""
if hasattr(self, '_user_changed_data'):
return self._user_changed_data
changed_data: dict = {}
for field in self.get_user_changed_fields:
if hasattr(self.Meta.model, field):
changed_data.update({
field: self.request.POST.dict()[field]
})
if len(changed_data) > 0:
self._user_changed_data = changed_data
return changed_data
@property
def get_user_changed_fields(self) -> list(str()):
"""List of fields the user changed.
This data is sourced from the HTTP/POST data.
Returns:
list: All of the fields that have changed.
"""
if hasattr(self, '_user_changed_fields'):
return self._user_changed_fields
changed_data: list = []
changed_data_exempt = [
'_state',
'csrfmiddlewaretoken',
'ticket_comments',
'url',
]
post_data: dict = self.request.POST.dict().copy()
for field in post_data:
if hasattr(self.Meta.model, field):
changed_data = changed_data + [ field ]
if len(changed_data) > 0:
self._user_changed_fields = changed_data
return changed_data
@property
def validate_field_permission(self):
""" Check field permissions
Users can't edit all fields. They can only adjust fields that they
have the permissions to adjust.
## Required fields
A field marked as required when the instance has no pk, the field will have
it's permission marked as allowed. This is not the case for items thaat are being
edited, i.e. have a pk.
Raises:
ValidationError: Access Denied when user has no ticket permissions assigned
ValidationError: User tried to edit a field they dont have permission to edit.
"""
fields_allowed = self.get_fields_allowed_by_permission
if len(fields_allowed) == 0:
self.combined_validation_error('Access Denied to all fields', code='access_denied_all_fields')
for field in self.get_user_changed_fields:
allowed: bool = False
if (
field in self.fields
and field in self.ticket_type_fields
and (
field in fields_allowed
)
):
allowed = True
if hasattr(self.instance, 'pk'):
if (
field in self.fields
and field in self.ticket_type_fields
and self.instance.pk is None
):
if self.fields[field].required:
allowed = True
elif self.instance is None:
if self.fields[field].required:
allowed = True
if not allowed:
if (
self.field_edited(field)
or (
field not in fields_allowed
and hasattr(self.Meta.model, field)
)
):
self.combined_validation_error(
f'cant edit field: {field}',
code=f'cant_edit_field_{field}',
)
return False
return True
def field_edited(self, field:str) -> bool:
if hasattr(self, 'cleaned_data'): # initial avail in ui
initial_data: dict = self.initial
changed_data: dict = self.get_user_changed_data
elif hasattr(self, 'validated_data'): # API
initial_data:dict = self.instance.__dict__
changed_data: dict = self.validated_data
if field in initial_data:
value = initial_data[field]
elif str(field) + '_id' in initial_data:
value = initial_data[str(field) + '_id']
else:
return True
if field in changed_data:
if changed_data[field] == value:
return False
if hasattr(changed_data[field], 'id'):
if value is None:
return True
if int(value) == changed_data[field].id:
return False
else:
val = value
if value is None:
return True
if type(changed_data[field]) is int:
val = int(value)
elif type(changed_data[field]) is bool:
val = bool(value)
elif type(changed_data[field]) is str:
val = str(value)
if val == changed_data[field]:
return False
else:
return False
return True
def validate_field_milestone(self):
is_valid: bool = False
if self.instance is not None:
if self.instance.milestone is None:
return True
else:
if self.instance.project is None:
self.combined_validation_error(
f'Milestones require a project',
code=f'milestone_requires_project',
)
return False
if self.instance.project.id == self.instance.milestone.project.id:
return True
else:
self.combined_validation_error(
f'Milestone must be from the same project',
code=f'milestone_same_project',
)
return is_valid
def validate_field_organization(self) -> bool:
"""Check `organization field`
Raises:
ValidationError: user tried to change the organization
Returns:
True (bool): OK
False (bool): User tried to edit the organization
"""
is_valid: bool = True
if self.instance is not None:
if self.instance.pk is not None:
if 'organization' in self.get_user_changed_fields:
if self.field_edited('organization'):
is_valid = False
self.combined_validation_error(
f'cant edit field: organization',
code=f'cant_edit_field_organization',
)
return is_valid
def validate_field_status(self):
"""Validate status field
Ticket status depends upon ticket type.
Ensure that the corrent status is used.
"""
is_valid = False
if not hasattr(self, '_ticket_type'):
self._ticket_type = self.initial['type_ticket']
try:
if hasattr(self, 'cleaned_data'):
field = self.cleaned_data['status']
else:
field = self.validated_data['status']
except KeyError:
# field = self.fields['status'].default.value
field = getattr(self.Meta.model, 'status').field.default.value
if self._ticket_type == 'request':
if field in self.Meta.model.TicketStatus.Request._value2member_map_:
is_valid = True
elif self._ticket_type == 'incident':
if field in self.Meta.model.TicketStatus.Incident._value2member_map_:
is_valid = True
elif self._ticket_type == 'problem':
if field in self.Meta.model.TicketStatus.Problem._value2member_map_:
is_valid = True
elif self._ticket_type == 'change':
if field in self.Meta.model.TicketStatus.Change._value2member_map_:
is_valid = True
elif self._ticket_type == 'issue':
if field in self.Meta.model.TicketStatus.Issue._value2member_map_:
is_valid = True
elif self._ticket_type == 'merge':
if field in self.Meta.model.TicketStatus.Merge._value2member_map_:
is_valid = True
elif self._ticket_type == 'project_task':
if field in self.Meta.model.TicketStatus.ProjectTask._value2member_map_:
is_valid = True
if not is_valid:
if hasattr(self, 'validated_data'):
raise serializers.ValidationError('Incorrect Status set')
else:
self.combined_validation_error('Incorrect Status set')
return is_valid
def validate_ticket(self):
"""Validations common to all ticket types."""
is_valid = False
fields: list = []
if hasattr(self, 'validated_data'):
fields = self.validated_data
else:
fields = self.cleaned_data
validate_field_permission = False
if self.validate_field_permission:
validate_field_permission = True
validate_field_organization: bool = False
if self.validate_field_organization():
validate_field_organization = True
validate_field_milestone: bool = False
if self.validate_field_milestone():
validate_field_milestone: bool = True
validate_field_status = False
if self.validate_field_status():
validate_field_status = True
if (
validate_field_permission
and validate_field_status
and validate_field_milestone
and validate_field_organization
):
is_valid = True
return is_valid
def validate_change_ticket(self):
# check status
# check type
pass
def validate_incident_ticket(self):
# check status
# check type
pass
def validate_problem_ticket(self):
# check status
# check type
pass
def validate_request_ticket(self):
# check status
# check type
# self.combined_validation_error('Test to see what it looks like')
pass
def validate_project_task_ticket(self):
if hasattr(self,'_project'):
self.cleaned_data.update({
'project': self._project
})
if self.cleaned_data['project'] is None:
self.combined_validation_error('A project task requires a project')

View File

@ -1,276 +0,0 @@
from django.core.exceptions import PermissionDenied
from django.forms import ValidationError
from rest_framework import serializers
from access.mixin import OrganizationMixin
class TicketCommentValidation(
OrganizationMixin,
):
original_object = None
_comment_type:str = None
"""Human readable comment type. i.e. `request` in lowercase"""
_has_add_permission: bool = False
_has_change_permission: bool = False
_has_delete_permission: bool = False
_has_import_permission: bool = False
_has_triage_permission: bool = False
_ticket_organization = None
"""Ticket Organization as a organization object"""
_ticket_type: str = None
"""Human readable type of ticket. i.e. `request` in lowercase"""
request = None
add_fields: list = [
'body',
'duration'
]
change_fields: list = [
'body',
]
delete_fields: list = [
'is_deleted',
]
import_fields: list = [
'organization',
'parent',
'ticket',
'external_ref',
'external_system',
'comment_type',
'body',
'category',
'created',
'modified',
'private',
'duration',
'template',
'is_template',
'source',
'status',
'responsible_user',
'responsible_team',
'user',
'date_closed',
'planned_start_date',
'planned_finish_date',
'real_start_date',
'real_finish_date',
]
triage_fields: list = [
'category',
'body',
'private',
'duration',
'template',
'is_template',
'source',
'status',
'responsible_user',
'responsible_team',
'planned_start_date',
'planned_finish_date',
'real_start_date',
'real_finish_date',
]
@property
def fields_allowed(self) -> list(str()):
""" Get the allowed fields for a ticket ccomment
Returns:
list(str): A list of allowed fields for the user
"""
if self.request is None:
raise ValueError('Attribute self.request must be set')
fields_allowed: list = []
if self._has_add_permission and not self.request.user.is_superuser:
fields_allowed = self.add_fields
if self._has_change_permission and not self.request.user.is_superuser:
fields_allowed = self.change_fields
if self._has_delete_permission and not self.request.user.is_superuser:
fields_allowed = fields_allowed + self.delete_fields
if self._has_import_permission and not self.request.user.is_superuser:
fields_allowed = fields_allowed + self.import_fields
if self._has_triage_permission and not self.request.user.is_superuser:
fields_allowed = fields_allowed + self.triage_fields
if self.request.user.is_superuser:
all_fields: list = self.add_fields
all_fields = all_fields + self.change_fields
all_fields = all_fields + self.delete_fields
all_fields = all_fields + self.import_fields
all_fields = all_fields + self.triage_fields
fields_allowed = fields_allowed + all_fields
comment_fields = []
if (
self._ticket_type == 'request'
or
self._ticket_type == 'incident'
or
self._ticket_type == 'problem'
or
self._ticket_type == 'change'
or
self._ticket_type == 'project_task'
):
if self._comment_type == 'task':
comment_fields = self.Meta.model.fields_itsm_task
self.fields['comment_type'].initial = self.Meta.model.CommentType.TASK
elif self._comment_type == 'comment':
comment_fields = self.Meta.model.common_itsm_fields
self.fields['comment_type'].initial = self.Meta.model.CommentType.COMMENT
elif self._comment_type == 'solution':
comment_fields = self.Meta.model.common_itsm_fields
self.fields['comment_type'].initial = self.Meta.model.CommentType.SOLUTION
elif self._comment_type == 'notification':
comment_fields = self.Meta.model.fields_itsm_notification
self.fields['comment_type'].initial = self.Meta.model.CommentType.NOTIFICATION
elif self._ticket_type == 'issue':
comment_fields = self.Meta.model.fields_git_issue
elif self._ticket_type == 'merge':
comment_fields = self.Meta.model.fields_git_merge
for comment_field in comment_fields:
if comment_field not in fields_allowed:
comment_fields.remove(comment_field)
return comment_fields
@property
def ticket_comment_permissions(self):
if self._ticket_organization is None:
raise ValueError('Attribute self._ticket_organization must be set')
if self.request is None:
raise ValueError('Attribute self.request must be set')
if self.has_organization_permission(
organization=self._ticket_organization.id,
permissions_required = [ 'core.add_ticket_'+ self._ticket_type ],
) and not self.request.user.is_superuser:
self._has_add_permission = True
if (
self.has_organization_permission(
organization=self._ticket_organization.id,
permissions_required = [ 'core.change_ticketcomment' ],
) or
self.request.user.id == self.instance.user_id
) and not self.request.user.is_superuser:
self._has_change_permission = True
if self.has_organization_permission(
organization=self._ticket_organization.id,
permissions_required = [ 'core.delete_ticketcomment' ],
) and not self.request.user.is_superuser:
self._has_delete_permission = True
if self.has_organization_permission(
organization=self._ticket_organization.id,
permissions_required = [ 'core.import_ticketcomment' ],
) and not self.request.user.is_superuser:
self._has_import_permission = True
if self.has_organization_permission(
organization=self._ticket_organization.id,
permissions_required = [ 'core.triage_ticket_'+ self._ticket_type ],
) and not self.request.user.is_superuser:
self._has_triage_permission = True
if (
not self._has_triage_permission and (
self._comment_type == 'notification' or
self._comment_type == 'task' or
self._comment_type == 'solution'
)
) and not self.request.user.is_superuser:
raise PermissionDenied("You dont have permission for comment types: notification, task and solution")
def validate_ticket_comment(self) -> bool:
is_valid: bool = True
self.ticket_comment_permissions
fields_allowed = self.fields_allowed
for field in self.change_fields:
if field not in fields_allowed:
raise PermissionDenied(f'You tried to edit a field ({field}) that you dont have access to edit')
return is_valid

View File

@ -1,138 +0,0 @@
{% extends 'base.html.j2' %}
{% load json %}
{% load markdown %}
{% block content %}
<script>
function openCity(evt, cityName) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the button that opened the tab
document.getElementById(cityName).style.display = "block";
evt.currentTarget.className += " active";
}
</script>
<div class="tab">
<button onclick="window.location='{% url 'Settings:_task_results' %}';"
style="vertical-align: middle; padding: auto; margin: 0px">
<svg xmlns="http://www.w3.org/2000/svg" height="25px" viewBox="0 -960 960 960" width="25px"
style="vertical-align: middle; margin: 0px; padding: 0px border: none; " fill="#6a6e73">
<path d="m313-480 155 156q11 11 11.5 27.5T468-268q-11 11-28 11t-28-11L228-452q-6-6-8.5-13t-2.5-15q0-8 2.5-15t8.5-13l184-184q11-11 27.5-11.5T468-692q11 11 11 28t-11 28L313-480Zm264 0 155 156q11 11 11.5 27.5T732-268q-11 11-28 11t-28-11L492-452q-6-6-8.5-13t-2.5-15q0-8 2.5-15t8.5-13l184-184q11-11 27.5-11.5T732-692q11 11 11 28t-11 28L577-480Z" />
</svg> Back to Task Results</button>
<button id="defaultOpen" class="tablinks" onclick="openCity(event, 'Details')">Details</button>
<!-- <button class="tablinks" onclick="openCity(event, 'Installations')">Installations</button> -->
</div>
<style>
.detail-view-field {
display:unset;
height: 30px;
line-height: 30px;
padding: 0px 20px 40px 20px;
}
.detail-view-field label {
display: inline-block;
font-weight: bold;
width: 200px;
margin: 10px;
/*padding: 10px;*/
height: 30px;
line-height: 30px;
}
.detail-view-field span {
display: inline-block;
width: 340px;
margin: 10px;
/*padding: 10px;*/
border-bottom: 1px solid #ccc;
height: 30px;
line-height: 30px;
}
</style>
<div id="Details" class="tabcontent">
<h3>Details </h3>
<div style="align-items:flex-start; align-content: center; display: flexbox; width: 100%">
<div style="display: inline; width: 40%; margin: 30px;">
<div class="detail-view-field">
<label>{{ form.task_id.label }}</label>
<span>{{ form.task_id.value }}</span>
</div>
<div class="detail-view-field">
<label>{{ form.task_name.label }}</label>
<span>{{ form.task_name.value }}</span>
</div>
<div class="detail-view-field">
<label>{{ form.status.label }}</label>
<span>{{ form.status.value }}</span>
</div>
<div class="detail-view-field">
<label>Created</label>
<span>{{ task_result.date_created }}</span>
</div>
<div class="detail-view-field">
<label>Finished</label>
<span>{{ task_result.date_done }}</span>
</div>
</div>
<div style="display: inline; width: 40%; margin: 30px; text-align: left;">
<div>
<label style="font-weight: bold; width: 100%; border-bottom: 1px solid #ccc; display: block; text-align: inherit;">{{ form.task_args.label }}</label>
<div style="display: inline-block; text-align: left;">{{ form.task_args.value }}</div>
</div>
<br />
<div>
<label style="font-weight: bold; width: 100%; border-bottom: 1px solid #ccc; display: block; text-align: inherit;">Result</label>
<div style="display: inline-block; text-align: left;"><pre style="text-align: left; max-width: 300px;">{{ task_result.result | json_pretty }}</pre></div>
</div>
</div>
</div>
<script>
// Get the element with id="defaultOpen" and click on it
document.getElementById("defaultOpen").click();
</script>
</div>
{% endblock %}

View File

@ -1,25 +0,0 @@
{% extends 'base.html.j2' %}
{% block content %}
<input type="button" value="<< Back to settings" onclick="window.location='{% url 'Settings:Settings' %}';">
<table style="max-width: 100%;">
<thead>
<th>ID</th>
<th>Name</th>
<th>Status</th>
<th>Created</th>
<th>Completed</th>
</thead>
{% for entry in task_results %}
<tr class="clicker">
<td><a href="{% url 'Settings:_task_result_view' pk=entry.id %}">{{ entry.task_id }}</a></td>
<td>{{ entry.task_name }}</td>
<td>{{ entry.status }}</td>
<td>{{ entry.date_created }}</td>
<td>{{ entry.date_done }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}

View File

@ -1,47 +0,0 @@
{% extends 'base.html.j2' %}
{% block content %}
<input type="button" value="<< Back to settings" onclick="window.location='{% url 'Settings:Settings' %}';">
<input type="button" value="New Category" onclick="window.location='{% url 'Settings:_ticket_category_add' %}';">
<table style="max-width: 100%;">
<thead>
<th>Name</th>
<th>Organization</th>
<th>created</th>
<th>modified</th>
<th>&nbsp;</th>
</thead>
{% if items %}
{% for category in items %}
<tr>
<td><a href="{% url 'Settings:_ticket_category_view' pk=category.id %}">{{ category.name }}</a></td>
<td>{{ category.organization }}</td>
<td>{{ category.created }}</td>
<td>{{ category.modified }}</td>
<td>&nbsp;</td>
</tr>
{% endfor %}
{% else %}
<tr><td colspan="5">Nothing Found</td></tr>
{% endif%}
</table>
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
<a href="?page=1">&laquo; first</a>
<a href="?page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">next</a>
<a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
{% endif %}
</span>
</div>
{% endblock %}

View File

@ -1,47 +0,0 @@
{% extends 'base.html.j2' %}
{% block content %}
<input type="button" value="<< Back to settings" onclick="window.location='{% url 'Settings:Settings' %}';">
<input type="button" value="New Category" onclick="window.location='{% url 'Settings:_ticket_comment_category_add' %}';">
<table style="max-width: 100%;">
<thead>
<th>Name</th>
<th>Organization</th>
<th>created</th>
<th>modified</th>
<th>&nbsp;</th>
</thead>
{% if items %}
{% for category in items %}
<tr>
<td><a href="{% url 'Settings:_ticket_comment_category_view' pk=category.id %}">{{ category.name }}</a></td>
<td>{{ category.organization }}</td>
<td>{{ category.created }}</td>
<td>{{ category.modified }}</td>
<td>&nbsp;</td>
</tr>
{% endfor %}
{% else %}
<tr><td colspan="5">Nothing Found</td></tr>
{% endif%}
</table>
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
<a href="?page=1">&laquo; first</a>
<a href="?page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">next</a>
<a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
{% endif %}
</span>
</div>
{% endblock %}

View File

@ -1,34 +0,0 @@
{% extends 'detail.html.j2' %}
{% load json %}
{% load markdown %}
{% block tabs %}
<form action="" method="post">
{% csrf_token %}
<div id="details" class="content-tab">
{% include 'content/section.html.j2' with tab=form.tabs.details %}
</div>
<div id="notes" class="content-tab">
{% include 'content/section.html.j2' with tab=form.tabs.notes %}
{{ notes_form }}
<input type="submit" name="{{notes_form.prefix}}" value="Submit" />
<div class="comments">
{% if notes %}
{% for note in notes%}
{% include 'note.html.j2' %}
{% endfor %}
{% endif %}
</div>
</div>
</form>
{% endblock %}

View File

@ -1,163 +0,0 @@
{% extends 'base.html.j2' %}
{% block additional-stylesheet %}
{% load static %}
<link rel="stylesheet" href="{% static 'ticketing.css' %}">
{% endblock additional-stylesheet %}
{% load markdown %}
{% block article %}
<div id="ticket-content">
<div id="ticket-data">
<div id="ticket-description">
<h3 class="{{ ticket_type }}-ticket">
<span class="sub-script">opened by</span> {{ ticket.opened_by }} <span class="sub-script">on</span> {{ ticket.created }}
{% if ticket.created|date_time_seconds != ticket.modified|date_time_seconds %}
<span class="sub-script">Updated</span> {{ ticket.modified }}
{% endif %}
</h3>
<div>
<input style="float: right; position: relative; margin: 0px;" type="button" value="Edit" onclick="window.location='{{ edit_url }}';">
</div>
<div id="markdown">{{ ticket.description | markdown | safe }}</div>
</div>
<div id="ticket-additional-data">
<div id="data-block">
<h3>
<div id="text">Related Tickets</div>
<div id="icons">
<a href="{% url '_ticket_related_add' ticket_type=ticket_type ticket_id=ticket.id %}">{% include 'icons/ticket/add.svg' %}</a>
</div>
</h3>
{% if ticket.related_tickets %}
{% for related_ticket in ticket.related_tickets %}
<div id="linked-tickets" class="{{ related_ticket.type }}-ticket">
<div class="icon icon-{{ related_ticket.how_related }}">{% include related_ticket.icon_filename %}</div>
<div id="markdown" class="ticket">
{% if related_ticket.how_related == 'blocked_by' %}
Blocked by
{% elif related_ticket.how_related == 'blocks' %}
Blocks
{% elif related_ticket.how_related == 'related' %}
Related to
{% endif %}
<span style="display: inline-block;">{{ related_ticket.markdown | markdown | safe }}</span>
</div>
</div>
{% endfor %}
{% else %}
<div>Nothing Found</div>
{% endif %}
</div>
<div id="data-block" class="linked-item">
<h3>
<div id="text">Linked Items</div>
<div id="icons">
<a href="{% url '_ticket_linked_item_add' ticket_type=ticket_type ticket_id=ticket.id %}">{% include 'icons/ticket/add.svg' %}</a>
</div>
</h3>
{% if ticket.linked_items %}
{% for linked_item in ticket.linked_items %}
<div id="item">{{ linked_item | markdown | safe }}</div>
{% endfor %}
{% else %}
<div style="text-align:center;%">Nothing found</div>
{% endif%}
</div>
</div>
{% include 'core/ticket/comment.html.j2' %}
</div>
<div id="ticket-meta">
<h3 class="{{ ticket_type }}-ticket">
{{ ticket_type }} <span style="font-size: smaller;">#{{ ticket.id }}
{% if ticket.external_ref %}
<span style="display: inline-block;" title="External system {{ ticket.get_external_system_display }}">(#{{ ticket.external_ref }})</span>
{% endif %}</span>
</h3>
<fieldset>
<label>Assigned</label>
<span class="text">
{% if ticket.assigned_users %}
{% for user in ticket.assigned_users.all %}
{{ user }}
{% endfor%}
{% endif %}
{% if ticket.assigned_teams %}
{% for team in ticket.assigned_teams.all %}
{{ team }}
{% endfor%}
{% endif %}
</span>
</fieldset>
<fieldset>
<label>Status</label>
<span>{% include 'core/ticket/badge_ticket_status.html.j2' with ticket_status_text=ticket.get_status_display ticket_status=ticket.get_status_display|ticket_status %}</span>
</fieldset>
<fieldset>
<label>Labels</label>
<span class="text">val</span>
</fieldset>
{% if ticket.category %}
<fieldset>
<label>Category</label>
<span class="text">
<a href="{% url 'Settings:_ticket_category_view' pk=ticket.category.id %}">
{{ ticket.category }}
</a>
</span>
</fieldset>
{% endif %}
{% if ticket.project %}
<fieldset>
<label>Project</label>
<span class="text">
<a href="{% url 'Project Management:_project_view' pk=ticket.project_id %}">{{ ticket.project }}</a>
</span>
</fieldset>
{% endif %}
{% if ticket.milestone %}
<fieldset>
<label>Milestone</label>
<span class="text">
<a href="{% url 'Project Management:_project_milestone_view' project_id=ticket.project_id pk=ticket.milestone.id %}">{{ ticket.milestone }}</a>
</span>
</fieldset>
{% endif %}
<fieldset>
<label>Priority</label>
<span class="text">U{{ ticket.get_urgency_display }} / I{{ ticket.get_impact_display }} / P{{ ticket.get_priority_display }}</span>
</fieldset>
<fieldset>
<label>Duration</label>
<span class="text">{{ ticket.duration_ticket|to_duration }}</span>
</fieldset>
<fieldset>
<label>Milestone</label>
<span class="text">val</span>
</fieldset>
<fieldset>
<label>Roadmap(s)</label>
<span class="text">val</span>
</fieldset>
</div>
</div>
{% endblock %}

View File

@ -1,6 +0,0 @@
<span id="badge">
<span id="icon" class="ticket-status ticket-status-{{ ticket_status }}">
{% include 'core/ticket/icon_status.html.j2' %}
</span>
<span id="text">{{ ticket_status_text }}</span>
</span>

View File

@ -1,89 +0,0 @@
{% load i18n %}
{% if ticket_type == 'change'%}
{% translate 'ITIM:_ticket_comment_change_reply_add' as comment_reply_url %}
{% elif ticket_type == 'incident'%}
{% translate 'ITIM:_ticket_comment_incident_reply_add' as comment_reply_url %}
{% elif ticket_type == 'project_task'%}
{% translate 'Project Management:_project_task_comment_reply_add' as comment_reply_url %}
{% elif ticket_type == 'problem'%}
{% translate 'ITIM:_ticket_comment_problem_reply_add' as comment_reply_url %}
{% elif ticket_type == 'request'%}
{% translate 'Assistance:_ticket_comment_request_reply_add' as comment_reply_url %}
{% endif %}
<div id="ticket-comments">
<ul>
{% for comment in ticket.comments %}
<li {% if comment.get_comment_type_display == 'Action' %}id="{{ comment.get_comment_type_display }}"{% endif %}>
{% include 'core/ticket/comment/comment.html.j2' %}
{% if comment.threads %}
<div id="discussion" style="/*background-color: #fff;*/">
<h4 style="display: flex; padding-left: 5px;">
Replies
{% include 'icons/ticket/expanded.svg' %}
</h4>
</div>
<div style="padding-left: 40px; border-left: 1px solid #177fe66e; border-bottom: 1px solid #177fe66e;">
{% if comment.threads %}
{% for thread in comment.threads %}
{% include 'core/ticket/comment/comment.html.j2' with comment=thread %}
{% endfor %}
{% endif %}
<div >
<div style="padding: 10px; padding-top: 10px">
{% if ticket_type == 'project_task'%}
<input type="button" value="Comment" onclick="window.location='{% url comment_reply_url ticket.project.id ticket_type ticket.id comment.id %}?comment_type=comment';">
<input type="button" value="Task" onclick="window.location='{% url comment_reply_url ticket.project.id ticket_type ticket.id comment.id %}?comment_type=task';">
{% else %}
<input type="button" value="Comment" onclick="window.location='{% url comment_reply_url ticket_type ticket.id comment.id %}?comment_type=comment';">
<input type="button" value="Task" onclick="window.location='{% url comment_reply_url ticket_type ticket.id comment.id %}?comment_type=task';">
{% endif %}
</div>
</div>
{% endif %}
</li>
{% endfor %}
</ul>
<div id="comment" style="padding: 20px;">
{% if ticket_type == 'change'%}
{% translate 'ITIM:_ticket_comment_change_add' as comment_url %}
{% elif ticket_type == 'incident'%}
{% translate 'ITIM:_ticket_comment_incident_add' as comment_url %}
{% elif ticket_type == 'project_task'%}
{% translate 'Project Management:_project_task_comment_add' as comment_url %}
{% elif ticket_type == 'problem'%}
{% translate 'ITIM:_ticket_comment_problem_add' as comment_url %}
{% elif ticket_type == 'request'%}
{% translate 'Assistance:_ticket_comment_request_add' as comment_url %}
{% endif %}
{% if ticket_type == 'project_task'%}
<input type="button" value="Comment" onclick="window.location='{% url comment_url ticket.project.id ticket_type ticket.id%}?comment_type=comment';">
<input type="button" value="Task" onclick="window.location='{% url comment_url ticket.project.id ticket_type ticket.id %}?comment_type=task';">
<input type="button" value="Notification" onclick="window.location='{% url comment_url ticket.project.id ticket_type ticket.id %}?comment_type=notification';">
<input type="button" value="Resolve" onclick="window.location='{% url comment_url ticket.project.id ticket_type ticket.id %}?comment_type=solution';">
{% else %}
<input type="button" value="Comment" onclick="window.location='{% url comment_url ticket_type ticket.id%}?comment_type=comment';">
<input type="button" value="Task" onclick="window.location='{% url comment_url ticket_type ticket.id %}?comment_type=task';">
<input type="button" value="Notification" onclick="window.location='{% url comment_url ticket_type ticket.id %}?comment_type=notification';">
<input type="button" value="Resolve" onclick="window.location='{% url comment_url ticket_type ticket.id %}?comment_type=solution';">
{% endif %}
</div>
</div>

View File

@ -1,132 +0,0 @@
{% if comment %}
{% load markdown %}
{% if comment.get_comment_type_display == 'Action' %}
<div style="padding: 0px; margin: 0px;"><span style="display: inline-block;">{{ comment.user.username }}&nbsp;</span><span style="display: inline-block;">{{ comment.body | markdown | safe }}</span></div>
{% elif comment.get_comment_type_display == 'Comment' or comment.get_comment_type_display == 'Task' or comment.get_comment_type_display == 'Notification' or comment.get_comment_type_display == 'Solution' %}
<div id="comment" class="comment-type-default comment-type-{{ comment.get_comment_type_display }}">
<h4>
<div id="text">
{{ comment.user }}
<span class="sub-script">{% if comment.get_comment_type_display == 'Task' %}
created a task
{% elif comment.get_comment_type_display == 'Solution' %}
solved
{% else %}
wrote
{% endif %}
on</span> {{ comment.created }}
{% if comment.created|date_time_seconds != comment.modified|date_time_seconds %}
<span class="sub-script">Updated</span> {{ comment.modified }}
{% endif %}
</div>
<div id="icons">
{%if not comment.parent_id %}
{% if ticket_type == 'project_task'%}
<a title="Reply with Comment" href="{% url comment_reply_url ticket.project.id ticket_type ticket.id comment.id %}?comment_type=comment">
{% include 'icons/ticket/reply.svg' %}
</a>
<a title="Reply with Task" href="{% url comment_reply_url ticket.project.id ticket_type ticket.id comment.id %}?comment_type=task">
{% include 'icons/ticket/task.svg' %}
</a>
<a title="Reply with Notification" href="{% url comment_reply_url ticket.project.id ticket_type ticket.id comment.id %}?comment_type=notification">
{% include 'icons/ticket/notification.svg' %}
</a>
{% else %}
<a title="Reply with Comment" href="{% url comment_reply_url ticket_type ticket.id comment.id %}?comment_type=comment">
{% include 'icons/ticket/reply.svg' %}
</a>
<a title="Reply with Task" href="{% url comment_reply_url ticket_type ticket.id comment.id %}?comment_type=task">
{% include 'icons/ticket/task.svg' %}
</a>
<a title="Reply with Notification" href="{% url comment_reply_url ticket_type ticket.id comment.id %}?comment_type=notification">
{% include 'icons/ticket/notification.svg' %}
</a>
{% endif %}
{% endif %}
<a title="Edit Comment" href="{% url 'Assistance:_ticket_comment_request_change' ticket_type ticket.id comment.id %}">
{% include 'icons/ticket/edit.svg' %}
</a>
</div>
</h4>
<div style="line-height:30px;">
{% if comment.get_comment_type_display != 'Notification' %}
<fieldset>
<label>Source</label>
<span>{{ comment.get_source_display }}</span>
</fieldset>
{% endif %}
{% if comment.get_comment_type_display == 'Task' or comment.get_comment_type_display == 'Notification' %}
<fieldset>
<label>Status</label>
<span>{{ comment.get_status_display }}</span>
</fieldset>
{% if comment.get_comment_type_display == 'Task' %}
<fieldset>
<label>Responsible User</label>
<span>{{ comment.responsible_user }}</span>
</fieldset>
{% endif %}
<fieldset>
<label>
{% if comment.get_comment_type_display == 'Task' %}
Responsible Team
{% elif comment.get_comment_type_display == 'Notification' %}
Notify Team
{% endif %}
</label>
<span>{{ comment.responsible_team }}</span>
</fieldset>
{% endif %}
<fieldset>
<label>Category</label>
<span>{{ comment.category }}</span>
</fieldset>
</div>
<hr />
<div id="markdown" style="margin: 15px; padding: 10px; background-color: #fff;">
{{ comment.body | markdown | safe }}
</div>
<hr />
<div>
{% if comment.get_comment_type_display == 'Task' or comment.get_comment_type_display == 'Notification' %}
<fieldset>
<label>Planned Start</label>
<span>{{ comment.planned_start_date }}</span>
</fieldset>
{% if comment.get_comment_type_display == 'Task' %}
<fieldset>
<label>Planned Finish</label>
<span>{{ comment.planned_finish_date }}</span>
</fieldset>
{% endif %}
<fieldset>
<label>Actual Start</label>
<span>{{ comment.real_start_date }}</span>
</fieldset>
<fieldset>
<label>Actual Finish</label>
<span>{{ comment.real_finish_date }}</span>
</fieldset>
{% endif %}
<fieldset>
<label>Duration</label>
<span>{{ comment.duration|to_duration }}</span>
</fieldset>
</div>
</div>
{% endif %}
{% endif %}

View File

@ -1,25 +0,0 @@
{% if ticket_status == 'new' %}
{% include 'icons/ticket/add.svg' %}
{% elif ticket_status == 'assigned' %}
{% include 'icons/ticket/status_assigned.svg' %}
{% elif ticket_status == 'assigned_planning' %}
{% include 'icons/ticket/status_assigned_planning.svg' %}
{% elif ticket_status == 'closed' %}
{% include 'icons/ticket/status_closed.svg' %}
{% elif ticket_status == 'draft' %}
{% include 'icons/ticket/add.svg' %}
{% elif ticket_status == 'pending' %}
{% include 'icons/ticket/status_pending.svg' %}
{% elif ticket_status == 'solved' %}
{% include 'icons/ticket/status_solved.svg' %}
{% elif ticket_status == 'invalid' %}
{% include 'icons/ticket/status_invalid.svg' %}
{% elif ticket_status == 'approvals' %}
{% include 'icons/ticket/status_approvals.svg' %}
{% elif ticket_status == 'accepted' %}
{% include 'icons/ticket/status_accepted.svg' %}
{% elif ticket_status == 'evaluation' %}
{% include 'icons/ticket/status_evaluation.svg' %}
{% elif ticket_status == 'testing' %}
{% include 'icons/ticket/status_testing.svg' %}
{% endif %}

View File

@ -1,67 +0,0 @@
{% extends 'base.html.j2' %}
{% block additional-stylesheet %}
{% load static %}
<link rel="stylesheet" href="{% static 'ticketing.css' %}">
{% endblock additional-stylesheet %}
{% load markdown %}
{% block content %}
<input type="button" value="New Ticket" onclick="window.location='{{ new_ticket_url }}';">
<style>
#status-icon {
margin: 0px;
}
#status-icon svg{
width: 22px;
}
</style>
<table style="max-width: 100%;">
<thead>
<th>&nbsp;</th>
<th>ID</th>
<th>Title</th>
<th>Status</th>
<th>Opened By</th>
<th>organization</th>
<th>Created</th>
</thead>
{% for ticket in tickets %}
<tr class="clicker">
<td id="status-icon">
&nbsp;
</td>
<td>{{ ticket.id }}</td>
<td>
{% if ticket_type == 'change' %}
<a href="{% url 'ITIM:_ticket_change_view' ticket_type='change' pk=ticket.id %}">
{% elif ticket_type == 'incident' %}
<a href="{% url 'ITIM:_ticket_incident_view' ticket_type='incident' pk=ticket.id %}">
{% elif ticket_type == 'problem' %}
<a href="{% url 'ITIM:_ticket_problem_view' ticket_type='problem' pk=ticket.id %}">
{% elif ticket_type == 'request' %}
<a href="{% url 'Assistance:_ticket_request_view' ticket_type='request' pk=ticket.id %}">
{% else %}
<a href=""></a>
{% endif %}
{{ ticket.title }}
</a>
</td>
<td>{% include 'core/ticket/badge_ticket_status.html.j2' with ticket_status_text=ticket.get_status_display ticket_status=ticket.get_status_display|ticket_status %}</td>
<td>{{ ticket.opened_by }}</td>
<td>{{ ticket.organization.name }}</td>
<td>{{ ticket.created }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}

View File

@ -1,17 +0,0 @@
<span id="rendered-ticket-link">
<span id="icon" class="ticket-status ticket-status-{{ ticket_status }}">{% include 'core/ticket/icon_status.html.j2' %}</span>
<span id="text">
<a href=" {% if ticket_type == 'change' %}
{% url 'ITIM:_ticket_change_view' ticket_type='change' pk=id %}
{% elif ticket_type == 'incident' %}
{% url 'ITIM:_ticket_incident_view' ticket_type='incident' pk=id %}
{% elif ticket_type == 'problem' %}
{% url 'ITIM:_ticket_problem_view' ticket_type='problem' pk=id %}
{% elif ticket_type == 'request' %}
{% url 'Assistance:_ticket_request_view' ticket_type='request' pk=id %}
{% elif ticket_type == 'project task' %}
{% url 'Project Management:_project_task_view' project_id=project_id ticket_type='project_task' pk=id %}
{% endif %}"><span style="color: #777;">#{{ id }}</span> {{ name }}, <span style="color: #777;">{{ ticket_type }}</span></a>
</span>
</span>

View File

@ -1,8 +0,0 @@
<span id="ticket-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" class="{{ ticket_type }}-ticket">
<path d="M319.33-246.67h321.34v-66.66H319.33v66.66Zm0-166.66h321.34V-480H319.33v66.67ZM226.67-80q-27 0-46.84-19.83Q160-119.67 160-146.67v-666.66q0-27 19.83-46.84Q199.67-880 226.67-880H574l226 226v507.33q0 27-19.83 46.84Q760.33-80 733.33-80H226.67Zm314-542.67v-190.66h-314v666.66h506.66v-476H540.67Zm-314-190.66v190.66-190.66 666.66-666.66Z"/>
</svg>
</span>

View File

@ -1,12 +0,0 @@
{% extends 'detail.html.j2' %}
{% block tabs %}
<div id="details" class="content-tab">
{% include 'content/section.html.j2' with tab=form.tabs.details %}
</div>
{% endblock %}

View File

@ -1,12 +0,0 @@
{% extends 'detail.html.j2' %}
{% block tabs %}
<div id="details" class="content-tab">
{% include 'content/section.html.j2' with tab=form.tabs.details %}
</div>
{% endblock %}

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M440-280h80v-160h160v-80H520v-160h-80v160H280v80h160v160Zm40 200q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>

Before

Width:  |  Height:  |  Size: 425 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M200-200h57l391-391-57-57-391 391v57Zm-80 80v-170l528-527q12-11 26.5-17t30.5-6q16 0 31 6t26 18l55 56q12 11 17.5 26t5.5 30q0 16-5.5 30.5T817-647L290-120H120Zm640-584-56-56 56 56Zm-141 85-28-29 57 57-29-28Z"/></svg>

Before

Width:  |  Height:  |  Size: 287 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M480-345 240-585l56-56 184 183 184-183 56 56-240 240Z"/></svg>

Before

Width:  |  Height:  |  Size: 136 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M448-201.33h66.67V-391l76 76 46.66-47L480-516.67l-156 156L371-314l77-77v189.67ZM226.67-80q-27 0-46.84-19.83Q160-119.67 160-146.67v-666.66q0-27 19.83-46.84Q199.67-880 226.67-880H574l226 226v507.33q0 27-19.83 46.84Q760.33-80 733.33-80H226.67Zm314-542.67v-190.66h-314v666.66h506.66v-476H540.67Zm-314-190.66v190.66-190.66 666.66-666.66Z"/></svg>

Before

Width:  |  Height:  |  Size: 415 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M760-200v-160q0-50-35-85t-85-35H273l144 144-57 56-240-240 240-240 57 56-144 144h367q83 0 141.5 58.5T840-360v160h-80Z"/></svg>

Before

Width:  |  Height:  |  Size: 199 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M423.28-291.22 708.87-576.8l-62.46-62.7-223.13 223.13L312.15-527.5l-62.45 62.7 173.58 173.58ZM480-71.87q-84.91 0-159.34-32.12-74.44-32.12-129.5-87.17-55.05-55.06-87.17-129.5Q71.87-395.09 71.87-480t32.12-159.34q32.12-74.44 87.17-129.5 55.06-55.05 129.5-87.17 74.43-32.12 159.34-32.12t159.34 32.12q74.44 32.12 129.5 87.17 55.05 55.06 87.17 129.5 32.12 74.43 32.12 159.34t-32.12 159.34q-32.12 74.44-87.17 129.5-55.06 55.05-129.5 87.17Q564.91-71.87 480-71.87Zm0-91q133.04 0 225.09-92.04 92.04-92.05 92.04-225.09 0-133.04-92.04-225.09-92.05-92.04-225.09-92.04-133.04 0-225.09 92.04-92.04 92.05-92.04 225.09 0 133.04 92.04 225.09 92.05 92.04 225.09 92.04ZM480-480Z"/></svg>

Before

Width:  |  Height:  |  Size: 741 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M477.28-240q21.96 0 37.3-15.34 15.33-15.33 15.33-37.32 0-21.99-15.33-37.18-15.34-15.18-37.3-15.18-21.95 0-37.29 15.18-15.34 15.19-15.34 37.18 0 21.99 15.34 37.32Q455.33-240 477.28-240Zm-38.63-154h78.78q0-32.04 7.62-51.28 7.62-19.24 41.43-51.29 25.28-25.04 40.16-48.91 14.88-23.87 14.88-57.39 0-56.89-40.52-87.25t-96.52-30.36q-57.96 0-94.65 31.2-36.7 31.19-51.18 74.63l71.26 27.67q5.48-18.48 22.38-39.24 16.91-20.76 50.99-20.76 29.13 0 43.94 16.31 14.8 16.3 14.8 35.87 0 18.8-11.64 35.94-11.64 17.14-27.97 30.71-43.04 38.52-53.4 59.36-10.36 20.83-10.36 74.79ZM480-71.87q-84.91 0-159.34-32.12-74.44-32.12-129.5-87.17-55.05-55.06-87.17-129.5Q71.87-395.09 71.87-480t32.12-159.34q32.12-74.44 87.17-129.5 55.06-55.05 129.5-87.17 74.43-32.12 159.34-32.12t159.34 32.12q74.44 32.12 129.5 87.17 55.05 55.06 87.17 129.5 32.12 74.43 32.12 159.34t-32.12 159.34q-32.12 74.44-87.17 129.5-55.06 55.05-129.5 87.17Q564.91-71.87 480-71.87Zm0-91q133.04 0 225.09-92.04 92.04-92.05 92.04-225.09 0-133.04-92.04-225.09-92.05-92.04-225.09-92.04-133.04 0-225.09 92.04-92.04 92.05-92.04 225.09 0 133.04 92.04 225.09 92.05 92.04 225.09 92.04ZM480-480Z"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="m380-300 280-180-280-180v360ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>

Before

Width:  |  Height:  |  Size: 397 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M325.07-325.07h69.86v-309.86h-69.86v309.86Zm160-4.65L710.87-480l-225.8-150.28v300.56ZM480.02-73.3q-83.95 0-158.14-31.96-74.19-31.96-129.43-87.19-55.23-55.24-87.19-129.41Q73.3-396.03 73.3-479.98q0-84.61 31.96-158.81 31.96-74.19 87.17-129.1t129.39-86.94q74.18-32.03 158.14-32.03 84.63 0 158.85 32.02 74.21 32.02 129.1 86.91 54.9 54.88 86.92 129.08 32.03 74.2 32.03 158.85 0 83.97-32.03 158.16t-86.94 129.41q-54.91 55.21-129.08 87.17Q564.64-73.3 480.02-73.3Zm-.02-75.76q138.38 0 234.66-96.51 96.28-96.52 96.28-234.43 0-138.38-96.28-234.66t-234.74-96.28q-137.79 0-234.33 96.28-96.53 96.28-96.53 234.74 0 137.79 96.51 234.33 96.52 96.53 234.43 96.53ZM480-480Z"/></svg>

Before

Width:  |  Height:  |  Size: 737 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M318.09-318.09h323.82v-323.82H318.09v323.82ZM480-71.87q-84.91 0-159.34-32.12-74.44-32.12-129.5-87.17-55.05-55.06-87.17-129.5Q71.87-395.09 71.87-480t32.12-159.34q32.12-74.44 87.17-129.5 55.06-55.05 129.5-87.17 74.43-32.12 159.34-32.12t159.34 32.12q74.44 32.12 129.5 87.17 55.05 55.06 87.17 129.5 32.12 74.43 32.12 159.34t-32.12 159.34q-32.12 74.44-87.17 129.5-55.06 55.05-129.5 87.17Q564.91-71.87 480-71.87Zm0-91q133.04 0 225.09-92.04 92.04-92.05 92.04-225.09 0-133.04-92.04-225.09-92.05-92.04-225.09-92.04-133.04 0-225.09 92.04-92.04 92.05-92.04 225.09 0 133.04 92.04 225.09 92.05 92.04 225.09 92.04ZM480-480Z"/></svg>

Before

Width:  |  Height:  |  Size: 692 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M480-280q83 0 141.5-58.5T680-480h-60q0 58-41 99t-99 41q-58 0-99-41t-41-99q0-58 41-99t99-41h2.28L434-570l42 43 120-120-120-120-43 43 44 44q-82 2-139.5 60T280-480q0 83 58.5 141.5T480-280Zm0 208.13q-84.91 0-159.34-32.12-74.44-32.12-129.5-87.17-55.05-55.06-87.17-129.5Q71.87-395.09 71.87-480t32.12-159.34q32.12-74.44 87.17-129.5 55.06-55.05 129.5-87.17 74.43-32.12 159.34-32.12t159.34 32.12q74.44 32.12 129.5 87.17 55.05 55.06 87.17 129.5 32.12 74.43 32.12 159.34t-32.12 159.34q-32.12 74.44-87.17 129.5-55.06 55.05-129.5 87.17Q564.91-71.87 480-71.87Zm0-91q133.04 0 225.09-92.04 92.04-92.05 92.04-225.09 0-133.04-92.04-225.09-92.05-92.04-225.09-92.04-133.04 0-225.09 92.04-92.04 92.05-92.04 225.09 0 133.04 92.04 225.09 92.05 92.04 225.09 92.04ZM480-480Z"/></svg>

Before

Width:  |  Height:  |  Size: 832 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M479.95-271.87q19.92 0 33.45-13.48 13.53-13.48 13.53-33.4 0-19.92-13.47-33.58-13.48-13.65-33.41-13.65-19.92 0-33.45 13.65-13.53 13.66-13.53 33.58 0 19.92 13.47 33.4 13.48 13.48 33.41 13.48ZM434.5-439.52h91v-245.5h-91v245.5ZM480-71.87q-84.91 0-159.34-32.12-74.44-32.12-129.5-87.17-55.05-55.06-87.17-129.5Q71.87-395.09 71.87-480t32.12-159.34q32.12-74.44 87.17-129.5 55.06-55.05 129.5-87.17 74.43-32.12 159.34-32.12t159.34 32.12q74.44 32.12 129.5 87.17 55.05 55.06 87.17 129.5 32.12 74.43 32.12 159.34t-32.12 159.34q-32.12 74.44-87.17 129.5-55.06 55.05-129.5 87.17Q564.91-71.87 480-71.87Zm0-91q133.04 0 225.09-92.04 92.04-92.05 92.04-225.09 0-133.04-92.04-225.09-92.05-92.04-225.09-92.04-133.04 0-225.09 92.04-92.04 92.05-92.04 225.09 0 133.04 92.04 225.09 92.05 92.04 225.09 92.04ZM480-480Z"/></svg>

Before

Width:  |  Height:  |  Size: 871 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M360-320h80v-320h-80v320Zm160 0h80v-320h-80v320ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>

Before

Width:  |  Height:  |  Size: 416 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="m424-296 282-282-56-56-226 226-114-114-56 56 170 170Zm56 216q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>

Before

Width:  |  Height:  |  Size: 421 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M480-280q83 0 141.5-58.5T680-480q0-83-58.5-141.5T480-680q-83 0-141.5 58.5T280-480q0 83 58.5 141.5T480-280Zm0 208.13q-84.91 0-159.34-32.12-74.44-32.12-129.5-87.17-55.05-55.06-87.17-129.5Q71.87-395.09 71.87-480t32.12-159.34q32.12-74.44 87.17-129.5 55.06-55.05 129.5-87.17 74.43-32.12 159.34-32.12t159.34 32.12q74.44 32.12 129.5 87.17 55.05 55.06 87.17 129.5 32.12 74.43 32.12 159.34t-32.12 159.34q-32.12 74.44-87.17 129.5-55.06 55.05-129.5 87.17Q564.91-71.87 480-71.87Zm0-91q133.04 0 225.09-92.04 92.04-92.05 92.04-225.09 0-133.04-92.04-225.09-92.05-92.04-225.09-92.04-133.04 0-225.09 92.04-92.04 92.05-92.04 225.09 0 133.04 92.04 225.09 92.05 92.04 225.09 92.04ZM480-480Z"/></svg>

Before

Width:  |  Height:  |  Size: 753 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="m435.33-250 228-228L618-523.33l-183 183L338.33-437l-45 45 142 142ZM226.67-80q-27 0-46.84-19.83Q160-119.67 160-146.67v-666.66q0-27 19.83-46.84Q199.67-880 226.67-880H574l226 226v507.33q0 27-19.83 46.84Q760.33-80 733.33-80H226.67Zm314-542.67v-190.66h-314v666.66h506.66v-476H540.67Zm-314-190.66v190.66-190.66 666.66-666.66Z"/></svg>

Before

Width:  |  Height:  |  Size: 402 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M319.33-246.67h321.34v-66.66H319.33v66.66Zm0-166.66h321.34V-480H319.33v66.67ZM226.67-80q-27 0-46.84-19.83Q160-119.67 160-146.67v-666.66q0-27 19.83-46.84Q199.67-880 226.67-880H574l226 226v507.33q0 27-19.83 46.84Q760.33-80 733.33-80H226.67Zm314-542.67v-190.66h-314v666.66h506.66v-476H540.67Zm-314-190.66v190.66-190.66 666.66-666.66Z"/></svg>

Before

Width:  |  Height:  |  Size: 413 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M320-320h320v-320H320v320ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>

Before

Width:  |  Height:  |  Size: 394 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M360-320h80v-320h-80v320Zm160 0h80v-320h-80v320ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>

Before

Width:  |  Height:  |  Size: 416 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M240-400h80q0-59 43-99.5T466-540q36 0 67 16.5t51 43.5h-64v80h200v-200h-80v62q-32-38-76.5-60T466-620q-95 0-160.5 64T240-400ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>

Before

Width:  |  Height:  |  Size: 491 B

View File

@ -1,35 +0,0 @@
{% load markdown %}
<div class="comment">
<div class="comment-header">
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 -960 960 960" width="16px">
<path
d="M480-400q-17 0-28.5-11.5T440-440q0-17 11.5-28.5T480-480q17 0 28.5 11.5T520-440q0 17-11.5 28.5T480-400Zm-160 0q-17 0-28.5-11.5T280-440q0-17 11.5-28.5T320-480q17 0 28.5 11.5T360-440q0 17-11.5 28.5T320-400Zm320 0q-17 0-28.5-11.5T600-440q0-17 11.5-28.5T640-480q17 0 28.5 11.5T680-440q0 17-11.5 28.5T640-400ZM480-240q-17 0-28.5-11.5T440-280q0-17 11.5-28.5T480-320q17 0 28.5 11.5T520-280q0 17-11.5 28.5T480-240Zm-160 0q-17 0-28.5-11.5T280-280q0-17 11.5-28.5T320-320q17 0 28.5 11.5T360-280q0 17-11.5 28.5T320-240Zm320 0q-17 0-28.5-11.5T600-280q0-17 11.5-28.5T640-320q17 0 28.5 11.5T680-280q0 17-11.5 28.5T640-240ZM200-80q-33 0-56.5-23.5T120-160v-560q0-33 23.5-56.5T200-800h40v-80h80v80h320v-80h80v80h40q33 0 56.5 23.5T840-720v560q0 33-23.5 56.5T760-80H200Zm0-80h560v-400H200v400Z" />
</svg>
<span>{{ note.created }}</span>
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 -960 960 960" width="16px" style="">
<path
d="M480-480q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47ZM160-160v-112q0-34 17.5-62.5T224-378q62-31 126-46.5T480-440q66 0 130 15.5T736-378q29 15 46.5 43.5T800-272v112H160Z" />
</svg>
<span style="">{{ note.usercreated }}</span>
<span style="display: inline; margin-right: auto">&nbsp;</span>
</div>
<div class="comment-body">{{ note.note | markdown | safe }}</div>
<div class="comment-footer">
<span>edited by: </span>
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 -960 960 960" width="16px">
<path
d="M480-400q-17 0-28.5-11.5T440-440q0-17 11.5-28.5T480-480q17 0 28.5 11.5T520-440q0 17-11.5 28.5T480-400Zm-160 0q-17 0-28.5-11.5T280-440q0-17 11.5-28.5T320-480q17 0 28.5 11.5T360-440q0 17-11.5 28.5T320-400Zm320 0q-17 0-28.5-11.5T600-440q0-17 11.5-28.5T640-480q17 0 28.5 11.5T680-440q0 17-11.5 28.5T640-400ZM480-240q-17 0-28.5-11.5T440-280q0-17 11.5-28.5T480-320q17 0 28.5 11.5T520-280q0 17-11.5 28.5T480-240Zm-160 0q-17 0-28.5-11.5T280-280q0-17 11.5-28.5T320-320q17 0 28.5 11.5T360-280q0 17-11.5 28.5T320-240Zm320 0q-17 0-28.5-11.5T600-280q0-17 11.5-28.5T640-320q17 0 28.5 11.5T680-280q0 17-11.5 28.5T640-240ZM200-80q-33 0-56.5-23.5T120-160v-560q0-33 23.5-56.5T200-800h40v-80h80v80h320v-80h80v80h40q33 0 56.5 23.5T840-720v560q0 33-23.5 56.5T760-80H200Zm0-80h560v-400H200v400Z" />
</svg>
<span>date </span>
<svg xmlns="http://www.w3.org/2000/svg" height="16px" viewBox="0 -960 960 960" width="16px" style="">
<path
d="M480-480q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47ZM160-160v-112q0-34 17.5-62.5T224-378q62-31 126-46.5T480-440q66 0 130 15.5T736-378q29 15 46.5 43.5T800-272v112H160Z" />
</svg>
<span>username</span>
<span style="display: inline; margin-right: auto">&nbsp;</span>
</div>
</div>

View File

@ -1,193 +0,0 @@
import django
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnonymousUser, Permission
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import reverse
from django.test import TestCase, Client
import pytest
import unittest
import requests
from access.models.tenant import Tenant as Organization
from access.models.team import Team
from access.models.team_user import TeamUsers
from centurion.tests.abstract.model_permissions import ModelPermissions
from core.models.manufacturer import Manufacturer
User = django.contrib.auth.get_user_model()
class ManufacturerPermissions(TestCase, ModelPermissions):
model = Manufacturer
app_namespace = 'Settings'
url_name_view = '_manufacturer_view'
url_name_add = '_manufacturer_add'
url_name_change = '_manufacturer_change'
url_name_delete = '_manufacturer_delete'
url_delete_response = reverse('Settings:_manufacturers')
@classmethod
def setUpTestData(self):
"""Setup Test
1. Create an organization for user and item
. create an organization that is different to item
2. Create a manufacturer
3. create teams with each permission: view, add, change, delete
4. create a user per team
"""
organization = Organization.objects.create(name='test_org')
self.organization = organization
different_organization = Organization.objects.create(name='test_different_organization')
self.item = self.model.objects.create(
organization=organization,
name = 'manufacturerone'
)
self.url_view_kwargs = {'pk': self.item.id}
# self.url_add_kwargs = {'pk': self.item.id}
self.add_data = {'manufacturer': 'manufacturer', 'organization': self.organization.id}
self.url_change_kwargs = {'pk': self.item.id}
self.change_data = {'manufacturer': 'manufacturer', 'organization': self.organization.id}
self.url_delete_kwargs = {'pk': self.item.id}
self.delete_data = {'manufacturer': 'manufacturer', 'organization': self.organization.id}
view_permissions = Permission.objects.get(
codename = 'view_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
view_team = Team.objects.create(
team_name = 'view_team',
organization = organization,
)
view_team.permissions.set([view_permissions])
add_permissions = Permission.objects.get(
codename = 'add_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
add_team = Team.objects.create(
team_name = 'add_team',
organization = organization,
)
add_team.permissions.set([add_permissions])
change_permissions = Permission.objects.get(
codename = 'change_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
change_team = Team.objects.create(
team_name = 'change_team',
organization = organization,
)
change_team.permissions.set([change_permissions])
delete_permissions = Permission.objects.get(
codename = 'delete_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
delete_team = Team.objects.create(
team_name = 'delete_team',
organization = organization,
)
delete_team.permissions.set([delete_permissions])
self.no_permissions_user = User.objects.create_user(username="test_no_permissions", password="password")
self.view_user = User.objects.create_user(username="test_user_view", password="password")
teamuser = TeamUsers.objects.create(
team = view_team,
user = self.view_user
)
self.add_user = User.objects.create_user(username="test_user_add", password="password")
teamuser = TeamUsers.objects.create(
team = add_team,
user = self.add_user
)
self.change_user = User.objects.create_user(username="test_user_change", password="password")
teamuser = TeamUsers.objects.create(
team = change_team,
user = self.change_user
)
self.delete_user = User.objects.create_user(username="test_user_delete", password="password")
teamuser = TeamUsers.objects.create(
team = delete_team,
user = self.delete_user
)
self.different_organization_user = User.objects.create_user(username="test_different_organization_user", password="password")
different_organization_team = Team.objects.create(
team_name = 'different_organization_team',
organization = different_organization,
)
different_organization_team.permissions.set([
view_permissions,
add_permissions,
change_permissions,
delete_permissions,
])
TeamUsers.objects.create(
team = different_organization_team,
user = self.different_organization_user
)

View File

@ -1,29 +0,0 @@
import pytest
import unittest
import requests
from django.test import TestCase
from centurion.tests.abstract.models import PrimaryModel
class ManufacturerViews(
TestCase,
PrimaryModel
):
add_module = 'settings.views.manufacturer'
add_view = 'Add'
change_module = add_module
change_view = 'View'
delete_module = add_module
delete_view = 'Delete'
display_module = add_module
display_view = 'View'
index_module = add_module
index_view = 'Index'

View File

@ -1,110 +0,0 @@
import django
import pytest
import unittest
import requests
from django.contrib.auth.models import AnonymousUser, Permission
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import reverse
from django.test import TestCase
from celery import states
from access.models.tenant import Tenant as Organization
from access.models.team import Team
from access.models.team_user import TeamUsers
from centurion.tests.abstract.model_permissions import ModelPermissionsView
from django_celery_results.models import TaskResult
User = django.contrib.auth.get_user_model()
class TaskResultPermissions(TestCase, ModelPermissionsView):
model = TaskResult
app_label = 'django_celery_results'
app_namespace = 'Settings'
url_name_view = '_task_result_view'
@classmethod
def setUpTestData(self):
"""Setup Test
1. Create an organization for user and item
. create an organization that is different to item
2. Create a device
3. create teams with each permission: view, add, change, delete
4. create a user per team
"""
organization = Organization.objects.create(name='test_org')
self.organization = organization
different_organization = Organization.objects.create(name='test_different_organization')
self.item = self.model.objects.create(
task_id='organization',
periodic_task_name='',
task_name = 'deviceone',
status=states.SUCCESS,
content_type='application/json',
content_encoding='utf-8',
)
self.url_view_kwargs = {'pk': self.item.id}
view_permissions = Permission.objects.get(
codename = 'view_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
view_team = Team.objects.create(
team_name = 'view_team',
organization = organization,
)
view_team.permissions.set([view_permissions])
self.no_permissions_user = User.objects.create_user(username="test_no_permissions", password="password")
self.view_user = User.objects.create_user(username="test_user_view", password="password")
teamuser = TeamUsers.objects.create(
team = view_team,
user = self.view_user
)
self.different_organization_user = User.objects.create_user(username="test_different_organization_user", password="password")
different_organization_team = Team.objects.create(
team_name = 'different_organization_team',
organization = different_organization,
)
different_organization_team.permissions.set([
view_permissions,
])
TeamUsers.objects.create(
team = different_organization_team,
user = self.different_organization_user
)
def test_model_view_different_organizaiton_denied(self): # Test is N/A
pass

View File

@ -1,30 +0,0 @@
import pytest
import unittest
import requests
from django.test import TestCase
from centurion.tests.abstract.models import ModelDisplay, ModelIndex
class TaskResultsViews(
TestCase,
ModelDisplay,
ModelIndex
):
# add_module = 'core.views.celery_log'
# add_view = 'GroupAdd'
# change_module = add_module
# change_view = 'GroupView'
# delete_module = add_module
# delete_view = 'GroupDelete'
display_module = 'core.views.celery_log'
display_view = 'View'
index_module = display_module
index_view = 'Index'

View File

@ -1,193 +0,0 @@
import django
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnonymousUser, Permission
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import reverse
from django.test import TestCase, Client
import pytest
import unittest
import requests
from access.models.tenant import Tenant as Organization
from access.models.team import Team
from access.models.team_user import TeamUsers
from centurion.tests.abstract.model_permissions import ModelPermissions
from core.models.ticket.ticket_category import TicketCategory
User = django.contrib.auth.get_user_model()
class TicketCategoryPermissions(TestCase, ModelPermissions):
model = TicketCategory
app_namespace = 'Settings'
url_name_view = '_ticket_category_view'
url_name_add = '_ticket_category_add'
url_name_change = '_ticket_category_change'
url_name_delete = '_ticket_category_delete'
url_delete_response = reverse('Settings:_ticket_categories')
@classmethod
def setUpTestData(self):
"""Setup Test
1. Create an organization for user and item
. create an organization that is different to item
2. Create a category
3. create teams with each permission: view, add, change, delete
4. create a user per team
"""
organization = Organization.objects.create(name='test_org')
self.organization = organization
different_organization = Organization.objects.create(name='test_different_organization')
self.item = self.model.objects.create(
organization=organization,
name = 'manufacturerone'
)
self.url_view_kwargs = {'pk': self.item.id}
# self.url_add_kwargs = {'pk': self.item.id}
self.add_data = {'name': 'manufacturer', 'organization': self.organization.id}
self.url_change_kwargs = {'pk': self.item.id}
self.change_data = {'name': 'manufacturer', 'organization': self.organization.id}
self.url_delete_kwargs = {'pk': self.item.id}
self.delete_data = {'name': 'manufacturer'}
view_permissions = Permission.objects.get(
codename = 'view_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
view_team = Team.objects.create(
team_name = 'view_team',
organization = organization,
)
view_team.permissions.set([view_permissions])
add_permissions = Permission.objects.get(
codename = 'add_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
add_team = Team.objects.create(
team_name = 'add_team',
organization = organization,
)
add_team.permissions.set([add_permissions])
change_permissions = Permission.objects.get(
codename = 'change_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
change_team = Team.objects.create(
team_name = 'change_team',
organization = organization,
)
change_team.permissions.set([change_permissions])
delete_permissions = Permission.objects.get(
codename = 'delete_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
delete_team = Team.objects.create(
team_name = 'delete_team',
organization = organization,
)
delete_team.permissions.set([delete_permissions])
self.no_permissions_user = User.objects.create_user(username="test_no_permissions", password="password")
self.view_user = User.objects.create_user(username="test_user_view", password="password")
teamuser = TeamUsers.objects.create(
team = view_team,
user = self.view_user
)
self.add_user = User.objects.create_user(username="test_user_add", password="password")
teamuser = TeamUsers.objects.create(
team = add_team,
user = self.add_user
)
self.change_user = User.objects.create_user(username="test_user_change", password="password")
teamuser = TeamUsers.objects.create(
team = change_team,
user = self.change_user
)
self.delete_user = User.objects.create_user(username="test_user_delete", password="password")
teamuser = TeamUsers.objects.create(
team = delete_team,
user = self.delete_user
)
self.different_organization_user = User.objects.create_user(username="test_different_organization_user", password="password")
different_organization_team = Team.objects.create(
team_name = 'different_organization_team',
organization = different_organization,
)
different_organization_team.permissions.set([
view_permissions,
add_permissions,
change_permissions,
delete_permissions,
])
TeamUsers.objects.create(
team = different_organization_team,
user = self.different_organization_user
)

View File

@ -1,33 +0,0 @@
import pytest
import unittest
import requests
from django.test import TestCase
from centurion.tests.abstract.models import PrimaryModel, ModelAdd, ModelChange, ModelDelete
# class TicketCommentViews(
# TestCase,
# PrimaryModel
# ):
class TicketCategoryViews(
TestCase,
PrimaryModel
):
add_module = 'core.views.ticket_categories'
add_view = 'Add'
change_module = add_module
change_view = 'Change'
delete_module = add_module
delete_view = 'Delete'
display_module = add_module
display_view = 'View'
index_module = add_module
index_view = 'Index'

View File

@ -1,25 +0,0 @@
import pytest
import unittest
import requests
from django.test import TestCase
from centurion.tests.abstract.models import ModelDisplay, ModelIndex
from core.models.ticket.ticket_comment import TicketComment
class TicketCommentCommon(
TestCase
):
model = TicketComment
def test_ticket_field_type_opened_by(self):
"""Replies to comments only to occur on primary comment
If a comment has a 'parent_id' set, ensure the comment can't be replied to
"""
pass

View File

@ -1,339 +0,0 @@
import django
import re
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnonymousUser, Permission
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import reverse
from django.test import TestCase, Client
import pytest
import unittest
import requests
from access.models.tenant import Tenant as Organization
from access.models.team import Team
from access.models.team_user import TeamUsers
from centurion.tests.abstract.model_permissions import ModelPermissions, ModelPermissionsAdd, ModelPermissionsChange
from project_management.models.projects import Project
from core.models.ticket.ticket import Ticket, RelatedTickets
from core.models.ticket.ticket_comment import TicketComment
User = django.contrib.auth.get_user_model()
class TicketCommentPermissions(
# ModelPermissions,
ModelPermissionsAdd,
ModelPermissionsChange,
):
ticket_type:str = None
ticket_type_enum: int = None
model = TicketComment
@classmethod
def setUpTestData(self):
"""Setup Test
1. Create an organization for user and item
. create an organization that is different to item
2. Create a manufacturer
3. create teams with each permission: view, add, change, delete
4. create a user per team
"""
organization = Organization.objects.create(name='test_org')
self.organization = organization
different_organization = Organization.objects.create(name='test_different_organization')
add_permissions = Permission.objects.get(
codename = 'add_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
add_ticket_permissions = Permission.objects.get(
codename = 'add_' + Ticket._meta.model_name + '_' + self.ticket_type,
content_type = ContentType.objects.get(
app_label = Ticket._meta.app_label,
model = Ticket._meta.model_name,
)
)
add_team = Team.objects.create(
team_name = 'add_team',
organization = organization,
)
add_team.permissions.set([add_ticket_permissions, add_permissions])
self.add_user = User.objects.create_user(username="test_user_add", password="password")
teamuser = TeamUsers.objects.create(
team = add_team,
user = self.add_user
)
self.ticket = Ticket.objects.create(
organization=organization,
title = 'A second ' + self.ticket_type + ' ticket',
description = 'the ticket body of item two',
ticket_type = int(Ticket.TicketType.REQUEST.value),
opened_by = self.add_user,
status = int(Ticket.TicketStatus.All.NEW.value)
)
self.item_add_user = self.model.objects.create(
organization=organization,
body = 'A ' + self.ticket_type + ' ticket comment',
ticket = self.ticket,
comment_type = int(TicketComment.CommentType.COMMENT),
user = self.add_user,
# status = int(Ticket.TicketStatus.All.NEW.value)
)
self.project = Project.objects.create(
name = 'ticket permissions project name',
organization = organization
)
self.url_add_kwargs = {'ticket_type': self.ticket_type, 'ticket_id': self.ticket.id}
self.add_data = {
'body': 'an add ticket',
'comment_type': int(TicketComment.CommentType.COMMENT.value),
'ticket': self.ticket.id,
'organization': self.organization.id,
'user': self.add_user.id,
}
view_permissions = Permission.objects.get(
codename = 'view_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
view_team = Team.objects.create(
team_name = 'view_team',
organization = organization,
)
view_team.permissions.set([view_permissions])
change_permissions = Permission.objects.get(
codename = 'change_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
change_team = Team.objects.create(
team_name = 'change_team',
organization = organization,
)
change_team.permissions.set([change_permissions])
self.change_team = change_team
delete_permissions = Permission.objects.get(
codename = 'delete_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
delete_team = Team.objects.create(
team_name = 'delete_team',
organization = organization,
)
delete_team.permissions.set([delete_permissions])
self.no_permissions_user = User.objects.create_user(username="test_no_permissions", password="password")
self.view_user = User.objects.create_user(username="test_user_view", password="password")
teamuser = TeamUsers.objects.create(
team = view_team,
user = self.view_user
)
self.change_user = User.objects.create_user(username="test_user_change", password="password")
teamuser = TeamUsers.objects.create(
team = change_team,
user = self.change_user
)
self.item = self.model.objects.create(
organization=organization,
body = 'A ' + self.ticket_type + ' ticket comment',
ticket = self.ticket,
comment_type = int(TicketComment.CommentType.COMMENT),
user = self.change_user,
# status = int(Ticket.TicketStatus.All.NEW.value)
)
self.url_view_kwargs = {'ticket_type': self.ticket_type, 'pk': self.item.id}
self.url_change_kwargs = {'ticket_type': self.ticket_type, 'ticket_id': self.ticket.id, 'pk': self.item.id}
self.change_data = {'body': 'a change to ticket commennt'}
self.url_delete_kwargs = {'ticket_type': self.ticket_type, 'ticket_id': self.ticket.id, 'pk': self.item.id}
self.delete_data = {'body': 'a delete to ticket'}
self.delete_user = User.objects.create_user(username="test_user_delete", password="password")
teamuser = TeamUsers.objects.create(
team = delete_team,
user = self.delete_user
)
self.different_organization_user = User.objects.create_user(username="test_different_organization_user", password="password")
different_organization_team = Team.objects.create(
team_name = 'different_organization_team',
organization = different_organization,
)
different_organization_team.permissions.set([
view_permissions,
add_permissions,
change_permissions,
delete_permissions,
])
TeamUsers.objects.create(
team = different_organization_team,
user = self.different_organization_user
)
def test_model_change_own_comment_has_permission(self):
""" Check correct permission for change
Make change with user who has add permission on own comment
"""
client = Client()
kwargs = self.url_change_kwargs.copy()
kwargs['pk'] = self.item_add_user.id
url = reverse(self.app_namespace + ':' + self.url_name_change, kwargs=kwargs)
client.force_login(self.add_user)
response = client.post(url, data=self.change_data)
assert response.status_code == 200
class ChangeTicketCommentPermissions(TicketCommentPermissions, TestCase):
ticket_type = 'change'
ticket_type_enum: int = int(Ticket.TicketType.CHANGE.value)
app_namespace = 'ITIM'
url_name_view = '_ticket_comment_change_view'
url_name_add = '_ticket_comment_change_add'
url_name_change = '_ticket_comment_change_change'
url_name_delete = '_ticket_comment_change_delete'
url_delete_response = reverse('ITIM:Changes')
class IncidentTicketCommentPermissions(TicketCommentPermissions, TestCase):
ticket_type = 'incident'
ticket_type_enum: int = int(Ticket.TicketType.INCIDENT.value)
app_namespace = 'ITIM'
url_name_view = '_ticket_comment_incident_view'
url_name_add = '_ticket_comment_incident_add'
url_name_change = '_ticket_comment_incident_change'
url_name_delete = '_ticket_comment_incident_delete'
url_delete_response = reverse('ITIM:Incidents')
class ProblemTicketCommentPermissions(TicketCommentPermissions, TestCase):
ticket_type = 'problem'
ticket_type_enum: int = int(Ticket.TicketType.PROBLEM.value)
app_namespace = 'ITIM'
url_name_view = '_ticket_comment_problem_view'
url_name_add = '_ticket_comment_problem_add'
url_name_change = '_ticket_comment_problem_change'
url_name_delete = '_ticket_comment_problem_delete'
url_delete_response = reverse('ITIM:Problems')
class RequestTicketCommentPermissions(TicketCommentPermissions, TestCase):
ticket_type = 'request'
ticket_type_enum: int = int(Ticket.TicketType.REQUEST.value)
app_namespace = 'Assistance'
url_name_view = '_ticket_comment_request_view'
url_name_add = '_ticket_comment_request_add'
url_name_change = '_ticket_comment_request_change'
url_name_delete = '_ticket_comment_request_delete'
url_delete_response = reverse('Assistance:Requests')

View File

@ -1,34 +0,0 @@
import pytest
import unittest
import requests
from django.test import TestCase
from centurion.tests.abstract.models import PrimaryModel, ModelAdd, ModelChange, ModelDelete
# class TicketCommentViews(
# TestCase,
# PrimaryModel
# ):
class TicketCommentViews(
TestCase,
ModelAdd,
ModelChange,
):
add_module = 'core.views.ticket'
add_view = 'Add'
change_module = add_module
change_view = 'Change'
delete_module = add_module
delete_view = 'Delete'
# display_module = add_module
# display_view = 'View'
# index_module = add_module
# index_view = 'Index'

View File

@ -1,192 +0,0 @@
import django
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnonymousUser, Permission
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import reverse
from django.test import TestCase, Client
import pytest
import unittest
import requests
from access.models.tenant import Tenant as Organization
from access.models.team import Team
from access.models.team_user import TeamUsers
from centurion.tests.abstract.model_permissions import ModelPermissions
from core.models.ticket.ticket_comment_category import TicketCommentCategory
User = django.contrib.auth.get_user_model()
class TicketCommentCategoryPermissions(TestCase, ModelPermissions):
model = TicketCommentCategory
app_namespace = 'Settings'
url_name_view = '_ticket_comment_category_view'
url_name_add = '_ticket_comment_category_add'
url_name_change = '_ticket_comment_category_change'
url_name_delete = '_ticket_comment_category_delete'
url_delete_response = reverse('Settings:_ticket_comment_categories')
@classmethod
def setUpTestData(self):
"""Setup Test
1. Create an organization for user and item
. create an organization that is different to item
2. Create a category
3. create teams with each permission: view, add, change, delete
4. create a user per team
"""
organization = Organization.objects.create(name='test_org')
self.organization = organization
different_organization = Organization.objects.create(name='test_different_organization')
self.item = self.model.objects.create(
organization=organization,
name = 'manufacturerone'
)
self.url_view_kwargs = {'pk': self.item.id}
# self.url_add_kwargs = {'pk': self.item.id}
self.add_data = {'name': 'manufacturer', 'organization': self.organization.id}
self.url_change_kwargs = {'pk': self.item.id}
self.change_data = {'name': 'manufacturer', 'organization': self.organization.id}
self.url_delete_kwargs = {'pk': self.item.id}
self.delete_data = {'name': 'manufacturer'}
view_permissions = Permission.objects.get(
codename = 'view_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
view_team = Team.objects.create(
team_name = 'view_team',
organization = organization,
)
view_team.permissions.set([view_permissions])
add_permissions = Permission.objects.get(
codename = 'add_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
add_team = Team.objects.create(
team_name = 'add_team',
organization = organization,
)
add_team.permissions.set([add_permissions])
change_permissions = Permission.objects.get(
codename = 'change_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
change_team = Team.objects.create(
team_name = 'change_team',
organization = organization,
)
change_team.permissions.set([change_permissions])
delete_permissions = Permission.objects.get(
codename = 'delete_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
delete_team = Team.objects.create(
team_name = 'delete_team',
organization = organization,
)
delete_team.permissions.set([delete_permissions])
self.no_permissions_user = User.objects.create_user(username="test_no_permissions", password="password")
self.view_user = User.objects.create_user(username="test_user_view", password="password")
teamuser = TeamUsers.objects.create(
team = view_team,
user = self.view_user
)
self.add_user = User.objects.create_user(username="test_user_add", password="password")
teamuser = TeamUsers.objects.create(
team = add_team,
user = self.add_user
)
self.change_user = User.objects.create_user(username="test_user_change", password="password")
teamuser = TeamUsers.objects.create(
team = change_team,
user = self.change_user
)
self.delete_user = User.objects.create_user(username="test_user_delete", password="password")
teamuser = TeamUsers.objects.create(
team = delete_team,
user = self.delete_user
)
self.different_organization_user = User.objects.create_user(username="test_different_organization_user", password="password")
different_organization_team = Team.objects.create(
team_name = 'different_organization_team',
organization = different_organization,
)
different_organization_team.permissions.set([
view_permissions,
add_permissions,
change_permissions,
delete_permissions,
])
TeamUsers.objects.create(
team = different_organization_team,
user = self.different_organization_user
)

View File

@ -1,33 +0,0 @@
import pytest
import unittest
import requests
from django.test import TestCase
from centurion.tests.abstract.models import PrimaryModel, ModelAdd, ModelChange, ModelDelete
# class TicketCommentViews(
# TestCase,
# PrimaryModel
# ):
class TicketCommentCategoryViews(
TestCase,
PrimaryModel
):
add_module = 'core.views.ticket_comment_category'
add_view = 'Add'
change_module = add_module
change_view = 'Change'
delete_module = add_module
delete_view = 'Delete'
display_module = add_module
display_view = 'View'
index_module = add_module
index_view = 'Index'

View File

@ -1,69 +0,0 @@
import pytest
import unittest
import requests
from django.test import TestCase
from centurion.tests.abstract.models import ModelDisplay, ModelIndex
class TicketCommon(
TestCase
):
@pytest.mark.skip(reason='to write')
def test_ticket_field_type_opened_by(self):
"""Ensure field is of a certain type
opened_by_field must be of type int
"""
pass
@pytest.mark.skip(reason='to write')
def test_ticket_field_value_not_null_opened_by(self):
"""Ensure field is not null
opened_by_field must be set and not null
"""
pass
@pytest.mark.skip(reason='to write')
def test_ticket_field_value_auto_set_opened_by(self):
"""Ensure field is auto set within code
opened_by_field must be set by code with non-tech user not being able to change
"""
pass
@pytest.mark.skip(reason='to write')
def test_ticket_field_value_tech_set_opened_by(self):
"""Ensure field can be set by a technician
opened_by_field can be set by a technician
"""
pass
@pytest.mark.skip(reason='to write')
def test_ticket_type_fields(self):
"""Placeholder test
following tests to be written:
- only tech can change tech fields (same org)
- non-tech cant see tech fields (same org) during creation
- non-tech cant change tech fields (same org)
- only tech can change tech fields (different org)
- non-tech cant see tech fields (different org) during creation
- non-tech cant change tech fields (different org)
- itsm ticket has the itsm related fields
- non-itsm ticket does not have any itsm related fields
"""
pass

View File

@ -1,29 +0,0 @@
import pytest
import unittest
import requests
from django.test import TestCase
from centurion.tests.abstract.models import PrimaryModel
class TicketViews(
TestCase,
PrimaryModel
):
add_module = 'core.views.ticket'
add_view = 'Add'
change_module = add_module
change_view = 'Change'
delete_module = add_module
delete_view = 'Delete'
display_module = add_module
display_view = 'View'
index_module = add_module
index_view = 'Index'

View File

@ -1,446 +0,0 @@
import django
import re
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnonymousUser, Permission
from django.contrib.contenttypes.models import ContentType
from django.shortcuts import reverse
from django.test import TestCase, Client
import pytest
import unittest
import requests
from access.models.tenant import Tenant as Organization
from access.models.team import Team
from access.models.team_user import TeamUsers
from centurion.tests.abstract.model_permissions import ModelPermissions, ModelPermissionsAdd
from project_management.models.projects import Project
from core.models.ticket.ticket import Ticket
from core.models.ticket.ticket_linked_items import TicketLinkedItem
# from core.tests.unit.ticket.ticket_permission.field_based_permissions import ITSMTicketFieldBasedPermissions, ProjectTicketFieldBasedPermissions
from itam.models.device import Device
from settings.models.user_settings import UserSettings
User = django.contrib.auth.get_user_model()
class TicketLinkedItemPermissions(
ModelPermissionsAdd,
):
ticket_type:str = None
ticket_type_enum: int = None
model = TicketLinkedItem
app_namespace = ''
# url_name_view = '_ticket_request_view'
# url_name_add = '_ticket_request_add'
# url_name_change = '_ticket_request_change'
# url_name_delete = '_ticket_request_delete'
# url_delete_response = reverse('Assistance:Requests')
@classmethod
def setUpTestData(self):
"""Setup Test
1. Create an organization for user and item
. create an organization that is different to item
2. Create a manufacturer
3. create teams with each permission: view, add, change, delete
4. create a user per team
"""
organization = Organization.objects.create(name='test_org')
self.organization = organization
different_organization = Organization.objects.create(name='test_different_organization')
add_permissions = Permission.objects.get(
codename = 'add_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
add_team = Team.objects.create(
team_name = 'add_team',
organization = organization,
)
add_team.permissions.set([add_permissions])
self.add_user = User.objects.create_user(username="test_user_add", password="password")
teamuser = TeamUsers.objects.create(
team = add_team,
user = self.add_user
)
user_settings = UserSettings.objects.get(user = self.add_user)
user_settings.default_organization = self.organization
user_settings.save()
self.ticket = Ticket.objects.create(
organization=organization,
title = 'A ' + self.ticket_type + ' ticket',
description = 'the ticket body',
ticket_type = self.ticket_type_enum,
opened_by = self.add_user,
status = int(Ticket.TicketStatus.All.NEW.value)
)
self.second_ticket = Ticket.objects.create(
organization=organization,
title = 'A second ' + self.ticket_type + ' ticket',
description = 'the ticket body of item two',
ticket_type = self.ticket_type_enum,
opened_by = self.add_user,
status = int(Ticket.TicketStatus.All.NEW.value)
)
self.device = Device.objects.create(
name = 'device-' + self.ticket_type,
organization=organization,
)
# self.project = Project.objects.create(
# name = 'ticket permissions project name',
# organization = organization
# )
# self.project_two = Project.objects.create(
# name = 'ticket permissions project name two',
# organization = organization
# )
# self.url_view_kwargs = {'ticket_type': self.ticket_type, 'pk': self.item.id}
self.url_add_kwargs = {'ticket_type': self.ticket_type, 'ticket_id': self.ticket.id}
self.add_data = {
'ticket': self.ticket.id,
'item': self.device.id,
'organization': self.organization.id,
}
# self.url_change_kwargs = {'ticket_type': self.ticket_type, 'pk': self.item.id}
# self.change_data = {'title': 'an change to ticket'}
# self.url_delete_kwargs = {'ticket_type': self.ticket_type, 'pk': self.item.id}
# self.delete_data = {'title': 'a delete to ticket'}
view_permissions = Permission.objects.get(
codename = 'view_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
view_team = Team.objects.create(
team_name = 'view_team',
organization = organization,
)
view_team.permissions.set([view_permissions])
change_permissions = Permission.objects.get(
codename = 'change_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
change_team = Team.objects.create(
team_name = 'change_team',
organization = organization,
)
change_team.permissions.set([change_permissions])
self.change_team = change_team
delete_permissions = Permission.objects.get(
codename = 'delete_' + self.model._meta.model_name,
content_type = ContentType.objects.get(
app_label = self.model._meta.app_label,
model = self.model._meta.model_name,
)
)
delete_team = Team.objects.create(
team_name = 'delete_team',
organization = organization,
)
delete_team.permissions.set([delete_permissions])
self.no_permissions_user = User.objects.create_user(username="test_no_permissions", password="password")
self.view_user = User.objects.create_user(username="test_user_view", password="password")
teamuser = TeamUsers.objects.create(
team = view_team,
user = self.view_user
)
self.change_user = User.objects.create_user(username="test_user_change", password="password")
teamuser = TeamUsers.objects.create(
team = change_team,
user = self.change_user
)
self.delete_user = User.objects.create_user(username="test_user_delete", password="password")
teamuser = TeamUsers.objects.create(
team = delete_team,
user = self.delete_user
)
self.different_organization_user = User.objects.create_user(username="test_different_organization_user", password="password")
different_organization_team = Team.objects.create(
team_name = 'different_organization_team',
organization = different_organization,
)
different_organization_team.permissions.set([
view_permissions,
add_permissions,
change_permissions,
delete_permissions,
])
TeamUsers.objects.create(
team = different_organization_team,
user = self.different_organization_user
)
# Import user/permissions
# import_permissions = Permission.objects.get(
# codename = 'import_' + self.model._meta.model_name,
# content_type = ContentType.objects.get(
# app_label = self.model._meta.app_label,
# model = self.model._meta.model_name,
# )
# )
# import_team = Team.objects.create(
# team_name = 'import_team',
# organization = organization,
# )
# import_team.permissions.set([change_permissions, import_permissions])
# self.import_user = User.objects.create_user(username="test_user_import", password="password")
# teamuser = TeamUsers.objects.create(
# team = import_team,
# user = self.import_user
# )
# Triage user/permissions
# triage_permissions = Permission.objects.get(
# codename = 'triage_' + self.model._meta.model_name,
# content_type = ContentType.objects.get(
# app_label = self.model._meta.app_label,
# model = self.model._meta.model_name,
# )
# )
# triage_team = Team.objects.create(
# team_name = 'triage_team',
# organization = organization,
# )
# triage_team.permissions.set([change_permissions, triage_permissions])
# self.triage_user = User.objects.create_user(username="test_user_triage", password="password")
# teamuser = TeamUsers.objects.create(
# team = triage_team,
# user = self.triage_user
# )
class ITSMTicketLinkedItemPermissions(
TicketLinkedItemPermissions,
):
pass
class ProjectTicketLinkedItemPermissions(
TicketLinkedItemPermissions,
):
pass
class ChangeTicketLinkedItemPermissions(ITSMTicketLinkedItemPermissions, TestCase):
ticket_type = 'change'
ticket_type_enum: int = int(Ticket.TicketType.CHANGE.value)
app_namespace = ''
# url_name_view = '_ticket_change_view'
url_name_add = '_ticket_linked_item_add'
# url_name_change = '_ticket_change_change'
# url_name_delete = '_ticket_change_delete'
# url_delete_response = reverse('ITIM:Changes')
class IncidentTicketLinkedItemPermissions(ITSMTicketLinkedItemPermissions, TestCase):
ticket_type = 'incident'
ticket_type_enum: int = int(Ticket.TicketType.INCIDENT.value)
# app_namespace = 'ITIM'
# url_name_view = '_ticket_incident_view'
url_name_add = '_ticket_linked_item_add'
# url_name_change = '_ticket_incident_change'
# url_name_delete = '_ticket_incident_delete'
# url_delete_response = reverse('ITIM:Incidents')
class ProblemTicketLinkedItemPermissions(ITSMTicketLinkedItemPermissions, TestCase):
ticket_type = 'problem'
ticket_type_enum: int = int(Ticket.TicketType.PROBLEM.value)
# app_namespace = 'ITIM'
# url_name_view = '_ticket_problem_view'
url_name_add = '_ticket_linked_item_add'
# url_name_change = '_ticket_problem_change'
# url_name_delete = '_ticket_problem_delete'
# url_delete_response = reverse('ITIM:Problems')
class ProjectTaskTicketLinkedItemPermissions(ProjectTicketLinkedItemPermissions, TestCase):
ticket_type = 'project_task'
ticket_type_enum: int = int(Ticket.TicketType.PROJECT_TASK.value)
# app_namespace = 'Project Management'
# url_name_view = '_project_task_view'
url_name_add = '_ticket_linked_item_add'
# url_name_change = '_project_task_change'
# url_name_delete = '_project_task_delete'
# @classmethod
# def setUpTestData(self):
# """Setup Test
# 1. Create an organization for user and item
# . create an organization that is different to item
# 2. Create a manufacturer
# 3. create teams with each permission: view, add, change, delete
# 4. create a user per team
# """
# super().setUpTestData()
# self.item = self.model.objects.create(
# organization = self.organization,
# title = 'Amended ' + self.ticket_type + ' ticket',
# description = 'the ticket body',
# ticket_type = int(Ticket.TicketType.REQUEST.value),
# opened_by = self.add_user,
# status = int(Ticket.TicketStatus.All.NEW.value),
# project = self.project
# )
# self.url_add_kwargs = {'project_id': self.project.id, 'ticket_type': self.ticket_type}
# self.url_change_kwargs = {'project_id': self.project.id, 'ticket_type': self.ticket_type, 'pk': self.item.id}
# self.url_delete_kwargs = {'project_id': self.project.id, 'ticket_type': self.ticket_type, 'pk': self.project.id}
# # self.url_delete_kwargs = {'pk': self.project.id}
# self.url_view_kwargs = {'project_id': self.project.id, 'ticket_type': self.ticket_type, 'pk': self.item.id}
# self.url_delete_response = reverse('Project Management:_project_view', kwargs={'pk': self.project.id})
class RequestTicketLinkedItemPermissions(ITSMTicketLinkedItemPermissions, TestCase):
ticket_type = 'request'
ticket_type_enum: int = int(Ticket.TicketType.REQUEST.value)
# app_namespace = ''
# url_name_view = '_ticket_request_view'
url_name_add = '_ticket_linked_item_add'
# url_name_change = '_ticket_request_change'
# url_name_delete = '_ticket_request_delete'
# url_delete_response = reverse('Assistance:Requests')

View File

@ -1,29 +0,0 @@
import pytest
import unittest
import requests
from django.test import TestCase
from centurion.tests.abstract.models import ModelAdd, PrimaryModel
class TicketLinkedItemViews(
TestCase,
ModelAdd
):
add_module = 'core.views.ticket_linked_item'
add_view = 'Add'
change_module = add_module
change_view = 'Change'
delete_module = add_module
delete_view = 'Delete'
display_module = add_module
display_view = 'View'
index_module = add_module
index_view = 'Index'

View File

@ -1,72 +0,0 @@
from django.views import generic
from access.mixin import OrganizationPermission
from django_celery_results.models import TaskResult
class Index(OrganizationPermission, generic.ListView):
context_object_name = "task_results"
fields = [
"task_id",
'task_name',
'status',
'date_created',
'date_done',
]
model = TaskResult
permission_required = [
'django_celery_results.view_taskresult',
]
template_name = 'celery_log_index.html.j2'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = 'Background Task Results'
return context
def get_success_url(self, **kwargs):
return reverse('Settings:_device_model_view', args=(self.kwargs['pk'],))
class View(OrganizationPermission, generic.UpdateView):
context_object_name = "task_result"
fields = [
"task_id",
'task_name',
'status',
'task_args',
]
model = TaskResult
permission_required = [
'django_celery_results.view_taskresult',
]
template_name = 'celery_log.html.j2'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = f"Task {self.object.task_id}"
return context
def post(self, request, *args, **kwargs):
pass

View File

@ -1,236 +0,0 @@
from django.template import Template, Context
from django.utils.html import escape
from django.views import generic
from access.mixin import OrganizationPermission
from core.exceptions import MissingAttribute
from settings.models.external_link import ExternalLink
from settings.models.user_settings import UserSettings
class View(OrganizationPermission):
""" Abstract class common to all views
## Functions
- `get_dynamic_permissions()` A function to build and return the permissions for the view
!!! Danger
Don't directly use this class within your view as it's already assigned to the views that require it.
"""
template_name:str = 'form.html.j2'
def get_form_kwargs(self) -> dict:
""" Fetch kwargs for form
Returns:
dict: kwargs used in fetching form
"""
kwargs = super().get_form_kwargs()
if self.form_class:
kwargs.update({'user': self.request.user})
return kwargs
class AddView(View, generic.CreateView):
template_name:str = 'form.html.j2'
def get_initial(self):
return {
'organization': UserSettings.objects.get(user = self.request.user).default_organization
}
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = 'New ' + self.model._meta.verbose_name
return context
class ChangeView(View, generic.UpdateView):
template_name:str = 'form.html.j2'
# ToDo: on migrating all views to seperate display and change views, external_links will not be required in `ChangView`
def get_context_data(self, **kwargs):
""" Get template context
For items that have the ability to have external links, this function
adds the external link details to the context.
!!! Danger "Requirement"
This function may be overridden with the caveat that this function is still called.
by the overriding function. i.e. `super().get_context_data(skwargs)`
!!! note
The adding of `external_links` within this view is scheduled to be removed.
Returns:
(dict): Context for the template to use inclusive of 'external_links'
"""
context = super().get_context_data(**kwargs)
external_links_query = None
if 'tab' in self.request.GET:
context['open_tab'] = str(self.request.GET.get("tab")).lower()
else:
context['open_tab'] = None
if self.model._meta.model_name == 'cluster':
external_links_query = ExternalLink.objects.filter(cluster=True)
elif self.model._meta.model_name == 'device':
external_links_query = ExternalLink.objects.filter(devices=True)
elif self.model._meta.model_name == 'software':
external_links_query = ExternalLink.objects.filter(software=True)
if external_links_query:
external_links: list = []
user_context = Context(context)
for external_link in external_links_query:
user_string = Template(external_link)
external_link_context: dict = {
'name': escape(external_link.name),
'link': escape(user_string.render(user_context)),
}
if external_link.colour:
external_link_context.update({'colour': external_link.colour })
external_links += [ external_link_context ]
context['external_links'] = external_links
return context
def get_initial(self):
return {
'organization': UserSettings.objects.get(user = self.request.user).default_organization
}
class DeleteView(OrganizationPermission, generic.DeleteView):
template_name:str = 'form.html.j2'
class DisplayView(OrganizationPermission, generic.DetailView):
""" A View used for displaying arbitrary data """
template_name:str = 'form.html.j2'
# ToDo: on migrating all views to seperate display and change views, external_links will not be required in `ChangView`
def get_context_data(self, **kwargs):
""" Get template context
For items that have the ability to have external links, this function
adds the external link details to the context.
!!! Danger "Requirement"
This function may be overridden with the caveat that this function is still called.
by the overriding function. i.e. `super().get_context_data(skwargs)`
Returns:
(dict): Context for the template to use inclusive of 'external_links'
"""
context = super().get_context_data(**kwargs)
external_links_query = None
if self.model._meta.model_name == 'device':
external_links_query = ExternalLink.objects.filter(devices=True)
elif self.model._meta.model_name == 'software':
external_links_query = ExternalLink.objects.filter(software=True)
if external_links_query:
external_links: list = []
user_context = Context(context)
for external_link in external_links_query:
user_string = Template(external_link)
external_link_context: dict = {
'name': escape(external_link.name),
'link': escape(user_string.render(user_context)),
}
if external_link.colour:
external_link_context.update({'colour': external_link.colour })
external_links += [ external_link_context ]
context['external_links'] = external_links
return context
class IndexView(View, generic.ListView):
model = None
""" Model the view is for
Leaving this value unset will prevent the item from showing up within the navigation menu
"""
template_name:str = None
def __init__(self, **kwargs):
if not self.model:
raise MissingAttribute('Model is required for view')
super().__init__(**kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = self.model._meta.verbose_name_plural
return context

View File

@ -1,83 +0,0 @@
from django.urls import reverse
from django.views import generic
from django_celery_results.models import TaskResult
from access.mixin import OrganizationPermission
from core.forms.related_ticket import RelatedTicketForm
from core.models.ticket.ticket import RelatedTickets
from core.views.common import AddView, ChangeView, DeleteView, IndexView
from settings.models.user_settings import UserSettings
class Add(AddView):
form_class = RelatedTicketForm
model = RelatedTickets
permission_required = [
'itam.add_device',
]
template_name = 'form.html.j2'
def get_initial(self):
initial_values: dict = {
'organization': UserSettings.objects.get(user = self.request.user).default_organization,
'from_ticket_id': self.kwargs['ticket_id'],
}
return initial_values
def get_success_url(self, **kwargs):
if self.kwargs['ticket_type'] == 'request':
return reverse('Assistance:_ticket_request_view', args=(self.kwargs['ticket_type'],self.kwargs['ticket_id'],))
elif self.kwargs['ticket_type'] == 'project_task':
return reverse('Project Management:_project_task_view', args=(self.object.from_ticket_id.project.id, self.kwargs['ticket_type'],self.kwargs['ticket_id'],))
else:
return reverse('ITIM:_ticket_' + str(self.kwargs['ticket_type']).lower() + '_view', args=(self.kwargs['ticket_type'],self.kwargs['ticket_id'],))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = 'Ticket Comment'
return context
class Delete(DeleteView):
model = RelatedTickets
permission_required = [
'itim.delete_cluster',
]
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = 'Delete ' + str(self.object)
return context
def get_success_url(self, **kwargs):
return reverse('ITIM:Clusters')

View File

@ -1,341 +0,0 @@
from django.http import Http404
from django.urls import reverse
from django.views import generic
from django_celery_results.models import TaskResult
from access.mixin import OrganizationPermission
from core.forms.ticket import DetailForm, TicketForm
from core.models.ticket.ticket import Ticket
from core.views.common import AddView, ChangeView, DeleteView, IndexView
from settings.models.user_settings import UserSettings
class Add(AddView):
form_class = TicketForm
model = Ticket
def get_dynamic_permissions(self):
return [
str('core.add_ticket_' + self.kwargs['ticket_type']),
]
def get_initial(self):
initial = super().get_initial()
initial.update({
'type_ticket': self.kwargs['ticket_type'],
})
if self.kwargs['ticket_type'] == 'project_task':
initial.update({
'project': int(self.kwargs['project_id'])
})
return initial
def form_valid(self, form):
created: bool = False
if form.instance.id is None:
created = True
val = super().form_valid(form)
if created:
form.instance.subscribed_users.add(form.instance.opened_by)
return val
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['request'] = self.request
return kwargs
def get_success_url(self, **kwargs):
if self.kwargs['ticket_type'] == 'request':
return reverse('Assistance:_ticket_request_view', args=(self.kwargs['ticket_type'],self.object.id,))
elif self.kwargs['ticket_type'] == 'project_task':
return reverse('Project Management:_project_task_view', args=(self.kwargs['project_id'], self.kwargs['ticket_type'],self.object.id,))
else:
return reverse('ITIM:_ticket_' + str(self.kwargs['ticket_type']).lower() + '_view', args=(self.kwargs['ticket_type'],self.object.id,))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = 'New Ticket'
return context
class Change(ChangeView):
form_class = TicketForm
model = Ticket
def get_dynamic_permissions(self):
return [
str('core.change_ticket_' + self.kwargs['ticket_type']),
]
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = str(self.object)
return context
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['request'] = self.request
return kwargs
def get_initial(self):
initial = super().get_initial()
initial.update({
'type_ticket': self.kwargs['ticket_type'],
})
if self.kwargs['ticket_type'] == 'project_task':
initial.update({
'project': int(self.kwargs['project_id'])
})
return initial
def get_success_url(self, **kwargs):
if self.kwargs['ticket_type'] == 'request':
return reverse('Assistance:_ticket_request_view', args=(self.kwargs['ticket_type'],self.object.id,))
elif self.kwargs['ticket_type'] == 'project_task':
return reverse('Project Management:_project_task_view', args=(self.kwargs['project_id'], self.kwargs['ticket_type'],self.object.id,))
else:
return reverse('ITIM:_ticket_' + str(self.kwargs['ticket_type']).lower() + '_view', args=(self.kwargs['ticket_type'],self.object.id,))
class Delete(DeleteView):
model = Ticket
def get_dynamic_permissions(self):
return [
str('core.delete_ticket_' + self.kwargs['ticket_type']),
]
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = 'Delete ' + str(self.object)
return context
def get_success_url(self, **kwargs):
if self.kwargs['ticket_type'] == 'request':
return reverse('Assistance:Requests')
elif self.kwargs['ticket_type'] == 'project_task':
return reverse('Project Management:_project_view', kwargs={'pk': self.object.id})
else:
if self.kwargs['ticket_type'] == 'change':
path = 'Changes'
elif self.kwargs['ticket_type'] == 'incident':
path = 'Incidents'
elif self.kwargs['ticket_type'] == 'problem':
path = 'Problems'
return reverse('ITIM:' + path)
class Index(OrganizationPermission, generic.ListView):
context_object_name = "tickets"
fields = [
"id",
'title',
'status',
'date_created',
]
model = Ticket
template_name = 'core/ticket/index.html.j2'
def get_dynamic_permissions(self):
return [
str('core.view_ticket_' + self.kwargs['ticket_type']),
]
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.kwargs['ticket_type'] == 'request':
context['new_ticket_url'] = reverse('Assistance:_ticket_request_add', args=(self.kwargs['ticket_type'],))
else:
context['new_ticket_url'] = reverse(str('ITIM:_ticket_' + self.kwargs['ticket_type'] + '_add'), args=(self.kwargs['ticket_type'],))
context['ticket_type'] = self.kwargs['ticket_type']
context['content_title'] = 'Tickets'
return context
def get_queryset(self):
if not hasattr(Ticket.TicketType, str(self.kwargs['ticket_type']).upper()):
raise Http404
queryset = super().get_queryset()
queryset = queryset.filter(
ticket_type = Ticket.TicketType[str(self.kwargs['ticket_type']).upper()]
)
return queryset
def get_success_url(self, **kwargs):
return reverse('Settings:_device_model_view', args=(self.kwargs['pk'],))
class View(ChangeView):
model = Ticket
template_name = 'core/ticket.html.j2'
form_class = DetailForm
context_object_name = "ticket"
def get_dynamic_permissions(self):
return [
str('core.view_ticket_' + self.kwargs['ticket_type']),
]
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['ticket_type'] = self.kwargs['ticket_type']
url_kwargs = { 'ticket_type': self.kwargs['ticket_type'], 'pk': self.kwargs['pk']}
if self.kwargs['ticket_type'] == 'request':
path = 'Assistance:_ticket_request_change'
context['model_delete_url'] = reverse('Assistance:_ticket_' + self.kwargs['ticket_type'] + '_delete', kwargs=url_kwargs)
elif self.kwargs['ticket_type'] == 'project_task':
path = 'Project Management:_project_task_change'
url_kwargs = { 'project_id': self.kwargs['project_id'],'ticket_type': self.kwargs['ticket_type'], 'pk': self.kwargs['pk']}
context['model_delete_url'] = reverse('Project Management:_project_task_delete', kwargs=url_kwargs)
else:
comment_path = 'ITIM:_ticket_comment_' + self.kwargs['ticket_type']
if self.kwargs['ticket_type'] == 'change':
path = 'ITIM:_ticket_change_change'
elif self.kwargs['ticket_type'] == 'incident':
path = 'ITIM:_ticket_incident_change'
elif self.kwargs['ticket_type'] == 'problem':
path = 'ITIM:_ticket_problem_change'
context['model_delete_url'] = reverse('ITIM:_ticket_' + self.kwargs['ticket_type'] + '_delete', kwargs=url_kwargs)
context['edit_url'] = reverse(
path,
kwargs = url_kwargs,
) # /assistance/ticket/{{ ticket_type }}/{{ ticket.id }}
context['content_title'] = self.object.title
return context
def get_initial(self):
return {
'type_ticket': self.kwargs['ticket_type'],
}

View File

@ -1,168 +0,0 @@
from django.urls import reverse
from core.forms.comment import AddNoteForm
from core.forms.ticket_categories import DetailForm, TicketCategory, TicketCategoryForm
from core.models.notes import Notes
from core.views.common import AddView, ChangeView, DeleteView, IndexView
class Add(AddView):
form_class = TicketCategoryForm
model = TicketCategory
permission_required = [
'core.add_ticketcategory',
]
def get_initial(self):
initial = super().get_initial()
if 'pk' in self.kwargs:
if self.kwargs['pk']:
initial.update({'parent': self.kwargs['pk']})
self.model.parent.field.hidden = True
return initial
def get_success_url(self, **kwargs):
return reverse('Settings:_ticket_categories')
class Change(ChangeView):
form_class = TicketCategoryForm
model = TicketCategory
permission_required = [
'core.change_ticketcategory',
]
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = str(self.object)
return context
def get_success_url(self, **kwargs):
return reverse('Settings:_ticket_category_view', args=(self.kwargs['pk'],))
class Delete(DeleteView):
model = TicketCategory
permission_required = [
'core.delete_ticketcategory',
]
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = 'Delete ' + str(self.object)
return context
def get_success_url(self, **kwargs):
return reverse('Settings:_ticket_categories')
class Index(IndexView):
context_object_name = "items"
model = TicketCategory
paginate_by = 10
permission_required = [
'core.view_ticketcategory'
]
template_name = 'core/index_ticket_categories.html.j2'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['model_docs_path'] = self.model._meta.app_label + '/' + self.model._meta.model_name
return context
class View(ChangeView):
context_object_name = "ticket_categories"
form_class = DetailForm
model = TicketCategory
permission_required = [
'core.view_ticketcategory',
]
template_name = 'core/ticket_category.html.j2'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['notes_form'] = AddNoteForm(prefix='note')
context['notes'] = Notes.objects.filter(service=self.kwargs['pk'])
context['model_pk'] = self.kwargs['pk']
context['model_name'] = self.model._meta.model_name
context['model_delete_url'] = reverse('Settings:_ticket_category_delete', kwargs={'pk': self.kwargs['pk']})
context['content_title'] = self.object.name
return context
# def post(self, request, *args, **kwargs):
# item = Cluster.objects.get(pk=self.kwargs['pk'])
# notes = AddNoteForm(request.POST, prefix='note')
# if notes.is_bound and notes.is_valid() and notes.instance.note != '':
# notes.instance.service = item
# notes.instance.organization = item.organization
# notes.save()
def get_success_url(self, **kwargs):
return reverse('Settings:_ticket_category_view', kwargs={'pk': self.kwargs['pk']})

View File

@ -1,156 +0,0 @@
from django.core.exceptions import ObjectDoesNotExist
from django.http import Http404
from django.urls import reverse
from django.views import generic
from django_celery_results.models import TaskResult
from access.mixin import OrganizationPermission
from core.forms.ticket_comment import CommentForm, DetailForm
from core.models.ticket.ticket_comment import TicketComment, Ticket
from core.views.common import AddView, ChangeView, DeleteView, IndexView
from settings.models.user_settings import UserSettings
class Add(AddView):
form_class = CommentForm
model = TicketComment
parent_model = Ticket
parent_model_pk_kwarg = 'ticket_id'
template_name = 'form.html.j2'
def get_dynamic_permissions(self):
if self.request.user.is_authenticated:
try:
ticket = Ticket.objects.get(pk=int(self.kwargs['ticket_id']))
if ticket.opened_by.id == self.request.user.id:
return []
except ObjectDoesNotExist:
pass
return [
str('core.add_ticketcomment'),
]
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['request'] = self.request
return kwargs
def get_initial(self):
initial_values: dict = {
'organization': UserSettings.objects.get(user = self.request.user).default_organization,
'type_ticket': self.kwargs['ticket_type'],
'ticket': self.kwargs['ticket_id'],
}
if 'comment_type' in self.request.GET:
initial_values.update({
'qs_comment_type': self.request.GET['comment_type']
})
if 'parent_id' in self.kwargs:
initial_values.update({
'parent': self.kwargs['parent_id']
})
return initial_values
def get_success_url(self, **kwargs):
if self.kwargs['ticket_type'] == 'request':
return reverse('Assistance:_ticket_request_view', args=(self.kwargs['ticket_type'],self.kwargs['ticket_id']))
elif self.kwargs['ticket_type'] == 'project_task':
return reverse('Project Management:_project_task_view', args=(self.object.ticket.project.id, self.kwargs['ticket_type'],self.kwargs['ticket_id'],))
return reverse(
'ITIM:_ticket_' + self.kwargs['ticket_type'] + '_view',
kwargs={'ticket_type': self.kwargs['ticket_type'], 'pk': self.kwargs['ticket_id']},
)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = 'Ticket Comment'
return context
class Change(ChangeView):
form_class = CommentForm
model = TicketComment
def get_dynamic_permissions(self):
try:
if (
self.request.user.is_authenticated and
self.get_object().user.id == self.request.user.id
):
return []
except Http404: # Although the model not found, permissions must return HTTP/403 for authenticated user
pass
return [
str('core.change_ticketcomment'),
]
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = str(self.object)
return context
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['request'] = self.request
return kwargs
def get_initial(self):
return {
'type_ticket': self.kwargs['ticket_type'],
}
def get_success_url(self, **kwargs):
return reverse('Assistance:_ticket_request_view', args=(self.kwargs['ticket_type'], self.kwargs['ticket_id'],))

View File

@ -1,168 +0,0 @@
from django.urls import reverse
from core.forms.comment import AddNoteForm
from core.forms.ticket_comment_category import DetailForm, TicketCommentCategory, TicketCommentCategoryForm
from core.models.notes import Notes
from core.views.common import AddView, ChangeView, DeleteView, IndexView
class Add(AddView):
form_class = TicketCommentCategoryForm
model = TicketCommentCategory
permission_required = [
'core.add_ticketcommentcategory',
]
def get_initial(self):
initial = super().get_initial()
if 'pk' in self.kwargs:
if self.kwargs['pk']:
initial.update({'parent': self.kwargs['pk']})
self.model.parent.field.hidden = True
return initial
def get_success_url(self, **kwargs):
return reverse('Settings:_ticket_comment_categories')
class Change(ChangeView):
form_class = TicketCommentCategoryForm
model = TicketCommentCategory
permission_required = [
'core.change_ticketcommentcategory',
]
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = str(self.object)
return context
def get_success_url(self, **kwargs):
return reverse('Settings:_ticket_comment_category_view', args=(self.kwargs['pk'],))
class Delete(DeleteView):
model = TicketCommentCategory
permission_required = [
'core.delete_ticketcommentcategory',
]
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = 'Delete ' + str(self.object)
return context
def get_success_url(self, **kwargs):
return reverse('Settings:_ticket_comment_categories')
class Index(IndexView):
context_object_name = "items"
model = TicketCommentCategory
paginate_by = 10
permission_required = [
'core.view_ticketcommentcategory'
]
template_name = 'core/index_ticket_comment_categories.html.j2'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['model_docs_path'] = self.model._meta.app_label + '/ticket_comment_category'
return context
class View(ChangeView):
context_object_name = "ticket_categories"
form_class = DetailForm
model = TicketCommentCategory
permission_required = [
'core.view_ticketcommentcategory',
]
template_name = 'core/ticket_comment_category.html.j2'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['notes_form'] = AddNoteForm(prefix='note')
context['notes'] = Notes.objects.filter(service=self.kwargs['pk'])
context['model_pk'] = self.kwargs['pk']
context['model_name'] = self.model._meta.model_name
context['model_delete_url'] = reverse('Settings:_ticket_comment_category_delete', kwargs={'pk': self.kwargs['pk']})
context['content_title'] = self.object.name
return context
# def post(self, request, *args, **kwargs):
# item = Cluster.objects.get(pk=self.kwargs['pk'])
# notes = AddNoteForm(request.POST, prefix='note')
# if notes.is_bound and notes.is_valid() and notes.instance.note != '':
# notes.instance.service = item
# notes.instance.organization = item.organization
# notes.save()
def get_success_url(self, **kwargs):
return reverse('Settings:_ticket_comment_category_view', kwargs={'pk': self.kwargs['pk']})

View File

@ -1,92 +0,0 @@
from django.urls import reverse
from django.views import generic
from django_celery_results.models import TaskResult
from access.mixin import OrganizationPermission
from core.forms.ticket_linked_item import TicketLinkedItem, TicketLinkedItemForm
from core.views.common import AddView, ChangeView, DeleteView, IndexView
from settings.models.user_settings import UserSettings
class Add(AddView):
form_class = TicketLinkedItemForm
model = TicketLinkedItem
permission_required = [
'core.add_ticketlinkeditem',
]
template_name = 'form.html.j2'
def get_initial(self):
initial_values: dict = {
'organization': UserSettings.objects.get(user = self.request.user).default_organization,
'ticket': self.kwargs['ticket_id'],
}
return initial_values
def get_success_url(self, **kwargs):
if self.kwargs['ticket_type'] == 'request':
return reverse('Assistance:_ticket_request_view', args=(self.kwargs['ticket_type'],self.kwargs['ticket_id'],))
elif self.kwargs['ticket_type'] == 'project_task':
return reverse('Project Management:_project_task_view', args=(self.object.from_ticket_id.project.id, self.kwargs['ticket_type'],self.kwargs['ticket_id'],))
else:
return reverse('ITIM:_ticket_' + str(self.kwargs['ticket_type']).lower() + '_view', args=(self.kwargs['ticket_type'],self.kwargs['ticket_id'],))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = 'Ticket Linked Item'
return context
class Delete(DeleteView):
model = TicketLinkedItem
permission_required = [
'itim.delete_cluster',
]
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['content_title'] = 'Delete ' + str(self.object)
return context
def get_success_url(self, **kwargs):
if self.kwargs['ticket_type'] == 'request':
return reverse('Assistance:_ticket_request_view', args=(self.kwargs['ticket_type'],self.kwargs['ticket_id'],))
elif self.kwargs['ticket_type'] == 'project_task':
return reverse('Project Management:_project_task_view', args=(self.object.from_ticket_id.project.id, self.kwargs['ticket_type'],self.kwargs['ticket_id'],))
else:
return reverse('ITIM:_ticket_' + str(self.kwargs['ticket_type']).lower() + '_view', args=(self.kwargs['ticket_type'],self.kwargs['ticket_id'],))