forked from extern/django-helpdesk
make django-helpdesk more customizable + bug fixes:
- look at settings.py for all new options regarding customization. - settings can be accessed inside the templates via the new templatetag 'load_helpdesk_settings' - allow editing of personal followups, but only if followup does not contain any ticketchanges - otherwise this information is lost after the editing. - add 'delete' link to attachments - link to list of closed tickets in queue overview - add 'closed & resolved' section to dashboard - hide 'pre-set reply' box if no pre-set replies are found. - use 'SelectDateWidget' for custom DateField - fix how we update followups so that attachments don't get deleted - fix bug where resolution emails contained the solution 'None' - fix stats crashing bug - fix locale bug
This commit is contained in:
parent
6e33408a7d
commit
cb34b1933a
@ -11,6 +11,7 @@ from datetime import datetime
|
||||
from StringIO import StringIO
|
||||
|
||||
from django import forms
|
||||
from django.forms import extras
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.translation import ugettext as _
|
||||
@ -195,6 +196,7 @@ class TicketForm(forms.Form):
|
||||
fieldclass = forms.BooleanField
|
||||
elif field.data_type == 'date':
|
||||
fieldclass = forms.DateField
|
||||
instanceargs['widget'] = extras.SelectDateWidget
|
||||
elif field.data_type == 'time':
|
||||
fieldclass = forms.TimeField
|
||||
elif field.data_type == 'datetime':
|
||||
|
@ -54,7 +54,13 @@ def send_templated_mail(template_name, email_context, recipients, sender=None, b
|
||||
import os
|
||||
|
||||
context = Context(email_context)
|
||||
locale = context['queue'].get('locale', 'en')
|
||||
|
||||
if hasattr(context['queue'], 'locale'):
|
||||
locale = getattr(context['queue'], 'locale', '')
|
||||
else:
|
||||
locale = context['queue'].get('locale', 'en')
|
||||
if not locale:
|
||||
locale = 'en'
|
||||
|
||||
t = None
|
||||
try:
|
||||
|
@ -28,5 +28,59 @@ if type(DEFAULT_USER_SETTINGS) != type(dict()):
|
||||
'tickets_per_page': 25
|
||||
}
|
||||
|
||||
''' generic options - visible on all pages '''
|
||||
# redirect to login page instead of the default homepage when users visits "/"?
|
||||
HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT = getattr(settings, 'HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT', False)
|
||||
|
||||
# show knowledgebase links?
|
||||
HELPDESK_KB_ENABLED = getattr(settings, 'HELPDESK_KB_ENABLED', True)
|
||||
|
||||
# show extended navigation by default, to all users, irrespective of staff status?
|
||||
HELPDESK_NAVIGATION_ENABLED = getattr(settings, 'HELPDESK_NAVIGATION_ENABLED', False)
|
||||
|
||||
# show 'stats' link in navigation bar?
|
||||
HELPDESK_NAVIGATION_STATS_ENABLED = getattr(settings, 'HELPDESK_NAVIGATION_STATS_ENABLED', True)
|
||||
|
||||
# set this to an email address inside your organization and a footer below
|
||||
# the 'Powered by django-helpdesk' will be shown, telling the user whom to contact
|
||||
# in case they have technical problems.
|
||||
HELPDESK_SUPPORT_PERSON = getattr(settings, 'HELPDESK_SUPPORT_PERSON', False)
|
||||
|
||||
|
||||
''' options for public pages '''
|
||||
# show 'view a ticket' section on public page?
|
||||
HELPDESK_VIEW_A_TICKET_PUBLIC = getattr(settings, 'HELPDESK_VIEW_A_TICKET_PUBLIC', True)
|
||||
|
||||
# show 'submit a ticket' section on public page?
|
||||
HELPDESK_SUBMIT_A_TICKET_PUBLIC = getattr(settings, 'HELPDESK_SUBMIT_A_TICKET_PUBLIC', True)
|
||||
|
||||
|
||||
''' options for update_ticket views '''
|
||||
# allow non-staff users to interact with tickets? this will also change how 'staff_member_required'
|
||||
# in staff.py will be defined.
|
||||
HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = getattr(settings, 'HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE', False)
|
||||
|
||||
# show edit buttons in ticket follow ups.
|
||||
HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP = getattr(settings, 'HELPDESK_HIDE_EDIT_BUTTON_FOLLOW_UP', True)
|
||||
|
||||
# show ticket edit button on top of ticket description.
|
||||
HELPDESK_SHOW_EDIT_BUTTON_TICKET_TOP = getattr(settings, 'HELPDESK_SHOW_EDIT_BUTTON_TICKET_TOP', True)
|
||||
|
||||
# show ticket delete button on top of ticket description.
|
||||
HELPDESK_SHOW_DELETE_BUTTON_TICKET_TOP = getattr(settings, 'HELPDESK_SHOW_DELETE_BUTTON_TICKET_TOP', True)
|
||||
|
||||
# show hold / unhold button on top of ticket description.
|
||||
HELPDESK_SHOW_HOLD_BUTTON_TICKET_TOP = getattr(settings, 'HELPDESK_SHOW_HOLD_BUTTON_TICKET_TOP', True)
|
||||
|
||||
# make all updates public by default? this will hide the 'is this update public' checkbox
|
||||
HELPDESK_UPDATE_PUBLIC_DEFAULT = getattr(settings, 'HELPDESK_UPDATE_PUBLIC_DEFAULT', True)
|
||||
|
||||
|
||||
''' options for dashboard '''
|
||||
# show delete button next to unassigned tickets
|
||||
HELPDESK_DASHBOARD_SHOW_DELETE_UNASSIGNED = getattr(settings, 'HELPDESK_DASHBOARD_SHOW_DELETE_UNASSIGNED', True)
|
||||
|
||||
|
||||
''' options for footer '''
|
||||
# show 'API' link at bottom of page
|
||||
HELPDESK_FOOTER_SHOW_API_LINK = getattr(settings, 'HELPDESK_FOOTER_SHOW_API_LINK', True)
|
||||
|
@ -1,2 +1,5 @@
|
||||
{% load i18n %}
|
||||
{% trans "Powered by <a href='https://github.com/rossp/django-helpdesk'>django-helpdesk</a>." %}
|
||||
{% trans "Powered by <a href='https://github.com/rossp/django-helpdesk'>django-helpdesk</a>." %}
|
||||
{% if helpdesk_settings.HELPDESK_SUPPORT_PERSON %}
|
||||
<p>{% trans "For technical support please contact:" %} <a href='mailto:{{ helpdesk_settings.HELPDESK_SUPPORT_PERSON }}'>{{ helpdesk_settings.HELPDESK_SUPPORT_PERSON }}</a></p>
|
||||
{% endif %}
|
||||
|
@ -1,5 +1,7 @@
|
||||
{% load i18n %}
|
||||
{% load saved_queries %}
|
||||
{% load load_helpdesk_settings %}
|
||||
{% with request|load_helpdesk_settings as helpdesk_settings %}
|
||||
{% with request|saved_queries as user_saved_queries_ %}
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
@ -51,10 +53,15 @@
|
||||
</div>
|
||||
|
||||
<div id='footer'>
|
||||
<p>{% include "helpdesk/attribution.html" %}<a href='{% url helpdesk_rss_index %}'><img src='{{ STATIC_URL }}helpdesk/rss_icon.png' width='14' height='14' alt='{% trans "RSS Icon" %}' title='{% trans "RSS Feeds" %}' border='0' />{% trans "RSS Feeds" %}</a> <a href='{% url helpdesk_api_help %}'>{% trans "API" %}</a> <a href='{% url helpdesk_user_settings %}'>{% trans "User Settings" %}</a> {% if user.is_superuser %}<a href='{% url helpdesk_system_settings %}'>{% trans "System Settings" %}</a>{% endif %}</p>
|
||||
<p>{% include "helpdesk/attribution.html" %}
|
||||
<a href='{% url helpdesk_rss_index %}'><img src='{{ STATIC_URL }}helpdesk/rss_icon.png' width='14' height='14' alt='{% trans "RSS Icon" %}' title='{% trans "RSS Feeds" %}' border='0' />{% trans "RSS Feeds" %}</a>
|
||||
{% if helpdesk_settings.HELPDESK_FOOTER_SHOW_API_LINK %}<a href='{% url helpdesk_api_help %}'>{% trans "API" %}</a>{% endif %}
|
||||
<a href='{% url helpdesk_user_settings %}'>{% trans "User Settings" %}</a>
|
||||
{% if user.is_superuser %}<a href='{% url helpdesk_system_settings %}'>{% trans "System Settings" %}</a>{% endif %}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% include "helpdesk/debug.html" %}
|
||||
</body>
|
||||
</html>
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
|
@ -6,13 +6,14 @@
|
||||
{% block helpdesk_body %}
|
||||
|
||||
<table width='40%' align='left'>
|
||||
<tr class='row_tablehead'><td colspan='4'>{% trans "Helpdesk Summary" %}</td></tr>
|
||||
<tr class='row_columnheads'><th>{% trans "Queue" %}</th><th>{% trans "Open" %}</th><th>{% trans "Resolved" %}</th></tr>
|
||||
<tr class='row_tablehead'><td colspan='5'>{% trans "Helpdesk Summary" %}</td></tr>
|
||||
<tr class='row_columnheads'><th>{% trans "Queue" %}</th><th>{% trans "Open" %}</th><th>{% trans "Resolved" %}</th><th>{% trans "Closed" %}</th></tr>
|
||||
{% for queue in dash_tickets %}
|
||||
<tr class='row_{% cycle odd,even %} row_hover '>
|
||||
<th><a href='{% url helpdesk_list %}?queue={{ queue.queue }}&status=1&status=2'>{{ queue.name }}</a></th>
|
||||
<td>{% if queue.open %}<a href='{% url helpdesk_list %}?queue={{ queue.queue }}&status=1&status=2'>{% endif %}{{ queue.open }}{% if queue.open %}</a>{% endif %}</td>
|
||||
<td>{% if queue.resolved %}<a href='{% url helpdesk_list %}?queue={{ queue.queue }}&status=3'>{% endif %}{{ queue.resolved }}{% if queue.resolved %}</a>{% endif %}</td>
|
||||
<td align="center">{% if queue.open %}<a href='{% url helpdesk_list %}?queue={{ queue.queue }}&status=1&status=2'>{% endif %}{{ queue.open }}{% if queue.open %}</a>{% endif %}</td>
|
||||
<td align="center">{% if queue.resolved %}<a href='{% url helpdesk_list %}?queue={{ queue.queue }}&status=3'>{% endif %}{{ queue.resolved }}{% if queue.resolved %}</a>{% endif %}</td>
|
||||
<td align="center">{% if queue.closed %}<a href='{% url helpdesk_list %}?queue={{ queue.queue }}&status=4'>{% endif %}{{ queue.closed }}{% if queue.closed %}</a>{% endif %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
@ -22,7 +23,7 @@
|
||||
<br style='clear: both;' />
|
||||
|
||||
<table width='100%'>
|
||||
<tr class='row_tablehead'><td colspan='6'>{% trans "Your Tickets" %}</td></tr>
|
||||
<tr class='row_tablehead'><td colspan='6'>{% trans "Your Open Tickets" %}</td></tr>
|
||||
<tr class='row_columnheads'><th>#</th><th>{% trans "Pr" %}</th><th>{% trans "Title" %}</th><th>{% trans "Queue" %}</th><th>{% trans "Status" %}</th><th>{% trans "Last Update" %}</th></tr>
|
||||
{% for ticket in user_tickets %}
|
||||
<tr class='row_{% cycle odd,even %} row_hover'>
|
||||
@ -39,6 +40,8 @@
|
||||
{% endif %}
|
||||
</table>
|
||||
|
||||
<br style='clear: both;' />
|
||||
|
||||
<table width='100%'>
|
||||
<tr class='row_tablehead'><td colspan='6'>{% trans "Unassigned Tickets" %}</td></tr>
|
||||
<tr class='row_columnheads'><th>#</th><th>{% trans "Pr" %}</th><th>{% trans "Title" %}</th><th>{% trans "Queue" %}</th><th>{% trans "Created" %}</th><th> </th></tr>
|
||||
@ -49,7 +52,7 @@
|
||||
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.title }}</a></th>
|
||||
<td>{{ ticket.queue }}</td>
|
||||
<td><span title='{{ ticket.created|date:"r" }}'>{{ ticket.created|timesince }} ago</span></td>
|
||||
<th><a href='{{ ticket.get_absolute_url }}?take'><span class='button button_take'>{% trans "Take" %}</span></a> | <a href='{% url helpdesk_delete ticket.id %}'><span class='button button_delete'>{% trans "Delete" %}</span></a></th>
|
||||
<th><a href='{{ ticket.get_absolute_url }}?take'><span class='button button_take'>{% trans "Take" %}</span></a> {% if helpdesk_settings.HELPDESK_DASHBOARD_SHOW_DELETE_UNASSIGNED %}| <a href='{% url helpdesk_delete ticket.id %}'><span class='button button_delete'>{% trans "Delete" %}</span></a>{% endif %}</th>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if not unassigned_tickets %}
|
||||
@ -57,4 +60,24 @@
|
||||
{% endif %}
|
||||
</table>
|
||||
|
||||
|
||||
{% if user_tickets_closed_resolved %}
|
||||
<br style='clear: both;' />
|
||||
|
||||
<table width='100%'>
|
||||
<tr class='row_tablehead'><td colspan='6'>{% trans "Your closed & resolved Tickets" %}</td></tr>
|
||||
<tr class='row_columnheads'><th>#</th><th>{% trans "Pr" %}</th><th>{% trans "Title" %}</th><th>{% trans "Queue" %}</th><th>{% trans "Status" %}</th><th>{% trans "Last Update" %}</th></tr>
|
||||
{% for ticket in user_tickets_closed_resolved %}
|
||||
<tr class='row_{% cycle odd,even %} row_hover'>
|
||||
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.ticket }}</a></th>
|
||||
<td>{{ ticket.get_priority_span }}</td>
|
||||
<th><a href='{{ ticket.get_absolute_url }}'>{{ ticket.title }}</a></th>
|
||||
<td>{{ ticket.queue }}</td>
|
||||
<td>{{ ticket.get_status }}</td>
|
||||
<td><span title='{{ ticket.modified|date:"r" }}'>{{ ticket.modified|timesince }}</span></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
@ -1,10 +1,12 @@
|
||||
{% load i18n %}
|
||||
{% if user.is_staff %}
|
||||
{% if helpdesk_settings.HELPDESK_NAVIGATION_ENABLED and user.is_authenticated or user.is_staff %}
|
||||
<ul id="dropdown">
|
||||
<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>
|
||||
{% if helpdesk_settings.HELPDESK_NAVIGATION_STATS_ENABLED %}
|
||||
<li><a href='{% url helpdesk_report_index %}'>{% trans "Stats" %}</a></li>
|
||||
{% endif %}
|
||||
{% if user_saved_queries_ %}
|
||||
<li class="headerlink"><a>Load Saved Query</a>
|
||||
<ul>
|
||||
@ -22,8 +24,12 @@
|
||||
</ul>
|
||||
{% else %}
|
||||
<ul>
|
||||
{% if helpdesk_settings.HELPDESK_SUBMIT_A_TICKET_PUBLIC %}
|
||||
<li><a href='{% url helpdesk_home %}'>{% trans "Submit A Ticket" %}</a></li>
|
||||
{% endif %}
|
||||
{% if helpdesk_settings.HELPDESK_KB_ENABLED %}<li><a href='{% url helpdesk_kb_index %}'>{% trans "Knowledgebase" %}</a></li>{% endif %}
|
||||
<li><a href='{% url login %}?next={% url helpdesk_dashboard %}'>{% trans "Log In" %}</a></li>
|
||||
{% if not helpdesk_settings.HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT or user.is_authenticated %}
|
||||
<li>{% if user.is_authenticated %}<a href='{% url logout %}'>{% trans "Logout" %}</a>{% else %}<a href='{% url login %}?next={% url helpdesk_dashboard %}'>{% trans "Log In" %}</a>{% endif %}</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
@ -1,4 +1,7 @@
|
||||
{% load i18n %}<html>
|
||||
{% load i18n %}
|
||||
{% load load_helpdesk_settings %}
|
||||
{% with request|load_helpdesk_settings as helpdesk_settings %}
|
||||
<html>
|
||||
<head>
|
||||
<title>{% block helpdesk_title %}{% trans "Helpdesk" %}{% endblock %}</title>
|
||||
<script src='{{ STATIC_URL }}helpdesk/jquery-1.5.min.js' type='text/javascript' language='javascript'></script>
|
||||
@ -19,4 +22,5 @@
|
||||
</div>
|
||||
</div>{% include "helpdesk/debug.html" %}
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
{% endwith %}
|
||||
|
@ -1,6 +1,7 @@
|
||||
{% extends "helpdesk/public_base.html" %}{% load i18n %}
|
||||
|
||||
{% block helpdesk_body %}
|
||||
{% if helpdesk_settings.HELPDESK_VIEW_A_TICKET_PUBLIC %}
|
||||
<h2>{% trans "View a Ticket" %}</h2>
|
||||
|
||||
<form method='get' action='{% url helpdesk_public_view %}'>
|
||||
@ -16,7 +17,9 @@
|
||||
<input type='submit' value='{% trans "View Ticket" %}' />
|
||||
</fieldset>
|
||||
{% csrf_token %}</form>
|
||||
{% endif %}
|
||||
|
||||
{% if helpdesk_settings.HELPDESK_SUBMIT_A_TICKET_PUBLIC %}
|
||||
<h2 name='submit'>{% trans "Submit a Ticket" %}</h2>
|
||||
|
||||
<p>{% trans "All fields are required. Please provide as descriptive a title and description as possible." %}</p>
|
||||
@ -42,4 +45,10 @@
|
||||
</fieldset>
|
||||
|
||||
{% csrf_token %}</form>
|
||||
{% endif %}
|
||||
|
||||
{% if not helpdesk_settings.HELPDESK_VIEW_A_TICKET_PUBLIC and not helpdesk_settings.HELPDESK_SUBMIT_A_TICKET_PUBLIC %}
|
||||
<h2>{% trans "Please use button at upper right to login first." %}</h2>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
@ -51,7 +51,11 @@
|
||||
<div class='followup'>
|
||||
<div class='title'>
|
||||
{{ followup.title }} <span class='byline'>{% if followup.user %}by {{ followup.user }}{% endif %} <span title='{{ followup.date|date:"r" }}'>{{ followup.date|timesince }} ago</span>{% if not followup.public %} <span class='private'>({% trans "Private" %})</span>{% endif %}</span>
|
||||
{% if helpdesk_settings.HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP %}
|
||||
{% if followup.user and request.user == followup.user and not followup.ticketchange_set.all %}
|
||||
<a href="{% url helpdesk_followup_edit ticket.id followup.id %}" class='followup-edit'><img width="60" height="15" title="Edit" alt="Edit" src="{{ STATIC_URL }}helpdesk/buttons/edit.png"></a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<span class='followup-desc'>{% if followup.comment %}{{ followup.comment|force_escape|urlizetrunc:50|num_to_link|linebreaksbr }}{% endif %}</span>
|
||||
{% for change in followup.ticketchange_set.all %}
|
||||
@ -60,7 +64,11 @@
|
||||
{% if forloop.last %}</div></ul>{% endif %}
|
||||
{% endfor %}
|
||||
{% for attachment in followup.attachment_set.all %}{% if forloop.first %}<div class='attachments'><ul>{% endif %}
|
||||
<li><a href='{{ attachment.file.url }}'>{{ attachment.filename }}</a> ({{ attachment.mime_type }}, {{ attachment.size|filesizeformat }})</li>
|
||||
<li><a href='{{ attachment.file.url }}'>{{ attachment.filename }}</a> ({{ attachment.mime_type }}, {{ attachment.size|filesizeformat }})
|
||||
{% if followup.user and request.user == followup.user %}
|
||||
<a href='{% url helpdesk_attachment_del ticket.id attachment.id %}'>delete</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% if forloop.last %}</ul></div>{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
@ -73,9 +81,11 @@
|
||||
|
||||
<fieldset>
|
||||
<dl>
|
||||
{% if preset_replies %}
|
||||
<dt><label for='id_preset'>{% trans "Use a Pre-set Reply" %}</label> <span class='form_optional'>(Optional)</span></dt>
|
||||
<dd><select name='preset' id='id_preset'><option value=''>------</option>{% for preset in preset_replies %}<option value='{{ preset.id }}'>{{ preset.name }}</option>{% endfor %}</select></dd>
|
||||
<dd class='form_help_text'>{% trans "Selecting a pre-set reply will over-write your comment below. You can then modify the pre-set reply to your liking before saving this update." %}</dd>
|
||||
{% endif %}
|
||||
|
||||
<dt><label for='commentBox'>{% trans "Comment / Resolution" %}</label></dt>
|
||||
<dd><textarea rows='8' cols='70' name='comment' id='commentBox'></textarea></dd>
|
||||
@ -109,9 +119,13 @@
|
||||
<input type='radio' name='new_status' value='5' id='st_duplicate' checked='checked'><label for='st_duplicate'>{% trans "Duplicate" %}</label></dd>
|
||||
{% endifequal %}
|
||||
|
||||
{% if helpdesk_settings.HELPDESK_UPDATE_PUBLIC_DEFAULT %}
|
||||
<input type='hidden' name='public' value='1'>
|
||||
{% else %}
|
||||
<dt><label for='id_public'>{% trans "Is this update public?" %}</label> <span class='form_optional'>(Optional)</span></dt>
|
||||
<dd><input type='checkbox' name='public' value='1' checked='checked' /></dD>
|
||||
<dd><input type='checkbox' name='public' value='1' checked='checked' /></dd>
|
||||
<dd class='form_help_text'>{% trans "If this is public, the submitter will be e-mailed your comment or resolution." %}</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
|
||||
<p id='ShowFurtherOptPara'><a href='#' id='ShowFurtherEditOptions'>{% trans "Change Further Details »" %}</a></p>
|
||||
|
@ -1,6 +1,15 @@
|
||||
{% load i18n %}
|
||||
<table width='100%'>
|
||||
<tr class='row_tablehead'><td colspan='2'>{{ ticket.id }}. {{ ticket.title }} [{{ ticket.get_status }}] <span class='ticket_toolbar'><a href='{% url helpdesk_edit ticket.id %}'><img src='{{ STATIC_URL }}helpdesk/buttons/edit.png' alt='Edit' title='Edit' width='60' height='15' /></a><a href='{% url helpdesk_delete ticket.id %}'><img src='{{ STATIC_URL }}helpdesk/buttons/delete.png' alt='Delete' title='Delete' width='60' height='15' /></a>{% if ticket.on_hold %}<a href='unhold/'>{% trans "Unhold" %}</a>{% else %}<a href='hold/'>{% trans "Hold" %}</a>{% endif %}</span></td></tr>
|
||||
<tr class='row_tablehead'><td colspan='2'>{{ ticket.id }}. {{ ticket.title }} [{{ ticket.get_status }}] <span class='ticket_toolbar'>
|
||||
{% if helpdesk_settings.HELPDESK_SHOW_EDIT_BUTTON_TICKET_TOP %}
|
||||
<a href='{% url helpdesk_edit ticket.id %}'><img src='{{ STATIC_URL }}helpdesk/buttons/edit.png' alt='Edit' title='Edit' width='60' height='15' /></a>
|
||||
{% endif %}
|
||||
{% if helpdesk_settings.HELPDESK_SHOW_DELETE_BUTTON_TICKET_TOP %}
|
||||
<a href='{% url helpdesk_delete ticket.id %}'><img src='{{ STATIC_URL }}helpdesk/buttons/delete.png' alt='Delete' title='Delete' width='60' height='15' /></a>
|
||||
{% endif %}
|
||||
{% if helpdesk_settings.HELPDESK_SHOW_HOLD_BUTTON_TICKET_TOP %}
|
||||
{% if ticket.on_hold %}<a href='unhold/'>{% trans "Unhold" %}</a>{% else %}<a href='hold/'>{% trans "Hold" %}</a>{% endif %}
|
||||
{% endif %}</span></td></tr>
|
||||
<tr class='row_columnheads'><th colspan='2'>{% blocktrans with ticket.queue as queue %}Queue: {{ queue }}{% endblocktrans %}</th></tr>
|
||||
|
||||
<tr class='{% cycle 'row_odd' 'row_even' as rowcolors %}'>
|
||||
|
21
helpdesk/templatetags/load_helpdesk_settings.py
Normal file
21
helpdesk/templatetags/load_helpdesk_settings.py
Normal file
@ -0,0 +1,21 @@
|
||||
"""
|
||||
django-helpdesk - A Django powered ticket tracker for small enterprise.
|
||||
|
||||
templatetags/load_helpdesk_settings.py - returns the settings as defined in
|
||||
django-helpdesk/helpdesk/settings.py
|
||||
"""
|
||||
|
||||
from django.template import Library
|
||||
from helpdesk import settings as helpdesk_settings_config
|
||||
|
||||
def load_helpdesk_settings(request):
|
||||
try:
|
||||
return helpdesk_settings_config
|
||||
except Exception, e:
|
||||
import sys
|
||||
print >> sys.stderr, "'load_helpdesk_settings' template tag (django-helpdesk) crashed with following error:"
|
||||
print >> sys.stderr, e
|
||||
return ''
|
||||
|
||||
register = Library()
|
||||
register.filter('load_helpdesk_settings', load_helpdesk_settings)
|
@ -80,6 +80,10 @@ urlpatterns = patterns('helpdesk.views.staff',
|
||||
url(r'^tickets/(?P<ticket_id>[0-9]+)/dependency/delete/(?P<dependency_id>[0-9]+)/$',
|
||||
'ticket_dependency_del',
|
||||
name='helpdesk_ticket_dependency_del'),
|
||||
|
||||
url(r'^tickets/(?P<ticket_id>[0-9]+)/attachment_delete/(?P<attachment_id>[0-9]+)/$',
|
||||
'attachment_del',
|
||||
name='helpdesk_attachment_del'),
|
||||
|
||||
url(r'^raw/(?P<type>\w+)/$',
|
||||
'raw_details',
|
||||
|
@ -22,7 +22,10 @@ from helpdesk.models import Ticket, Queue, UserSettings
|
||||
|
||||
|
||||
def homepage(request):
|
||||
if request.user.is_staff:
|
||||
if not request.user.is_authenticated() and helpdesk_settings.HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT:
|
||||
return HttpResponseRedirect(reverse('login'))
|
||||
|
||||
if (request.user.is_staff or (request.user.is_authenticated() and helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE)):
|
||||
try:
|
||||
if getattr(request.user.usersettings.settings, 'login_view_ticketlist', False):
|
||||
return HttpResponseRedirect(reverse('helpdesk_list'))
|
||||
|
@ -28,14 +28,20 @@ from helpdesk.forms import TicketForm, UserSettingsForm, EmailIgnoreForm, EditTi
|
||||
from helpdesk.lib import send_templated_mail, query_to_dict, apply_query, safe_template_context
|
||||
from helpdesk.models import Ticket, Queue, FollowUp, TicketChange, PreSetReply, Attachment, SavedSearch, IgnoreEmail, TicketCC, TicketDependency
|
||||
from helpdesk.settings import HAS_TAG_SUPPORT
|
||||
from helpdesk import settings as helpdesk_settings
|
||||
|
||||
if HAS_TAG_SUPPORT:
|
||||
from tagging.models import Tag, TaggedItem
|
||||
|
||||
staff_member_required = user_passes_test(lambda u: u.is_authenticated() and u.is_active and u.is_staff)
|
||||
superuser_required = user_passes_test(lambda u: u.is_authenticated() and u.is_active and u.is_superuser)
|
||||
if helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE:
|
||||
# treat 'normal' users like 'staff'
|
||||
staff_member_required = user_passes_test(lambda u: u.is_authenticated() and u.is_active)
|
||||
else:
|
||||
staff_member_required = user_passes_test(lambda u: u.is_authenticated() and u.is_active and u.is_staff)
|
||||
|
||||
|
||||
superuser_required = user_passes_test(lambda u: u.is_authenticated() and u.is_active and u.is_superuser)
|
||||
|
||||
|
||||
def dashboard(request):
|
||||
"""
|
||||
@ -44,12 +50,18 @@ def dashboard(request):
|
||||
with options for them to 'Take' ownership of said tickets.
|
||||
"""
|
||||
|
||||
# open & reopened tickets
|
||||
tickets = Ticket.objects.filter(
|
||||
assigned_to=request.user,
|
||||
).exclude(
|
||||
status=Ticket.CLOSED_STATUS,
|
||||
status__in = [Ticket.CLOSED_STATUS, Ticket.RESOLVED_STATUS],
|
||||
)
|
||||
|
||||
# closed & resolved tickets
|
||||
tickets_closed_resolved = Ticket.objects.filter(
|
||||
assigned_to=request.user,
|
||||
status__in = [Ticket.CLOSED_STATUS, Ticket.RESOLVED_STATUS])
|
||||
|
||||
unassigned_tickets = Ticket.objects.filter(
|
||||
assigned_to__isnull=True,
|
||||
).exclude(
|
||||
@ -67,7 +79,8 @@ def dashboard(request):
|
||||
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
|
||||
COUNT(CASE t.status WHEN '3' THEN t.id END) AS resolved,
|
||||
COUNT(CASE t.status WHEN '4' THEN t.id END) AS closed
|
||||
FROM helpdesk_ticket t,
|
||||
helpdesk_queue q
|
||||
WHERE q.id = t.queue_id
|
||||
@ -79,6 +92,7 @@ def dashboard(request):
|
||||
return render_to_response('helpdesk/dashboard.html',
|
||||
RequestContext(request, {
|
||||
'user_tickets': tickets,
|
||||
'user_tickets_closed_resolved': tickets_closed_resolved,
|
||||
'unassigned_tickets': unassigned_tickets,
|
||||
'dash_tickets': dash_tickets,
|
||||
}))
|
||||
@ -127,9 +141,18 @@ def followup_edit(request, ticket_id, followup_id, ):
|
||||
new_status = form.cleaned_data['new_status']
|
||||
#will save previous date
|
||||
old_date = followup.date
|
||||
followup.delete()
|
||||
new_followup = FollowUp(title=title, date=old_date, ticket=_ticket, comment=comment, public=public, new_status=new_status, )
|
||||
# keep old user if one did exist before.
|
||||
if followup.user:
|
||||
new_followup.user = followup.user
|
||||
new_followup.save()
|
||||
# get list of old attachments & link them to new_followup
|
||||
attachments = Attachment.objects.filter(followup = followup)
|
||||
for attachment in attachments:
|
||||
attachment.followup = new_followup
|
||||
attachment.save()
|
||||
# delete old followup
|
||||
followup.delete()
|
||||
return HttpResponseRedirect(reverse('helpdesk_view', args=[ticket.id]))
|
||||
|
||||
def view_ticket(request, ticket_id):
|
||||
@ -169,7 +192,7 @@ def view_ticket(request, ticket_id):
|
||||
return render_to_response('helpdesk/ticket.html',
|
||||
RequestContext(request, {
|
||||
'ticket': ticket,
|
||||
'active_users': User.objects.filter(is_active=True).filter(is_staff=True).order_by('username'),
|
||||
'active_users': User.objects.filter(is_active=True).order_by('username'),
|
||||
'priorities': Ticket.PRIORITY_CHOICES,
|
||||
'preset_replies': PreSetReply.objects.filter(Q(queues=ticket.queue) | Q(queues__isnull=True)),
|
||||
'tags_enabled': HAS_TAG_SUPPORT,
|
||||
@ -178,7 +201,7 @@ view_ticket = staff_member_required(view_ticket)
|
||||
|
||||
|
||||
def update_ticket(request, ticket_id, public=False):
|
||||
if not (public or (request.user.is_authenticated() and request.user.is_active and request.user.is_staff)):
|
||||
if not (public or (request.user.is_authenticated() and request.user.is_active and (request.user.is_staff or helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE))):
|
||||
return HttpResponseForbidden(_('Sorry, you need to login to do that.'))
|
||||
|
||||
ticket = get_object_or_404(Ticket, id=ticket_id)
|
||||
@ -195,6 +218,10 @@ def update_ticket(request, ticket_id, public=False):
|
||||
# comment.
|
||||
from django.template import loader, Context
|
||||
context = safe_template_context(ticket)
|
||||
# this line sometimes creates problems if code is sent as a comment.
|
||||
# if comment contains some django code, like "why does {% if bla %} crash",
|
||||
# then the following line will give us a crash, since django expects {% if %}
|
||||
# to be closed with an {% endif %} tag.
|
||||
comment = loader.get_template_from_string(comment).render(Context(context))
|
||||
|
||||
if owner is None and ticket.assigned_to:
|
||||
@ -202,7 +229,7 @@ def update_ticket(request, ticket_id, public=False):
|
||||
|
||||
f = FollowUp(ticket=ticket, date=datetime.now(), comment=comment)
|
||||
|
||||
if request.user.is_staff:
|
||||
if request.user.is_staff or helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE:
|
||||
f.user = request.user
|
||||
|
||||
f.public = public
|
||||
@ -217,9 +244,11 @@ def update_ticket(request, ticket_id, public=False):
|
||||
}
|
||||
ticket.assigned_to = new_user
|
||||
reassigned = True
|
||||
elif owner == 0 and ticket.assigned_to is not None:
|
||||
f.title = _('Unassigned')
|
||||
ticket.assigned_to = None
|
||||
# This makes no sense to me. Why should we ever remove the 'assigned to'
|
||||
# value?
|
||||
#elif owner == 0 and ticket.assigned_to is not None:
|
||||
# f.title = _('Unassigned')
|
||||
# ticket.assigned_to = None
|
||||
|
||||
if new_status != ticket.status:
|
||||
ticket.status = new_status
|
||||
@ -289,7 +318,7 @@ def update_ticket(request, ticket_id, public=False):
|
||||
c.save()
|
||||
ticket.tags = tags
|
||||
|
||||
if f.new_status == Ticket.RESOLVED_STATUS:
|
||||
if new_status == Ticket.RESOLVED_STATUS:
|
||||
ticket.resolution = comment
|
||||
|
||||
messages_sent_to = []
|
||||
@ -377,7 +406,7 @@ def update_ticket(request, ticket_id, public=False):
|
||||
|
||||
ticket.save()
|
||||
|
||||
if request.user.is_staff:
|
||||
if request.user.is_staff or helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE:
|
||||
return HttpResponseRedirect(ticket.get_absolute_url())
|
||||
else:
|
||||
return HttpResponseRedirect(ticket.ticket_url)
|
||||
@ -419,11 +448,11 @@ def mass_update(request):
|
||||
f = FollowUp(ticket=t, date=datetime.now(), title=_('Closed in bulk update'), public=True, user=request.user, new_status=Ticket.CLOSED_STATUS)
|
||||
f.save()
|
||||
# Send email to Submitter, Owner, Queue CC
|
||||
context = {
|
||||
'ticket': t,
|
||||
'queue': t.queue,
|
||||
'resolution': t.resolution,
|
||||
}
|
||||
context = safe_template_context(t)
|
||||
context.update(
|
||||
resolution = t.resolution,
|
||||
queue = t.queue,
|
||||
)
|
||||
|
||||
messages_sent_to = []
|
||||
|
||||
@ -833,7 +862,7 @@ def run_report(request, report):
|
||||
month = 1
|
||||
if (year > last_year) or (month > last_month and year >= last_year):
|
||||
working = False
|
||||
periods.append("%s %s" % (months[month], year))
|
||||
periods.append("%s %s" % (months[month - 1], year))
|
||||
|
||||
if report == 'userpriority':
|
||||
title = _('User by Priority')
|
||||
@ -1087,3 +1116,10 @@ def ticket_dependency_del(request, ticket_id, dependency_id):
|
||||
}))
|
||||
ticket_dependency_del = staff_member_required(ticket_dependency_del)
|
||||
|
||||
def attachment_del(request, ticket_id, attachment_id):
|
||||
ticket = get_object_or_404(Ticket, id=ticket_id)
|
||||
attachment = get_object_or_404(Attachment, id=attachment_id)
|
||||
attachment.delete()
|
||||
return HttpResponseRedirect(reverse('helpdesk_view', args=[ticket_id]))
|
||||
attachment_del = staff_member_required(attachment_del)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user