forked from extern/django-helpdesk
* Add localisation hooks
* Add VERY basic knowledgebase functions * Restructure views.py into views/*.py
This commit is contained in:
parent
dfb821336e
commit
23084499c1
@ -33,6 +33,7 @@ table {
|
||||
margin: 2px;
|
||||
border: solid #444 1px;
|
||||
color: #000;
|
||||
background-color: #eee;
|
||||
text-decoration: none;
|
||||
font-size: 10pt;
|
||||
line-height: 12pt;
|
||||
|
66
models.py
66
models.py
@ -29,6 +29,8 @@ class Queue(models.Model):
|
||||
title = models.CharField(_('Title'), max_length=100)
|
||||
slug = models.SlugField(_('Slug'), help_text=_('This slug is used when building ticket ID\'s. Once set, try not to change it or e-mailing may get messy.'))
|
||||
email_address = models.EmailField(_('E-Mail Address'), blank=True, null=True, help_text=_('All outgoing e-mails for this queue will use this e-mail address. If you use IMAP or POP3, this should be the e-mail address for that mailbox.'))
|
||||
allow_public_submission = models.BooleanField(_('Allow Public Submission?'), blank=True, null=True, help_text=_('Should this queue be listed on the public submission form?'))
|
||||
allow_email_submission = models.BooleanField(_('Allow E-Mail Submission?'), blank=True, null=True, help_text=_('Do you want to poll the e-mail box below for new tickets?'))
|
||||
escalate_days = models.IntegerField(_('Escalation Days'), blank=True, null=True, help_text=_('For tickets which are not held, how often do you wish to increase their priority? Set to 0 for no escalation.'))
|
||||
|
||||
def _from_address(self):
|
||||
@ -180,7 +182,7 @@ class Ticket(models.Model):
|
||||
return u'%s' % self.title
|
||||
|
||||
def get_absolute_url(self):
|
||||
return ('helpdesk.views.view_ticket', [str(self.id)])
|
||||
return ('helpdesk_view', [str(self.id)])
|
||||
get_absolute_url = models.permalink(get_absolute_url)
|
||||
|
||||
def save(self):
|
||||
@ -364,3 +366,65 @@ class EmailTemplate(models.Model):
|
||||
|
||||
class Meta:
|
||||
ordering = ['template_name',]
|
||||
|
||||
class KBCategory(models.Model):
|
||||
"""
|
||||
Lets help users help themselves: the Knowledge Base is a categorised
|
||||
listing of questions & answers.
|
||||
"""
|
||||
|
||||
title = models.CharField(_('Title'), max_length=100)
|
||||
slug = models.SlugField(_('Slug'))
|
||||
description = models.TextField(_('Description'))
|
||||
|
||||
def __unicode__(self):
|
||||
return u'%s' % self.title
|
||||
|
||||
class Admin:
|
||||
pass
|
||||
|
||||
class Meta:
|
||||
ordering = ['title',]
|
||||
|
||||
def get_absolute_url(self):
|
||||
return ('helpdesk_kb_category', [str(self.slug)])
|
||||
get_absolute_url = models.permalink(get_absolute_url)
|
||||
|
||||
class KBItem(models.Model):
|
||||
"""
|
||||
An item within the knowledgebase. Very straightforward question/answer
|
||||
style system.
|
||||
"""
|
||||
category = models.ForeignKey(KBCategory)
|
||||
title = models.CharField(_('Title'), max_length=100)
|
||||
question = models.TextField(_('Question'))
|
||||
answer = models.TextField(_('Answer'))
|
||||
|
||||
votes = models.IntegerField(_('Votes'), help_text=_('Total number of votes cast for this item'))
|
||||
recommendations = models.IntegerField(_('Positive Votes'), help_text=_('Number of votes for this item which were POSITIVE.'))
|
||||
|
||||
last_updated = models.DateTimeField(_('Last Updated'))
|
||||
|
||||
def save(self):
|
||||
self.last_updated = datetime.now()
|
||||
return super(KBItem, self).save()
|
||||
|
||||
def _score(self):
|
||||
if self.votes > 0:
|
||||
return int(self.recommendations / self.votes)
|
||||
else:
|
||||
return _('Unrated')
|
||||
score = property(_score)
|
||||
|
||||
def __unicode__(self):
|
||||
return u'%s' % self.title
|
||||
|
||||
class Admin:
|
||||
pass
|
||||
|
||||
class Meta:
|
||||
ordering = ['title',]
|
||||
|
||||
def get_absolute_url(self):
|
||||
return ('helpdesk_kb_item', [str(self.id)])
|
||||
get_absolute_url = models.permalink(get_absolute_url)
|
||||
|
@ -18,7 +18,7 @@ from helpdesk.models import Queue, Ticket, FollowUp, Attachment
|
||||
from helpdesk.lib import send_templated_mail
|
||||
|
||||
def process_email():
|
||||
for q in Queue.objects.filter(email_box_type__isnull=False):
|
||||
for q in Queue.objects.filter(email_box_type__isnull=False, allow_email_submission=True):
|
||||
if not q.email_box_last_check: q.email_box_last_check = datetime.now()-timedelta(minutes=30)
|
||||
if not q.email_box_interval: q.email_box_interval = 0
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
<div id='header'>
|
||||
<h1>{% trans "Helpdesk" %}</h1>
|
||||
<ul>
|
||||
<li><a href='{% url helpdesk_home %}'>{% trans "Dashboard" %}</a></li>
|
||||
<li><a href='{% url helpdesk_dashboard %}'>{% trans "Dashboard" %}</a></li>
|
||||
<li><a href='{% url helpdesk_list %}'>{% trans "Tickets" %}</a></li>
|
||||
<li><a href='{% url helpdesk_submit %}'>{% trans "New Ticket" %}</a></li>
|
||||
<li><a href='{% url helpdesk_report_index %}'>{% trans "Stats" %}</a></li>
|
||||
|
20
templates/helpdesk/kb_category.html
Normal file
20
templates/helpdesk/kb_category.html
Normal file
@ -0,0 +1,20 @@
|
||||
{% extends "helpdesk/public_base.html" %}{% load i18n %}
|
||||
|
||||
{% block helpdesk_body %}
|
||||
<h2>{% blocktrans with category.title as kbcat %}Knowledgebase Category: {{ kbcat }}{% endblocktrans %}</h2>
|
||||
|
||||
<p>{% blocktrans with category.title as kbcat %}You are viewing all items in the {{ kbcat }} category.{% endblocktrans %}</p>
|
||||
|
||||
<p>{{ category.description }}</p>
|
||||
|
||||
<table width='100%'>
|
||||
<tr class='row_tablehead'><td colspan='3'>{% blocktrans with category.title as kbcat %}Knowledgebase Category: {{ kbcat }}{% endblocktrans %}</td></tr>
|
||||
<tr class='row_columnheads'><th colspan='3'>{% trans "Article" %}</th></tr>
|
||||
|
||||
{% for item in items %}
|
||||
<tr class='row_even row_hover'><th><a href='{{ item.get_absolute_url }}'>{{ item.title }}</a></th><td>{{ item.score }}</td><td>{{ item.last_updated|timesince }}</td></tr>
|
||||
<tr class='row_odd'><td colspan='3'>{{ item.question }}</td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
18
templates/helpdesk/kb_index.html
Normal file
18
templates/helpdesk/kb_index.html
Normal file
@ -0,0 +1,18 @@
|
||||
{% extends "helpdesk/public_base.html" %}{% load i18n %}
|
||||
|
||||
{% block helpdesk_body %}
|
||||
<h2>{% trans "Knowledgebase" %}</h2>
|
||||
|
||||
<p>{% trans "We have listed a number of knowledgebase articles for your perusal in the following categories. Please check to see if any of these articles address your problem prior to opening a support ticket." %}</p>
|
||||
|
||||
<table width='100%'>
|
||||
<tr class='row_tablehead'><td>{% trans "Knowledgebase Categories" %}</td></tr>
|
||||
<tr class='row_columnheads'><th>{% trans "Category" %}</th></tr>
|
||||
|
||||
{% for category in categories %}
|
||||
<tr class='row_even row_hover'><th><a href='{{ category.get_absolute_url }}'>{{ category.title }}</a></th></tr>
|
||||
<tr class='row_odd'><td>{{ category.description }}</td></tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
{% endblock %}
|
32
templates/helpdesk/kb_item.html
Normal file
32
templates/helpdesk/kb_item.html
Normal file
@ -0,0 +1,32 @@
|
||||
{% extends "helpdesk/public_base.html" %}{% load i18n %}
|
||||
|
||||
{% block helpdesk_body %}
|
||||
<h2>{% blocktrans with item.title as item %}Knowledgebase: {{ item }}{% endblocktrans %}</h2>
|
||||
|
||||
<table width='100%'>
|
||||
<tr class='row_tablehead'><td>{{ item.title }}</td></tr>
|
||||
|
||||
<tr class='row_even row_hover'><th>{{ item.question }}</th></tr>
|
||||
<tr class='row_odd'><td>{{ item.answer }}</td></tr>
|
||||
</table>
|
||||
|
||||
<p>{% blocktrans with item.category.title as category_title and item.category.get_absolute_url as category_url %}View <a href='{{ category_url }}'>other <em>{{ category_title }}</em> articles</a>, or continue <a href='../'>viewing other knowledgebase articles</a>.{% endblocktrans %}</p>
|
||||
|
||||
<h2>{% trans "Feedback" %}</h2>
|
||||
|
||||
<p>{% trans "We give our users an opportunity to vote for items that they believe have helped them out, in order for us to better serve future customers. We would appreciate your feedback on this article. Did you find it useful?" %}</p>
|
||||
|
||||
<ul>
|
||||
<li><a href='vote/?vote=up'>{% trans "This article was useful to me" %}</a></li>
|
||||
<li><a href='vote/?vote=down'>{% trans "This article was <strong>not</strong> useful to me" %}</a></li>
|
||||
</ul>
|
||||
|
||||
<p>{% trans "The results of voting by other readers of this article are below:" %}</p>
|
||||
|
||||
<ul>
|
||||
<li>{% blocktrans with item.recommendations as recommendations %}Recommendations: {{ recommendations }}{% endblocktrans %}</li>
|
||||
<li>{% blocktrans with item.votes as votes %}Votes: {{ votes }}{% endblocktrans %}</li>
|
||||
<li>{% blocktrans with item.score as score %}Overall Rating: {{ score }}{% endblocktrans %}</li>
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
@ -11,6 +11,7 @@
|
||||
<h1>{% trans "Helpdesk" %}</h1>
|
||||
<ul>
|
||||
<li><a href='{% url helpdesk_home %}'>{% trans "Submit A Ticket" %}</a></li>
|
||||
<li><a href='{% url helpdesk_kb_index %}'>{% trans "Knowledgebase" %}</a></li>
|
||||
<li><a href='{% url login %}'>{% trans "Log In" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -16,7 +16,7 @@
|
||||
<dd><input type='text' name='email' /></dd>
|
||||
</dl>
|
||||
|
||||
<input type='submit' value='{% "View Ticket" %}' />
|
||||
<input type='submit' value='{% trans "View Ticket" %}' />
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
|
@ -93,7 +93,7 @@
|
||||
{% if followup.comment %}{{ followup.comment|num_to_link|safe }}{% endif %}
|
||||
{% for change in followup.ticketchange_set.all %}
|
||||
{% if forloop.first %}<div class='changes'><ul>{% endif %}
|
||||
<li>{% blocktrans %}Changed {{ change.field }} from {{ change.old_value }} to {{ change.new_value }}.{% endblocktrans %}</li>
|
||||
<li>{% blocktrans with change.field as field and change.old_value as old_value and change.new_value as new_value %}Changed {{ field }} from {{ old_value }} to {{ new_value }}.{% endblocktrans %}</li>
|
||||
{% if forloop.last %}</div></ul>{% endif %}
|
||||
{% endfor %}
|
||||
{% for attachment in followup.attachment_set.all %}{% if forloop.first %}<div class='attachments'><ul>{% endif %}
|
||||
@ -116,7 +116,7 @@
|
||||
|
||||
<dt><label for='commentBox'>{% trans "Comment / Resolution" %}</label></dt>
|
||||
<dd><textarea rows='8' cols='70' name='comment' id='commentBox'></textarea></dd>
|
||||
<dd class='form_help_text'>{% trans "You can use the ticket and queue template variables in your message." %}</dd>
|
||||
<dd class='form_help_text'>{% trans "You can use the {{ ticket }} and {{ queue }} template variables in your message." %}</dd>
|
||||
|
||||
<dt><label>{% trans "New Status" %}</label></dt>
|
||||
{% ifequal ticket.status 1 %}
|
||||
|
42
urls.py
42
urls.py
@ -11,14 +11,14 @@ from django.conf.urls.defaults import *
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
from feeds import feed_setup
|
||||
from helpdesk.views.feeds import feed_setup
|
||||
|
||||
from django.contrib.syndication.views import feed as django_feed
|
||||
|
||||
urlpatterns = patterns('helpdesk.views',
|
||||
url(r'^$',
|
||||
urlpatterns = patterns('helpdesk.views.staff',
|
||||
url(r'^dashboard/$',
|
||||
'dashboard',
|
||||
name='helpdesk_home'),
|
||||
name='helpdesk_dashboard'),
|
||||
|
||||
url(r'^tickets/$',
|
||||
'ticket_list',
|
||||
@ -51,10 +51,6 @@ urlpatterns = patterns('helpdesk.views',
|
||||
url(r'^raw/(?P<type>\w+)/$',
|
||||
'raw_details',
|
||||
name='helpdesk_raw'),
|
||||
|
||||
url(r'^view/$',
|
||||
'public_view',
|
||||
name='helpdesk_public_view'),
|
||||
|
||||
url(r'^rss/$',
|
||||
'rss_list',
|
||||
@ -69,16 +65,24 @@ urlpatterns = patterns('helpdesk.views',
|
||||
name='helpdesk_run_report'),
|
||||
)
|
||||
|
||||
urlpatterns += patterns('helpdesk.views.public',
|
||||
url(r'^$',
|
||||
'homepage',
|
||||
name='helpdesk_home'),
|
||||
|
||||
url(r'^view/$',
|
||||
'view_ticket',
|
||||
name='helpdesk_public_view'),
|
||||
)
|
||||
|
||||
urlpatterns += patterns('',
|
||||
url(r'^rss/(?P<url>.*)/$',
|
||||
login_required(django_feed),
|
||||
{'feed_dict': feed_setup},
|
||||
name='helpdesk_rss'),
|
||||
)
|
||||
|
||||
urlpatterns += patterns('',
|
||||
|
||||
url(r'^api/(?P<method>[a-z_-]+)/$',
|
||||
'helpdesk.api.api',
|
||||
'helpdesk.views.api.api',
|
||||
name='helpdesk_api'),
|
||||
|
||||
url(r'^api/$',
|
||||
@ -94,3 +98,17 @@ urlpatterns += patterns('',
|
||||
'django.contrib.auth.views.logout',
|
||||
name='logout'),
|
||||
)
|
||||
|
||||
urlpatterns += patterns('helpdesk.views.kb',
|
||||
url(r'^kb/$',
|
||||
'index', name='helpdesk_kb_index'),
|
||||
|
||||
url(r'^kb/(?P<slug>[A-Za-z_-]+)/$',
|
||||
'category', name='helpdesk_kb_category'),
|
||||
|
||||
url(r'^kb/(?P<item>[0-9]+)/$',
|
||||
'item', name='helpdesk_kb_item'),
|
||||
|
||||
url(r'^kb/(?P<item>[0-9]+)/vote/$',
|
||||
'vote', name='helpdesk_kb_vote'),
|
||||
)
|
||||
|
0
views/__init__.py
Normal file
0
views/__init__.py
Normal file
@ -4,7 +4,7 @@ from django.core.urlresolvers import reverse
|
||||
from django.db.models import Q
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from models import Ticket, FollowUp, Queue
|
||||
from helpdesk.models import Ticket, FollowUp, Queue
|
||||
|
||||
|
||||
class OpenTicketsByUser(Feed):
|
52
views/kb.py
Normal file
52
views/kb.py
Normal file
@ -0,0 +1,52 @@
|
||||
"""
|
||||
Jutda Helpdesk - A Django powered ticket tracker for small enterprise.
|
||||
|
||||
(c) Copyright 2008 Jutda. All Rights Reserved. See LICENSE for details.
|
||||
|
||||
views/kb.py - Public-facing knowledgebase views. The knowledgebase is a
|
||||
simple categorised question/answer system to show common
|
||||
resolutions to common problems.
|
||||
"""
|
||||
from datetime import datetime
|
||||
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import render_to_response, get_object_or_404
|
||||
from django.template import RequestContext
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from helpdesk.models import KBCategory, KBItem
|
||||
|
||||
def index(request):
|
||||
category_list = KBCategory.objects.all()
|
||||
# Add most popular items here.
|
||||
return render_to_response('helpdesk/kb_index.html',
|
||||
RequestContext(request, {
|
||||
'categories': category_list,
|
||||
}))
|
||||
|
||||
def category(request, slug):
|
||||
category = get_object_or_404(KBCategory, slug__iexact=slug)
|
||||
items = category.kbitem_set.all()
|
||||
return render_to_response('helpdesk/kb_category.html',
|
||||
RequestContext(request, {
|
||||
'category': category,
|
||||
'items': items,
|
||||
}))
|
||||
|
||||
def item(request, item):
|
||||
item = get_object_or_404(KBItem, pk=item)
|
||||
return render_to_response('helpdesk/kb_item.html',
|
||||
RequestContext(request, {
|
||||
'item': item,
|
||||
}))
|
||||
|
||||
def vote(request, item):
|
||||
item = get_object_or_404(KBItem, pk=item)
|
||||
vote = request.GET.get('vote', None)
|
||||
if vote in ('up', 'down'):
|
||||
item.votes += 1
|
||||
if vote == 'up':
|
||||
item.recommendations += 1
|
||||
item.save()
|
||||
|
||||
return HttpResponseRedirect(item.get_absolute_url())
|
60
views/public.py
Normal file
60
views/public.py
Normal file
@ -0,0 +1,60 @@
|
||||
"""
|
||||
Jutda Helpdesk - A Django powered ticket tracker for small enterprise.
|
||||
|
||||
(c) Copyright 2008 Jutda. All Rights Reserved. See LICENSE for details.
|
||||
|
||||
views/public.py - All public facing views, eg non-staff (no authentication
|
||||
required) views.
|
||||
"""
|
||||
from datetime import datetime
|
||||
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import HttpResponseRedirect, Http404, HttpResponse
|
||||
from django.shortcuts import render_to_response, get_object_or_404
|
||||
from django.template import loader, Context, RequestContext
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from helpdesk.forms import PublicTicketForm
|
||||
from helpdesk.lib import send_templated_mail
|
||||
from helpdesk.models import Ticket, Queue
|
||||
|
||||
def homepage(request):
|
||||
if request.user.is_authenticated():
|
||||
return HttpResponseRedirect(reverse('helpdesk_dashboard'))
|
||||
|
||||
if request.method == 'POST':
|
||||
form = PublicTicketForm(request.POST)
|
||||
form.fields['queue'].choices = [('', '--------')] + [[q.id, q.title] for q in Queue.objects.filter(allow_public_submission=True)]
|
||||
if form.is_valid():
|
||||
ticket = form.save()
|
||||
return HttpResponseRedirect('%s?ticket=%s&email=%s'% (reverse('helpdesk_public_view'), ticket.ticket_for_url, ticket.submitter_email))
|
||||
else:
|
||||
form = PublicTicketForm()
|
||||
form.fields['queue'].choices = [('', '--------')] + [[q.id, q.title] for q in Queue.objects.filter(allow_public_submission=True)]
|
||||
|
||||
return render_to_response('helpdesk/public_homepage.html',
|
||||
RequestContext(request, {
|
||||
'form': form,
|
||||
}))
|
||||
|
||||
def view_ticket(request):
|
||||
ticket = request.GET.get('ticket', '')
|
||||
email = request.GET.get('email', '')
|
||||
error_message = ''
|
||||
|
||||
if ticket and email:
|
||||
try:
|
||||
queue, ticket_id = ticket.split('-')
|
||||
t = Ticket.objects.get(id=ticket_id, queue__slug__iexact=queue, submitter_email__iexact=email)
|
||||
return render_to_response('helpdesk/public_view_ticket.html',
|
||||
RequestContext(request, {'ticket': t,}))
|
||||
except:
|
||||
t = False;
|
||||
error_message = _('Invalid ticket ID or e-mail address. Please try again.')
|
||||
|
||||
return render_to_response('helpdesk/public_view_form.html',
|
||||
RequestContext(request, {
|
||||
'ticket': ticket,
|
||||
'email': email,
|
||||
'error_message': error_message,
|
||||
}))
|
@ -3,8 +3,8 @@ Jutda Helpdesk - A Django powered ticket tracker for small enterprise.
|
||||
|
||||
(c) Copyright 2008 Jutda. All Rights Reserved. See LICENSE for details.
|
||||
|
||||
views.py - The bulk of the application - provides most business logic and
|
||||
renders all user-facing views.
|
||||
views/staff.py - The bulk of the application - provides most business logic and
|
||||
renders all staff-facing views.
|
||||
"""
|
||||
from datetime import datetime
|
||||
|
||||
@ -17,57 +17,42 @@ from django.shortcuts import render_to_response, get_object_or_404
|
||||
from django.template import loader, Context, RequestContext
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from helpdesk.forms import TicketForm, PublicTicketForm
|
||||
from helpdesk.forms import TicketForm
|
||||
from helpdesk.lib import send_templated_mail, line_chart, bar_chart, query_to_dict
|
||||
from helpdesk.models import Ticket, Queue, FollowUp, TicketChange, PreSetReply, Attachment
|
||||
|
||||
def dashboard(request):
|
||||
"""
|
||||
This isn't always truly a "dashboard" view. If the user is not logged in,
|
||||
we instead show the user a "public submission" form and a way to view
|
||||
existing tickets.
|
||||
A quick summary overview for users: A list of their own tickets, a table
|
||||
showing ticket counts by queue/status, and a list of unassigned tickets
|
||||
with options for them to 'Take' ownership of said tickets.
|
||||
"""
|
||||
if request.user.is_authenticated():
|
||||
tickets = Ticket.objects.filter(assigned_to=request.user).exclude(status=Ticket.CLOSED_STATUS)
|
||||
unassigned_tickets = Ticket.objects.filter(assigned_to__isnull=True).exclude(status=Ticket.CLOSED_STATUS)
|
||||
|
||||
from django.db import connection
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("""
|
||||
SELECT q.id as queue,
|
||||
q.title AS name,
|
||||
COUNT(CASE t.status WHEN '1' THEN t.id WHEN '2' THEN t.id END) AS open,
|
||||
COUNT(CASE t.status WHEN '3' THEN t.id END) AS resolved
|
||||
FROM helpdesk_ticket t,
|
||||
helpdesk_queue q
|
||||
WHERE q.id = t.queue_id
|
||||
GROUP BY queue, name
|
||||
ORDER BY q.id;
|
||||
""")
|
||||
dash_tickets = query_to_dict(cursor.fetchall(), cursor.description)
|
||||
|
||||
return render_to_response('helpdesk/dashboard.html',
|
||||
RequestContext(request, {
|
||||
'user_tickets': tickets,
|
||||
'unassigned_tickets': unassigned_tickets,
|
||||
'dash_tickets': dash_tickets,
|
||||
}))
|
||||
else:
|
||||
# Not a logged in user
|
||||
if request.method == 'POST':
|
||||
form = PublicTicketForm(request.POST)
|
||||
form.fields['queue'].choices = [('', '--------')] + [[q.id, q.title] for q in Queue.objects.all()]
|
||||
if form.is_valid():
|
||||
ticket = form.save()
|
||||
return HttpResponseRedirect('%s?ticket=%s&email=%s'% (reverse('helpdesk_public_view'), ticket.ticket_for_url, ticket.submitter_email))
|
||||
else:
|
||||
form = PublicTicketForm()
|
||||
form.fields['queue'].choices = [('', '--------')] + [[q.id, q.title] for q in Queue.objects.all()]
|
||||
tickets = Ticket.objects.filter(assigned_to=request.user).exclude(status=Ticket.CLOSED_STATUS)
|
||||
unassigned_tickets = Ticket.objects.filter(assigned_to__isnull=True).exclude(status=Ticket.CLOSED_STATUS)
|
||||
|
||||
return render_to_response('helpdesk/public_homepage.html',
|
||||
RequestContext(request, {
|
||||
'form': form,
|
||||
}))
|
||||
from django.db import connection
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("""
|
||||
SELECT q.id as queue,
|
||||
q.title AS name,
|
||||
COUNT(CASE t.status WHEN '1' THEN t.id WHEN '2' THEN t.id END) AS open,
|
||||
COUNT(CASE t.status WHEN '3' THEN t.id END) AS resolved
|
||||
FROM helpdesk_ticket t,
|
||||
helpdesk_queue q
|
||||
WHERE q.id = t.queue_id
|
||||
GROUP BY queue, name
|
||||
ORDER BY q.id;
|
||||
""")
|
||||
dash_tickets = query_to_dict(cursor.fetchall(), cursor.description)
|
||||
|
||||
return render_to_response('helpdesk/dashboard.html',
|
||||
RequestContext(request, {
|
||||
'user_tickets': tickets,
|
||||
'unassigned_tickets': unassigned_tickets,
|
||||
'dash_tickets': dash_tickets,
|
||||
}))
|
||||
dashboard = login_required(dashboard)
|
||||
|
||||
def delete_ticket(request, ticket_id):
|
||||
ticket = get_object_or_404(Ticket, id=ticket_id)
|
||||
@ -303,28 +288,6 @@ def raw_details(request, type):
|
||||
raise Http404
|
||||
raw_details = login_required(raw_details)
|
||||
|
||||
def public_view(request):
|
||||
ticket = request.GET.get('ticket', '')
|
||||
email = request.GET.get('email', '')
|
||||
error_message = ''
|
||||
|
||||
if ticket and email:
|
||||
queue, ticket_id = ticket.split('-')
|
||||
try:
|
||||
t = Ticket.objects.get(id=ticket_id, queue__slug__iexact=queue, submitter_email__iexact=email)
|
||||
return render_to_response('helpdesk/public_view_ticket.html',
|
||||
RequestContext(request, {'ticket': t,}))
|
||||
except:
|
||||
t = False;
|
||||
error_message = _('Invalid ticket ID or e-mail address. Please try again.')
|
||||
|
||||
return render_to_response('helpdesk/public_view_form.html',
|
||||
RequestContext(request, {
|
||||
'ticket': ticket,
|
||||
'email': email,
|
||||
'error_message': error_message,
|
||||
}))
|
||||
|
||||
def hold_ticket(request, ticket_id, unhold=False):
|
||||
ticket = get_object_or_404(Ticket, id=ticket_id)
|
||||
|
Loading…
Reference in New Issue
Block a user