diff --git a/helpdesk/forms.py b/helpdesk/forms.py
index ff76d435..55b004e9 100644
--- a/helpdesk/forms.py
+++ b/helpdesk/forms.py
@@ -177,6 +177,17 @@ class AbstractTicketForm(CustomFieldMixin, forms.Form):
help_text=_('You can attach a file such as a document or screenshot to this ticket.'),
)
+ def __init__(self, kbcategory=None, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ if kbcategory:
+ self.fields['kbitem'] = forms.ChoiceField(
+ widget=forms.Select(attrs={'class': 'form-control'}),
+ required=False,
+ label=_('Knowedge Base Item'),
+ choices=[(kbi.pk, kbi.title) for kbi in KBItem.objects.filter(category=kbcategory.pk)],
+ )
+
+
def _add_form_custom_fields(self, staff_only_filter=None):
if staff_only_filter is None:
queryset = CustomField.objects.all()
@@ -184,11 +195,8 @@ class AbstractTicketForm(CustomFieldMixin, forms.Form):
queryset = CustomField.objects.filter(staff_only=staff_only_filter)
for field in queryset:
- instanceargs = {
- 'label': field.label,
- 'help_text': field.help_text,
- 'required': field.required,
- }
+ instanceargs = { 'label': field.label, 'help_text':
+ field.help_text, 'required': field.required, }
self.customfield_to_field(field, instanceargs)
@@ -341,22 +349,13 @@ class PublicTicketForm(AbstractTicketForm):
help_text=_('We will e-mail you when your ticket is updated.'),
)
- def __init__(self, hidden_fields=(), readonly_fields=(), kbcategory=None, *args, **kwargs):
+ def __init__(self, hidden_fields=(), readonly_fields=(), *args, **kwargs):
"""
Add any (non-staff) custom fields that are defined to the form
"""
super(PublicTicketForm, self).__init__(*args, **kwargs)
self._add_form_custom_fields(False)
- if kbcategory:
- self.fields['kbitem'] = forms.ChoiceField(
- widget=forms.Select(attrs={'class': 'form-control'}),
- required=False,
- label=_('Knowedge Base Item'),
- choices=[(kbi.pk, kbi.title) for kbi in KBItem.objects.filter(category=kbcategory.pk)],
- )
-
-
field_hide_table = {
'queue': 'HELPDESK_PUBLIC_TICKET_QUEUE',
'priority': 'HELPDESK_PUBLIC_TICKET_PRIORITY',
diff --git a/helpdesk/models.py b/helpdesk/models.py
index 09d2436b..1ab47c74 100644
--- a/helpdesk/models.py
+++ b/helpdesk/models.py
@@ -1320,6 +1320,11 @@ class KBItem(models.Model):
from django.urls import reverse
return str(reverse('helpdesk:kb_category', args=(self.category.slug,)))+"?kbitem="+str(self.pk)
+ def query_url(self):
+ from django.urls import reverse
+ return str(reverse('helpdesk:list')) +"?kbitem="+str(self.pk)
+
+
def get_markdown(self):
return get_markdown(self.answer)
diff --git a/helpdesk/templates/helpdesk/filters/kbitems.html b/helpdesk/templates/helpdesk/filters/kbitems.html
new file mode 100644
index 00000000..fa79dd33
--- /dev/null
+++ b/helpdesk/templates/helpdesk/filters/kbitems.html
@@ -0,0 +1,15 @@
+{% load i18n humanize %}
+{% load static from staticfiles %}
+{% load in_list %}
+
diff --git a/helpdesk/templates/helpdesk/kb_category.html b/helpdesk/templates/helpdesk/kb_category.html
index 953fe183..38ddd413 100644
--- a/helpdesk/templates/helpdesk/kb_category.html
+++ b/helpdesk/templates/helpdesk/kb_category.html
@@ -43,6 +43,7 @@
{% blocktrans with recommendations=item.recommendations votes=item.votes %}{{ recommendations }} people found this answer useful of {{votes}}. {% endblocktrans %}
{% endif %}
+
@@ -51,7 +52,7 @@
{% endfor %}
{% if category.queue %}
-
+
{% endif %}
{% endblock %}
diff --git a/helpdesk/templates/helpdesk/ticket_desc_table.html b/helpdesk/templates/helpdesk/ticket_desc_table.html
index 52b3000e..4a3dbfe5 100644
--- a/helpdesk/templates/helpdesk/ticket_desc_table.html
+++ b/helpdesk/templates/helpdesk/ticket_desc_table.html
@@ -68,6 +68,12 @@
{% trans "Total time spent" %} |
{{ ticket.time_spent_formated }} |
+ {% if ticket.kbitem %}
+
+ {% trans "Knowlegebase item" %} |
+ {{ticket.kbitem.title}} |
+
+ {% endif %}
{% trans "Attachments" %} |
diff --git a/helpdesk/templates/helpdesk/ticket_list.html b/helpdesk/templates/helpdesk/ticket_list.html
index 3e56eb7c..03be65e2 100644
--- a/helpdesk/templates/helpdesk/ticket_list.html
+++ b/helpdesk/templates/helpdesk/ticket_list.html
@@ -171,6 +171,7 @@
+
{% csrf_token %}
@@ -196,6 +197,9 @@
{% include './filters/keywords.html' %}
+
+ {% include './filters/kbitems.html' %}
+
@@ -318,8 +322,8 @@
var name = data.split(" ")[1];
if (type === 'display')
{
- data = '' +
- row.id + '. ' +
+ data = '';
}
return data
@@ -348,7 +352,7 @@
"render": function(data, type, row, meta) {
if (data != "None") {
return data;
- }
+ }
else {
return "";
}
@@ -396,6 +400,9 @@
{% if query_params.search_string %}
$("#filterBuilderSelect-Keywords")[0].disabled = "disabled";
{% endif %}
+ {% if query_params.filtering.kbitem__in %}
+ $("#filterBuilderSelect-KBItems")[0].disabled = "disabled";
+ {% endif %}
});
{% for f in query_params.filtering %}
diff --git a/helpdesk/views/abstract_views.py b/helpdesk/views/abstract_views.py
new file mode 100644
index 00000000..648996b3
--- /dev/null
+++ b/helpdesk/views/abstract_views.py
@@ -0,0 +1,37 @@
+from django.views.generic.edit import FormView
+
+from helpdesk.models import CustomField, KBItem, Queue
+
+
+class AbstractCreateTicketMixin():
+ def get_initial(self):
+ initial_data = {}
+ request = self.request
+ try:
+ initial_data['queue'] = Queue.objects.get(slug=request.GET.get('queue', None)).id
+ except Queue.DoesNotExist:
+ pass
+ if request.user.is_authenticated and request.user.usersettings_helpdesk.use_email_as_submitter and request.user.email:
+ initial_data['submitter_email'] = request.user.email
+
+
+ query_param_fields = ['submitter_email', 'title', 'body', 'queue', 'kbitem']
+ custom_fields = ["custom_%s" % f.name for f in CustomField.objects.filter(staff_only=False)]
+ query_param_fields += custom_fields
+ for qpf in query_param_fields:
+ initial_data[qpf] = request.GET.get(qpf, initial_data.get(qpf, ""))
+
+ return initial_data
+
+ def get_form_kwargs(self, *args, **kwargs):
+ kwargs = super().get_form_kwargs(*args, **kwargs)
+ kbitem = self.request.GET.get(
+ 'kbitem',
+ self.request.POST.get('kbitem', None),
+ )
+ if kbitem:
+ try:
+ kwargs['kbcategory'] = KBItem.objects.get(pk=int(kbitem)).category
+ except (ValueError, KBItem.DoesNotExist):
+ pass
+ return kwargs
diff --git a/helpdesk/views/kb.py b/helpdesk/views/kb.py
index 78666767..1b2626d0 100644
--- a/helpdesk/views/kb.py
+++ b/helpdesk/views/kb.py
@@ -30,12 +30,18 @@ def category(request, slug):
selected_item = request.GET.get('kbitem', None)
try:
selected_item = int(selected_item)
- except ValueError:
+ except TypeError:
+ pass
+ qparams = request.GET.copy()
+ try:
+ del qparams['kbitem']
+ except KeyError:
pass
return render(request, 'helpdesk/kb_category.html', {
'category': category,
'items': items,
'selected_item': selected_item,
+ 'query_param_string': qparams.urlencode(),
'helpdesk_settings': helpdesk_settings,
})
diff --git a/helpdesk/views/public.py b/helpdesk/views/public.py
index 2ffcdc38..b9f5279b 100644
--- a/helpdesk/views/public.py
+++ b/helpdesk/views/public.py
@@ -19,6 +19,7 @@ from django.views.generic.edit import FormView
from helpdesk import settings as helpdesk_settings
from helpdesk.decorators import protect_view, is_helpdesk_staff
import helpdesk.views.staff as staff
+import helpdesk.views.abstract_views as abstract_views
from helpdesk.forms import PublicTicketForm
from helpdesk.lib import text_is_spam
from helpdesk.models import CustomField, Ticket, Queue, UserSettings, KBCategory, KBItem
@@ -31,7 +32,7 @@ def create_ticket(request, *args, **kwargs):
return CreateTicketView.as_view()(request, *args, **kwargs)
-class BaseCreateTicketView(FormView):
+class BaseCreateTicketView(abstract_views.AbstractCreateTicketMixin, FormView):
form_class = PublicTicketForm
def dispatch(self, *args, **kwargs):
@@ -51,54 +52,27 @@ class BaseCreateTicketView(FormView):
return HttpResponseRedirect(reverse('helpdesk:dashboard'))
return super().dispatch(*args, **kwargs)
- def get_context_data(self, **kwargs):
- context = super().get_context_data(**kwargs)
- context['kb_categories'] = KBCategory.objects.all()
- return context
-
def get_initial(self):
request = self.request
- initial_data = {}
- try:
- queue = Queue.objects.get(slug=request.GET.get('queue', None))
- except Queue.DoesNotExist:
- queue = None
+ initial_data = super().get_initial()
# add pre-defined data for public ticket
if hasattr(settings, 'HELPDESK_PUBLIC_TICKET_QUEUE'):
# get the requested queue; return an error if queue not found
try:
- queue = Queue.objects.get(slug=settings.HELPDESK_PUBLIC_TICKET_QUEUE)
+ initial_data['queue'] = Queue.objects.get(slug=settings.HELPDESK_PUBLIC_TICKET_QUEUE).id
except Queue.DoesNotExist:
return HttpResponse(status=500)
if hasattr(settings, 'HELPDESK_PUBLIC_TICKET_PRIORITY'):
initial_data['priority'] = settings.HELPDESK_PUBLIC_TICKET_PRIORITY
if hasattr(settings, 'HELPDESK_PUBLIC_TICKET_DUE_DATE'):
initial_data['due_date'] = settings.HELPDESK_PUBLIC_TICKET_DUE_DATE
-
- if queue:
- initial_data['queue'] = queue.id
-
- if request.user.is_authenticated and request.user.email:
- initial_data['submitter_email'] = request.user.email
-
- query_param_fields = ['submitter_email', 'title', 'body', 'queue', 'kbitem']
- custom_fields = ["custom_%s" % f.name for f in CustomField.objects.filter(staff_only=False)]
- query_param_fields += custom_fields
- for qpf in query_param_fields:
- initial_data[qpf] = request.GET.get(qpf, initial_data.get(qpf, ""))
return initial_data
def get_form_kwargs(self, *args, **kwargs):
kwargs = super().get_form_kwargs(*args, **kwargs)
kwargs['hidden_fields'] = self.request.GET.get('_hide_fields_', '').split(',')
kwargs['readonly_fields'] = self.request.GET.get('_readonly_fields_', '').split(',')
- kbitem = self.request.GET.get('kbitem', None)
- if kbitem:
- try:
- kwargs['kbcategory'] = KBItem.objects.get(pk=int(kbitem))
- except (ValueError, KBItem.DoesNotExist):
- pass
return kwargs
def form_valid(self, form):
@@ -134,6 +108,11 @@ class CreateTicketView(BaseCreateTicketView):
class Homepage(CreateTicketView):
template_name = 'helpdesk/public_homepage.html'
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['kb_categories'] = KBCategory.objects.all()
+ return context
+
def search_for_ticket(request, error_message=None):
if hasattr(settings, 'HELPDESK_VIEW_A_TICKET_PUBLIC') and settings.HELPDESK_VIEW_A_TICKET_PUBLIC:
diff --git a/helpdesk/views/staff.py b/helpdesk/views/staff.py
index c374b51b..0ea2f481 100644
--- a/helpdesk/views/staff.py
+++ b/helpdesk/views/staff.py
@@ -52,9 +52,10 @@ from helpdesk.lib import (
)
from helpdesk.models import (
Ticket, Queue, FollowUp, TicketChange, PreSetReply, FollowUpAttachment, SavedSearch,
- IgnoreEmail, TicketCC, TicketDependency, UserSettings,
+ IgnoreEmail, TicketCC, TicketDependency, UserSettings, KBItem,
)
from helpdesk import settings as helpdesk_settings
+import helpdesk.views.abstract_views as abstract_views
from helpdesk.views.permissions import MustBeStaffMixin
from ..lib import format_time_spent
@@ -802,7 +803,9 @@ def ticket_list(request):
'search_string': '',
}
default_query_params = {
- 'filtering': {'status__in': [1, 2, 3]},
+ 'filtering': {
+ 'status__in': [1, 2, 3],
+ },
'sorting': 'created',
'search_string': '',
'sortreverse': False,
@@ -849,7 +852,7 @@ def ticket_list(request):
if saved_query:
pass
- elif not {'queue', 'assigned_to', 'status', 'q', 'sort', 'sortreverse'}.intersection(request.GET):
+ elif not {'queue', 'assigned_to', 'status', 'q', 'sort', 'sortreverse', 'kbitem'}.intersection(request.GET):
# Fall-back if no querying is being done
all_queues = Queue.objects.all()
query_params = deepcopy(default_query_params)
@@ -858,6 +861,7 @@ def ticket_list(request):
('queue', 'queue__id__in'),
('assigned_to', 'assigned_to__id__in'),
('status', 'status__in'),
+ ('kbitem', 'kbitem__in'),
]
for param, filter_command in filter_in_params:
@@ -884,7 +888,7 @@ def ticket_list(request):
# SORTING
sort = request.GET.get('sort', None)
- if sort not in ('status', 'assigned_to', 'created', 'title', 'queue', 'priority'):
+ if sort not in ('status', 'assigned_to', 'created', 'title', 'queue', 'priority', 'kbitem'):
sort = 'created'
query_params['sorting'] = sort
@@ -907,12 +911,15 @@ def ticket_list(request):
''
'Django Documentation on string matching in SQLite.')
+ kbitem_choices = [(item.pk, item.title) for item in KBItem.objects.all()]
+
return render(request, 'helpdesk/ticket_list.html', dict(
context,
default_tickets_per_page=request.user.usersettings_helpdesk.tickets_per_page,
user_choices=User.objects.filter(is_active=True, is_staff=True),
queue_choices=huser.get_queues(),
status_choices=Ticket.STATUS_CHOICES,
+ kbitem_choices=kbitem_choices,
urlsafe_query=urlsafe_query,
user_saved_queries=user_saved_queries,
query_params=query_params,
@@ -992,17 +999,12 @@ def edit_ticket(request, ticket_id):
edit_ticket = staff_member_required(edit_ticket)
-class CreateTicketView(MustBeStaffMixin, FormView):
+class CreateTicketView(MustBeStaffMixin, abstract_views.AbstractCreateTicketMixin, FormView):
template_name = 'helpdesk/create_ticket.html'
form_class = TicketForm
def get_initial(self):
- initial_data = {}
- request = self.request
- if request.user.usersettings_helpdesk.use_email_as_submitter and request.user.email:
- initial_data['submitter_email'] = request.user.email
- if 'queue' in request.GET:
- initial_data['queue'] = request.GET['queue']
+ initial_data = super().get_initial()
return initial_data
def get_form_kwargs(self):
|